Skip to content

Commit

Permalink
Make the hable and ue4 tone mapping configurable.
Browse files Browse the repository at this point in the history
  • Loading branch information
leMaik committed Dec 28, 2022
1 parent 70b3cf7 commit 3b1f1c5
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

import org.apache.commons.math3.util.FastMath;
import se.llbit.chunky.renderer.scene.Scene;
import se.llbit.json.JsonObject;
import se.llbit.util.Configurable;

/**
* Implementation of Hable (i.e. Uncharted 2) tone mapping
*
* @link http://filmicworlds.com/blog/filmic-tonemapping-operators/
* @link https://www.gdcvault.com/play/1012351/Uncharted-2-HDR
*/
public class HableToneMappingFilter extends SimplePixelPostProcessingFilter {
public class HableToneMappingFilter extends SimplePixelPostProcessingFilter implements Configurable {
public enum Preset {
/**
* Parameters from <a href="http://filmicworlds.com/blog/filmic-tonemapping-operators/">John Hable's blog post</a>
Expand Down Expand Up @@ -149,4 +151,28 @@ public String getName() {
public String getId() {
return "TONEMAP3";
}

@Override
public void loadConfiguration(JsonObject json) {
reset();
hA = json.get("shoulderStrength").floatValue(hA);
hB = json.get("linearStrength").floatValue(hB);
hC = json.get("linearAngle").floatValue(hC);
hD = json.get("toeStrength").floatValue(hD);
hE = json.get("toeNumerator").floatValue(hE);
hF = json.get("toeDenominator").floatValue(hF);
hW = json.get("linearWhitePointValue").floatValue(hW);
recalculateWhiteScale();
}

@Override
public void storeConfiguration(JsonObject json) {
json.add("shoulderStrength", hA);
json.add("linearStrength", hB);
json.add("linearAngle", hC);
json.add("toeStrength", hD);
json.add("toeNumerator", hE);
json.add("toeDenominator", hF);
json.add("linearWhitePointValue", hW);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@

import org.apache.commons.math3.util.FastMath;
import se.llbit.chunky.renderer.scene.Scene;
import se.llbit.json.JsonObject;
import se.llbit.math.QuickMath;
import se.llbit.util.Configurable;

/**
* Implementation of the Unreal Engine 4 Filmic Tone Mapper.
*
* @link https://docs.unrealengine.com/4.26/en-US/RenderingAndGraphics/PostProcessEffects/ColorGrading/
* @link https://www.desmos.com/calculator/h8rbdpawxj?lang=de
*/
public class UE4ToneMappingFilter extends SimplePixelPostProcessingFilter {
public class UE4ToneMappingFilter extends SimplePixelPostProcessingFilter implements Configurable {
public enum Preset {
/**
* ACES curve parameters
Expand Down Expand Up @@ -149,4 +151,26 @@ public String getName() {
public String getId() {
return "UE4_FILMIC";
}

@Override
public void loadConfiguration(JsonObject json) {
reset();
saturation = json.get("saturation").floatValue(saturation);
slope = json.get("slope").floatValue(slope);
toe = json.get("toe").floatValue(toe);
shoulder = json.get("shoulder").floatValue(shoulder);
blackClip = json.get("blackClip").floatValue(blackClip);
whiteClip = json.get("whiteClip").floatValue(whiteClip);
recalculateConstants();
}

@Override
public void storeConfiguration(JsonObject json) {
json.add("saturation", saturation);
json.add("slope", slope);
json.add("toe", toe);
json.add("shoulder", shoulder);
json.add("blackClip", blackClip);
json.add("whiteClip", whiteClip);
}
}
27 changes: 19 additions & 8 deletions chunky/src/java/se/llbit/chunky/renderer/scene/Scene.java
Original file line number Diff line number Diff line change
Expand Up @@ -1865,6 +1865,9 @@ public PostProcessingFilter getPostProcessingFilter() {
*/
public synchronized void setPostprocess(PostProcessingFilter p) {
postProcessingFilter = p;
if (postProcessingFilter instanceof Configurable) {
((Configurable) postProcessingFilter).reset();
}
if (mode == RenderMode.PREVIEW) {
// Don't interrupt the render if we are currently rendering.
refresh();
Expand Down Expand Up @@ -2656,6 +2659,11 @@ public void setUseCustomWaterColor(boolean value) {
json.add("yMax", yMax);
json.add("exposure", exposure);
json.add("postprocess", postProcessingFilter.getId());
if (postProcessingFilter instanceof Configurable) {
JsonObject postprocessJson = new JsonObject();
((Configurable) postProcessingFilter).storeConfiguration(postprocessJson);
json.add("postprocessSettings", postprocessJson);
}
json.add("outputMode", outputMode.getName());
json.add("renderTime", renderTime);
json.add("spp", spp);
Expand Down Expand Up @@ -2926,14 +2934,17 @@ public synchronized void importFromJson(JsonObject json) {

exposure = json.get("exposure").doubleValue(exposure);
postProcessingFilter = PostProcessingFilters
.getPostProcessingFilterFromId(json.get("postprocess").stringValue(postProcessingFilter.getId()))
.orElseGet(() -> {
if (json.get("postprocess").stringValue(null) != null) {
Log.warn("The post processing filter " + json +
" is unknown. Maybe you're missing a plugin that was used to create this scene?");
}
return DEFAULT_POSTPROCESSING_FILTER;
});
.getPostProcessingFilterFromId(json.get("postprocess").stringValue(postProcessingFilter.getId()))
.orElseGet(() -> {
if (json.get("postprocess").stringValue(null) != null) {
Log.warn("The post processing filter " + json +
" is unknown. Maybe you're missing a plugin that was used to create this scene?");
}
return DEFAULT_POSTPROCESSING_FILTER;
});
if (postProcessingFilter instanceof Configurable) {
((Configurable) postProcessingFilter).loadConfiguration(json.get("postprocessSettings").asObject());
}
outputMode = PictureExportFormats
.getFormat(json.get("outputMode").stringValue(outputMode.getName()))
.orElse(PictureExportFormats.PNG);
Expand Down

0 comments on commit 3b1f1c5

Please sign in to comment.