Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

public enum SunSamplingStrategy implements Registerable {
OFF("Off", "Sun is not sampled with next event estimation.", false, true, false, true),
NON_LUMINOUS("Non-Luminous", "Sun is drawn on the skybox but it does not contribute to the lighting of the scene.", false, false, false, false),
FAST("Fast", "Fast sun sampling algorithm. Lower noise but does not correctly model some visual effects.", true, false, false, false),
HIGH_QUALITY("High Quality", "High quality sun sampling. More noise but correctly models visual effects such as caustics.", true, true, true, true);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,18 @@ public static boolean pathTrace(Scene scene, Ray ray, WorkerState state, int add
} else if (ray.depth == 0) {
// Direct sky hit.
if (!scene.transparentSky()) {
scene.sky.getSkyColorInterpolated(ray);
scene.sky.getSkyColor(ray, true, false);
addSkyFog(scene, ray, state, ox, od);
hit = true;
}
} else if (ray.specular) {
// Indirect sky hit - specular color.
scene.sky.getSkyColor(ray, true);
scene.sky.getSkyColor(ray, true, false);
addSkyFog(scene, ray, state, ox, od);
hit = true;
} else {
// Indirect sky hit - diffuse color.
scene.sky.getSkyColorDiffuseSun(ray, scene.getSunSamplingStrategy().isDiffuseSun());
scene.sky.getSkyColor(ray, false, scene.getSunSamplingStrategy().isDiffuseSun());
// Skip sky fog - likely not noticeable in diffuse reflection.
hit = true;
}
Expand Down Expand Up @@ -201,7 +201,7 @@ public static boolean pathTrace(Scene scene, Ray ray, WorkerState state, int add
}
}

if (scene.getSunSamplingStrategy().doSunSampling()) {
if (scene.getSunSamplingStrategy().doSunSampling() && scene.sun.sunlightEnabled()) {
reflected.set(ray);
scene.sun.getRandomSunDirection(reflected, random);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public class PreviewRayTracer implements RayTracer {
}

if (ray.getCurrentMaterial() == Air.INSTANCE) {
scene.sky.getApparentSkyColor(ray, true);
scene.sky.getSkyColor(ray, true, false);
} else {
scene.sun.flatShading(ray);
}
Expand Down
11 changes: 2 additions & 9 deletions chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java
Original file line number Diff line number Diff line change
Expand Up @@ -3016,15 +3016,7 @@ public synchronized void importFromJson(JsonObject json) {
emitterIntensity = json.get("emitterIntensity").doubleValue(emitterIntensity);

if (json.get("sunSamplingStrategy").isUnknown()) {
boolean sunSampling = json.get("sunEnabled").boolValue(false);
boolean drawSun = json.get("sun").asObject().get("drawTexture").boolValue(false);
if (drawSun) {
if (sunSampling) {
sunSamplingStrategy = SunSamplingStrategy.FAST;
} else {
sunSamplingStrategy = SunSamplingStrategy.NON_LUMINOUS;
}
} else {
if (json.get("sunEnabled").boolValue(false)) {
sunSamplingStrategy = SunSamplingStrategy.FAST;
}
} else {
Expand All @@ -3033,6 +3025,7 @@ public synchronized void importFromJson(JsonObject json) {

if (json.get("sunEnabled").boolValue(false)) {
sunSamplingStrategy = SunSamplingStrategy.FAST;
sun.setEnableSunlight(true);
} else {
sunSamplingStrategy = SunSamplingStrategy.valueOf(json.get("sunSamplingStrategy").asString(SunSamplingStrategy.FAST.getId()));
}
Expand Down
93 changes: 48 additions & 45 deletions chunky/src/java/se/llbit/chunky/renderer/scene/Sky.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ public static SkyMode get(String name) {
/** Current sky rendering mode. */
private SkyMode mode = SkyMode.DEFAULT;

private boolean enableSkymapInterpolation = true;

/** Simulated skies. */
public final static List<SimulatedSky> skies = new ArrayList<>();

Expand Down Expand Up @@ -254,12 +256,13 @@ public void set(Sky other) {
if (simulatedSkyMode.updateSun(scene.sun, horizonOffset)) {
skyCache.precalculateSky();
}
enableSkymapInterpolation = other.enableSkymapInterpolation;
}

/**
* Calculate sky color for the ray, based on sky mode.
*/
public void getSkyDiffuseColorInner(Ray ray) {
private void getSkyDiffuseColorInner(Ray ray) {
switch (mode) {
case SOLID_COLOR: {
ray.color.set(color.x, color.y, color.z, 1);
Expand Down Expand Up @@ -360,26 +363,30 @@ public void getSkyDiffuseColorInner(Ray ray) {
/**
* Panoramic skymap color.
*/
public void getSkyColor(Ray ray, boolean drawSun) {
getSkyDiffuseColorInner(ray);
ray.color.scale(skyExposure);
ray.color.scale(skyLightModifier);
if (drawSun) addSunColor(ray);
ray.color.w = 1;
}
public void getSkyColor(Ray ray, boolean isApparentColor, boolean isDiffuseSun) {
Comment thread
leMaik marked this conversation as resolved.
if (enableSkymapInterpolation) {
getSkyColorInterpolated(ray);
} else {
getSkyDiffuseColorInner(ray);
}

public void getApparentSkyColor(Ray ray, boolean drawSun) {
getSkyDiffuseColorInner(ray);
ray.color.scale(skyExposure);
ray.color.scale(apparentSkyLightModifier);
if (drawSun) addSunColor(ray);
if (isApparentColor) {
ray.color.scale(apparentSkyLightModifier);
addSunColor(ray, false);
} else {
ray.color.scale(skyLightModifier);
if (isDiffuseSun) {
addSunColor(ray, true);
}
}
ray.color.w = 1;
}

/**
* Bilinear interpolated panoramic skymap color.
*/
public void getSkyColorInterpolated(Ray ray) {
private void getSkyColorInterpolated(Ray ray) {
switch (mode) {
case SKYMAP_EQUIRECTANGULAR: {
double x = rotation.transformX(ray.d);
Expand Down Expand Up @@ -449,49 +456,34 @@ public void getSkyColorInterpolated(Ray ray) {
getSkyDiffuseColorInner(ray);
}
}
ray.color.scale(skyExposure);
ray.color.scale(apparentSkyLightModifier);
addSunColor(ray);
Comment on lines -452 to -454

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is public. Is it intended to not apply exposure, sky light modifier and sun here anymore?

@Peregrine05 Peregrine05 Apr 21, 2023

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is only accessed from within Sky.java, so it can be made private (the same goes with getSkyDiffuseColorInner). It is no longer intended to apply modifications to the sky color in the getSkyColorInterpolated method; modifications are now done in the getSkyColor method, after getting the base sky color.

ray.color.w = 1;
}

/**
* Add sun color contribution. This does not alpha blend the sun color
* because the Minecraft sun texture has no alpha channel.
*/
private void addSunColor(Ray ray) {
double r = ray.color.x;
double g = ray.color.y;
double b = ray.color.z;
if (scene.sun().intersect(ray)) {

// Blend sun color with current color.
ray.color.x = ray.color.x + r;
ray.color.y = ray.color.y + g;
ray.color.z = ray.color.z + b;
}
}

public void getSkyColorDiffuseSun(Ray ray, boolean diffuseSun) {
getSkyDiffuseColorInner(ray);
ray.color.scale(skyExposure);
ray.color.scale(skyLightModifier);
if (diffuseSun) addSunColorDiffuseSun(ray);
ray.color.w = 1;
}

public void addSunColorDiffuseSun(Ray ray) {
private void addSunColor(Ray ray, boolean isDiffuseSun) {
double r = ray.color.x;
double g = ray.color.y;
double b = ray.color.z;
if (isDiffuseSun) {
if (scene.sun().intersectDiffuse(ray)) {
double mult = scene.sun().getLuminosity();

// Blend sun color with current color.
ray.color.x = ray.color.x * mult + r;
ray.color.y = ray.color.y * mult + g;
ray.color.z = ray.color.z * mult + b;
}
} else {
if (scene.sun().intersect(ray)) {

if (scene.sun().intersectDiffuse(ray)) {
double mult = scene.sun().getLuminosity();

// Blend sun color with current color.
ray.color.x = ray.color.x * mult + r;
ray.color.y = ray.color.y * mult + g;
ray.color.z = ray.color.z * mult + b;
// Blend sun color with current color.
ray.color.x = ray.color.x + r;
ray.color.y = ray.color.y + g;
ray.color.z = ray.color.z + b;
}
}
}

Expand Down Expand Up @@ -673,6 +665,7 @@ public void setSkyCacheResolution(int resolution) {
break;
}
}
sky.add("enableSkymapInterpolation", enableSkymapInterpolation);
return sky;
}

Expand Down Expand Up @@ -749,6 +742,7 @@ public void importFromJson(JsonObject json) {
default:
break;
}
enableSkymapInterpolation = json.get("enableSkymapInterpolation").boolValue(enableSkymapInterpolation);
}

private void updateTransform() {
Expand Down Expand Up @@ -1178,4 +1172,13 @@ public void setColor(Vector3 color) {
public Vector3 getColor() {
return color;
}

public void setEnableSkymapInterpolation(boolean value) {
enableSkymapInterpolation = value;
scene.refresh();
}

public boolean getEnableSkymapInterpolation() {
return enableSkymapInterpolation;
}
}
46 changes: 25 additions & 21 deletions chunky/src/java/se/llbit/chunky/renderer/scene/Sun.java
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ public class Sun implements JsonSerializable {

private final Vector3 apparentColor = new Vector3(1, 1, 1);

private boolean enableSunlight = true;

private boolean drawTexture = true;

private double chroma(double turb, double turb2, double sunTheta, double[][] matrix) {
Expand Down Expand Up @@ -195,6 +197,7 @@ public void set(Sun other) {
altitude = other.altitude;
color.set(other.color);
apparentColor.set(other.apparentColor);
enableSunlight = other.enableSunlight;
drawTexture = other.drawTexture;
intensity = other.intensity;
luminosity = other.luminosity;
Expand Down Expand Up @@ -281,33 +284,18 @@ public double getAzimuth() {
* @return <code>true</code> if the ray intersects the sun model
*/
public boolean intersect(Ray ray) {
if (!drawTexture || ray.d.dot(sw) < .5) {
return false;
}

double width = radius * 4;
double width2 = width * 2;
double a;
a = Math.PI / 2 - FastMath.acos(ray.d.dot(su)) + width;
if (a >= 0 && a < width2) {
double b = Math.PI / 2 - FastMath.acos(ray.d.dot(sv)) + width;
if (b >= 0 && b < width2) {
texture.getColor(a / width2, b / width2, ray.color);
ray.color.x *= apparentTextureBrightness.x * 10;
ray.color.y *= apparentTextureBrightness.y * 10;
ray.color.z *= apparentTextureBrightness.z * 10;
return true;
}
}

return false;
return doIntersect(ray, apparentTextureBrightness, false);
}

/**
* Used with <code>SSS: OFF</code> and <code>SSS: HIGH_QUALITY</code>.
*/
public boolean intersectDiffuse(Ray ray) {
if (ray.d.dot(sw) < .5) {
return doIntersect(ray, color, true);
}

private boolean doIntersect(Ray ray, Vector3 color, boolean isDiffuse) {
if ((isDiffuse && !enableSunlight) || (!isDiffuse && !drawTexture) || ray.d.dot(sw) < .5) {
return false;
}

Expand Down Expand Up @@ -475,6 +463,7 @@ public void getRandomSunDirection(Ray reflected, Random random) {
apparentColorObj.add("green", apparentColor.y);
apparentColorObj.add("blue", apparentColor.z);
sun.add("apparentColor", apparentColorObj);
sun.add("enableSunlight", enableSunlight);
sun.add("drawTexture", drawTexture);
return sun;
}
Expand Down Expand Up @@ -502,6 +491,10 @@ public void importFromJson(JsonObject json) {
apparentColor.z = apparentColorObj.get("blue").doubleValue(1);
}

if (!json.get("enableSunlight").isUnknown()) {
enableSunlight = json.get("enableSunlight").boolValue(enableSunlight);
}

drawTexture = json.get("drawTexture").boolValue(drawTexture);

initSun();
Expand All @@ -518,6 +511,17 @@ public Vector3 getApparentColor() {
return apparentColor;
}

public void setEnableSunlight(boolean value) {
if (value != enableSunlight) {
enableSunlight = value;
scene.refresh();
}
}

public boolean sunlightEnabled() {
return enableSunlight;
}

public void setDrawTexture(boolean value) {
if (value != drawTexture) {
drawTexture = value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class AdvancedTab extends ScrollPane implements RenderControlsTab, Initia
@FXML private Button mergeRenderDump;
@FXML private CheckBox shutdown;
@FXML private CheckBox fastFog;
@FXML private CheckBox enableSkymapInterpolation;
@FXML private IntegerAdjuster cacheResolution;
@FXML private DoubleAdjuster animationTime;
@FXML private ChoiceBox<PictureExportFormat> outputMode;
Expand Down Expand Up @@ -141,6 +142,8 @@ public PictureExportFormat fromString(String string) {
fastFog.setTooltip(new Tooltip("Enable faster fog rendering algorithm."));
fastFog.selectedProperty()
.addListener((observable, oldValue, newValue) -> scene.setFastFog(newValue));
enableSkymapInterpolation.setTooltip(new Tooltip("Enable interpolation of the skymap / skybox texture, if a skymap / skybox is being used."));
enableSkymapInterpolation.selectedProperty().addListener((observable, oldValue, newValue) -> scene.sky().setEnableSkymapInterpolation(newValue));
cacheResolution.setName("Sky cache resolution");
cacheResolution.setTooltip("Resolution of the sky cache. Lower values will use less memory and improve performance but can cause sky artifacts.");
cacheResolution.setRange(1, 4096);
Expand Down Expand Up @@ -301,6 +304,7 @@ public boolean shutdownAfterCompletedRender() {
public void update(Scene scene) {
outputMode.getSelectionModel().select(scene.getOutputMode());
fastFog.setSelected(scene.fog.fastFog());
enableSkymapInterpolation.setSelected(scene.sky().getEnableSkymapInterpolation());
renderThreads.set(PersistentSettings.getNumThreads());
cpuLoad.set(PersistentSettings.getCPULoad());
rayDepth.set(scene.getRayDepth());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public class LightingTab extends ScrollPane implements RenderControlsTab, Initia
@FXML private DoubleAdjuster emitterIntensity;
@FXML private DoubleAdjuster sunIntensity;
@FXML private CheckBox drawSun;
@FXML private CheckBox enableSunlight;
@FXML private ComboBox<SunSamplingStrategy> sunSamplingStrategy;
@FXML private DoubleAdjuster sunLuminosity;
@FXML private DoubleAdjuster apparentSunBrightness;
Expand Down Expand Up @@ -129,9 +130,16 @@ public LightingTab() throws IOException {
});
emitterSamplingStrategy.setTooltip(new Tooltip("Determine how emitters are sampled at each bounce."));

enableSunlight.selectedProperty().addListener((observable, oldValue, newValue) -> {
scene.sun().setEnableSunlight(newValue);
sunSamplingStrategy.setDisable(!newValue);
});
enableSunlight.setTooltip(new Tooltip("Changes whether the sun emits light."));

drawSun.selectedProperty().addListener((observable, oldValue, newValue) -> scene.sun().setDrawTexture(newValue));
drawSun.setTooltip(new Tooltip("Draws the sun texture on top of the skymap."));

sunSamplingStrategy.setDisable(!enableSunlight.isSelected());
sunSamplingStrategy.getItems().addAll(SunSamplingStrategy.values());
sunSamplingStrategy.getSelectionModel().selectedItemProperty().addListener(
(observable, oldValue, newValue) -> scene.setSunSamplingStrategy(newValue));
Expand Down Expand Up @@ -203,6 +211,7 @@ public void setController(RenderControlsFxController controller) {
sunAltitude.set(QuickMath.radToDeg(scene.sun().getAltitude()));
enableEmitters.setSelected(scene.getEmittersEnabled());
sunSamplingStrategy.getSelectionModel().select(scene.getSunSamplingStrategy());
enableSunlight.setSelected(scene.sun().sunlightEnabled());
drawSun.setSelected(scene.sun().drawTexture());
sunColor.colorProperty().removeListener(sunColorListener);
sunColor.setColor(ColorUtil.toFx(scene.sun().getColor()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<Separator prefWidth="200.0" />
<CheckBox fx:id="shutdown" mnemonicParsing="false" text="Shutdown computer when render completes" />
<CheckBox fx:id="fastFog" mnemonicParsing="false" text="Fast fog" />
<CheckBox fx:id="enableSkymapInterpolation" mnemonicParsing="false" text="Enable skymap interpolation" />
<IntegerAdjuster fx:id="cacheResolution" />
<DoubleAdjuster fx:id="animationTime" />
<HBox alignment="CENTER_LEFT" spacing="10.0">
Expand Down
Loading