diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index b3fac3b18a..c430c39172 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -5,6 +5,10 @@ A new header is inserted each time a *tag* is created. ## v1.11.1 (currently main branch) +- engine: Luminance scaling can now be used with any tone mapping operator. It was previously tied + to the "EVILS" tone mapping operator. +- engine: Removed the "EVILS" tone mapping operator [⚠️ **API Change**]. + ## v1.11.0 - engine: Added support for transparent shadows. Add `transparentShadow : true` in the material file. diff --git a/android/filament-android/src/main/cpp/ColorGrading.cpp b/android/filament-android/src/main/cpp/ColorGrading.cpp index 814012cafc..725e88dd4f 100644 --- a/android/filament-android/src/main/cpp/ColorGrading.cpp +++ b/android/filament-android/src/main/cpp/ColorGrading.cpp @@ -60,6 +60,13 @@ Java_com_google_android_filament_ColorGrading_nBuilderToneMapping(JNIEnv*, jclas builder->toneMapping(toneMapping); } +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_ColorGrading_nBuilderLuminanceScaling(JNIEnv*, jclass, + jlong nativeBuilder, jboolean luminanceScaling) { + ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder; + builder->luminanceScaling(luminanceScaling); +} + extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_ColorGrading_nBuilderExposure(JNIEnv*, jclass, jlong nativeBuilder, jfloat exposure) { diff --git a/android/filament-android/src/main/java/com/google/android/filament/ColorGrading.java b/android/filament-android/src/main/java/com/google/android/filament/ColorGrading.java index da54f06f99..2118257ba6 100644 --- a/android/filament-android/src/main/java/com/google/android/filament/ColorGrading.java +++ b/android/filament-android/src/main/java/com/google/android/filament/ColorGrading.java @@ -64,6 +64,7 @@ import static com.google.android.filament.Asserts.assertFloat4In; *
  • Saturation
  • *
  • Curves
  • *
  • Tone mapping
  • + *
  • Luminance scaling
  • * * *

    Defaults

    @@ -81,6 +82,7 @@ import static com.google.android.filament.Asserts.assertFloat4In; *
  • Saturation: 1.0
  • *
  • Curves: gamma {1,1,1}, midPoint {1,1,1}, and scale {1,1,1}
  • *
  • Tone mapping: {@link ToneMapping#ACES_LEGACY}
  • + *
  • Luminance scaling: false
  • * * * @see View @@ -111,8 +113,8 @@ public class ColorGrading { ACES, /** Filmic tone mapping, modelled after ACES but applied in sRGB space. */ FILMIC, - /** Exposure value invariant luminance scaling tone mapping, offers the best behaviors in high intensity areas. */ - EVILS, + /** Reserved for future use. */ + RESERVED, /** Reinhard luma-based tone mapping. */ REINHARD, /** Tone mapping used to validate/debug scene exposure. */ @@ -173,6 +175,25 @@ public class ColorGrading { return this; } + /** + * Enables or disables the luminance scaling component (LICH) from the exposure value + * invariant luminance system (EVILS). When this setting is enabled, pixels with high + * chromatic values will roll-off to white to offer a more natural rendering. This step + * also helps avoid undesirable hue skews caused by out of gamut colors clipped + * to the destination color gamut. + * + * When luminance scaling is enabled, tone mapping is performed on the luminance of each + * pixel instead of per-channel. + * + * @param luminanceScaling Enables or disables EVILS post-tone mapping + * + * @return This Builder, for chaining calls + */ + public Builder luminanceScaling(boolean luminanceScaling) { + nBuilderLuminanceScaling(mNativeBuilder, luminanceScaling); + return this; + } + /** * Adjusts the exposure of this image. The exposure is specified in stops: * each stop brightens (positive values) or darkens (negative values) the image by @@ -482,6 +503,7 @@ public class ColorGrading { private static native void nBuilderQuality(long nativeBuilder, int quality); private static native void nBuilderToneMapping(long nativeBuilder, int toneMapper); + private static native void nBuilderLuminanceScaling(long nativeBuilder, boolean luminanceScaling); private static native void nBuilderExposure(long nativeBuilder, float exposure); private static native void nBuilderWhiteBalance(long nativeBuilder, float temperature, float tint); private static native void nBuilderChannelMixer(long nativeBuilder, float[] outRed, float[] outGreen, float[] outBlue); diff --git a/filament/include/filament/ColorGrading.h b/filament/include/filament/ColorGrading.h index 4b4d88e42b..cf336c16ad 100644 --- a/filament/include/filament/ColorGrading.h +++ b/filament/include/filament/ColorGrading.h @@ -74,6 +74,7 @@ class FColorGrading; * - Saturation * - Curves * - Tone mapping + * - Luminance scaling * * Defaults * ======== @@ -90,6 +91,7 @@ class FColorGrading; * - Saturation: 1.0 * - Curves: gamma {1,1,1}, midPoint {1,1,1}, and scale {1,1,1} * - Tone mapping: ACES_LEGACY + * - Luminance scaling: false * * @see View */ @@ -111,7 +113,7 @@ public: ACES_LEGACY = 1, //!< ACES tone mapping, with a brightness modifier to match Filament's legacy tone mapper ACES = 2, //!< ACES tone mapping FILMIC = 3, //!< Filmic tone mapping, modelled after ACES but applied in sRGB space - EVILS = 4, //!< Exposure value invariant luminance scaling tone mapping, offers the best behaviors in high intensity areas + RESERVED = 4, //!< Currently unused REINHARD = 5, //!< Reinhard luma-based tone mapping DISPLAY_RANGE = 6, //!< Tone mapping used to validate/debug scene exposure }; @@ -154,6 +156,22 @@ public: */ Builder& toneMapping(ToneMapping toneMapping) noexcept; + /** + * Enables or disables the luminance scaling component (LICH) from the exposure value + * invariant luminance system (EVILS). When this setting is enabled, pixels with high + * chromatic values will roll-off to white to offer a more natural rendering. This step + * also helps avoid undesirable hue skews caused by out of gamut colors clipped + * to the destination color gamut. + * + * When luminance scaling is enabled, tone mapping is performed on the luminance of each + * pixel instead of per-channel. + * + * @param luminanceScaling Enables or disables EVILS post-tone mapping + * + * @return This Builder, for chaining calls + */ + Builder& luminanceScaling(bool luminanceScaling) noexcept; + /** * Adjusts the exposure of this image. The exposure is specified in stops: * each stop brightens (positive values) or darkens (negative values) the image by diff --git a/filament/src/ColorGrading.cpp b/filament/src/ColorGrading.cpp index d2dd509005..b6dcb9b3a6 100644 --- a/filament/src/ColorGrading.cpp +++ b/filament/src/ColorGrading.cpp @@ -52,6 +52,8 @@ struct ColorGrading::BuilderDetails { ColorGrading::QualityLevel quality = QualityLevel::MEDIUM; ToneMapping toneMapping = ToneMapping::ACES_LEGACY; + // Luminance scaling + bool luminanceScaling = false; // Exposure float exposure = 0.0f; // White balance @@ -88,6 +90,7 @@ struct ColorGrading::BuilderDetails { // Note: Do NOT compare hasAdjustments return quality == rhs.quality && toneMapping == rhs.toneMapping && + luminanceScaling == rhs.luminanceScaling && exposure == rhs.exposure && whiteBalance == rhs.whiteBalance && outRed == rhs.outRed && @@ -127,6 +130,11 @@ ColorGrading::Builder& ColorGrading::Builder::toneMapping(ToneMapping toneMappin return *this; } +ColorGrading::Builder& ColorGrading::Builder::luminanceScaling(bool luminanceScaling) noexcept { + mImpl->luminanceScaling = luminanceScaling; + return *this; +} + ColorGrading::Builder& ColorGrading::Builder::exposure(float exposure) noexcept { mImpl->exposure = exposure; return *this; @@ -273,7 +281,8 @@ mat3f selectColorGradingTransformIn(ColorGrading::ToneMapping toneMapping) { case ColorGrading::ToneMapping::ACES: return sRGB_to_AP1; case ColorGrading::ToneMapping::FILMIC: - case ColorGrading::ToneMapping::EVILS: + case ColorGrading::ToneMapping::RESERVED: + case ColorGrading::ToneMapping::DISPLAY_RANGE: return mat3f{}; // stay in sRGB default: return sRGB_to_REC2020; @@ -286,7 +295,8 @@ mat3f selectColorGradingTransformOut(ColorGrading::ToneMapping toneMapping) { case ColorGrading::ToneMapping::ACES: return AP1_to_sRGB; case ColorGrading::ToneMapping::FILMIC: - case ColorGrading::ToneMapping::EVILS: + case ColorGrading::ToneMapping::RESERVED: + case ColorGrading::ToneMapping::DISPLAY_RANGE: return mat3f{}; // stay in sRGB default: return REC2020_to_sRGB; @@ -303,6 +313,16 @@ float3 selectLuminanceTransform(ColorGrading::ToneMapping toneMapping) { } } +float3 selectLuminanceScalingTransform(ColorGrading::ToneMapping toneMapping) { + switch (toneMapping) { + case ColorGrading::ToneMapping::ACES_LEGACY: + case ColorGrading::ToneMapping::ACES: + return LUMA_AP1; + default: + return LUMA_HK_REC709; + } +} + UTILS_ALWAYS_INLINE inline constexpr float3 channelMixer(float3 v, float3 r, float3 g, float3 b) { return {dot(v, r), dot(v, g), dot(v, b)}; @@ -379,6 +399,39 @@ inline float3 curves(float3 v, float3 shadowGamma, float3 midPoint, float3 highl }; } +//------------------------------------------------------------------------------ +// Luminance scaling +//------------------------------------------------------------------------------ + +static float3 luminanceScaling( + float3 x, ColorTransform toneMapper, float3 luminanceWeights) noexcept { + + // Troy Sobotka, 2021, "EVILS - Exposure Value Invariant Luminance Scaling" + // https://colab.research.google.com/drive/1iPJzNNKR7PynFmsqSnQm3bCZmQ3CvAJ-#scrollTo=psU43hb-BLzB + + float luminanceIn = dot(x, luminanceWeights); + + // TODO: We could optimize for the case of single-channel luminance + float luminanceOut = toneMapper(luminanceIn).x; + + float peak = max(x); + float3 chromaRatio = max(x / peak, 0.0f); + + float chromaRatioLuminance = dot(chromaRatio, luminanceWeights); + + float3 maxReserves = 1.0f - chromaRatio; + float maxReservesLuminance = dot(maxReserves, luminanceWeights); + + float luminanceDifference = std::max(luminanceOut - chromaRatioLuminance, 0.0f); + float scaledLuminanceDifference = + luminanceDifference / std::max(maxReservesLuminance, std::numeric_limits::min()); + + float chromaScale = (luminanceOut - luminanceDifference) / + std::max(chromaRatioLuminance, std::numeric_limits::min()); + + return chromaScale * chromaRatio + scaledLuminanceDifference * maxReserves; +} + //------------------------------------------------------------------------------ // Quality //------------------------------------------------------------------------------ @@ -435,8 +488,8 @@ ColorTransform selectToneMapping(ColorGrading::ToneMapping toneMapping) { return tonemap::ACES; case ColorGrading::ToneMapping::FILMIC: return tonemap::Filmic; - case ColorGrading::ToneMapping::EVILS: - return tonemap::EVILS; + case ColorGrading::ToneMapping::RESERVED: + return tonemap::Linear; case ColorGrading::ToneMapping::REINHARD: return tonemap::Reinhard; case ColorGrading::ToneMapping::DISPLAY_RANGE: @@ -452,6 +505,7 @@ struct Config { mat3f colorGradingTransformIn; mat3f colorGradingTransformOut; float3 luminanceTransform; + float3 luminanceScalingTransform; ColorTransform linearToLogTransform; ColorTransform logToLinearTransform; ColorTransform toneMapper; @@ -474,14 +528,15 @@ FColorGrading::FColorGrading(FEngine& engine, const Builder& builder) { utils::SpinLock configLock; { std::lock_guard lock(configLock); - c.colorGradingTransformIn = selectColorGradingTransformIn(builder->toneMapping); - c.colorGradingTransformOut = selectColorGradingTransformOut(builder->toneMapping); - c.luminanceTransform = selectLuminanceTransform(builder->toneMapping); - c.linearToLogTransform = selectLinearToLogTransform(builder->toneMapping); - c.logToLinearTransform = selectLogToLinearTransform(builder->toneMapping); - c.toneMapper = selectToneMapping(builder->toneMapping); - c.lutDimension = selectLutDimension(builder->quality); - c.adaptationTransform = adaptationTransform(builder->whiteBalance); + c.colorGradingTransformIn = selectColorGradingTransformIn(builder->toneMapping); + c.colorGradingTransformOut = selectColorGradingTransformOut(builder->toneMapping); + c.luminanceTransform = selectLuminanceTransform(builder->toneMapping); + c.luminanceScalingTransform = selectLuminanceScalingTransform(builder->toneMapping); + c.linearToLogTransform = selectLinearToLogTransform(builder->toneMapping); + c.logToLinearTransform = selectLogToLinearTransform(builder->toneMapping); + c.toneMapper = selectToneMapping(builder->toneMapping); + c.lutDimension = selectLutDimension(builder->quality); + c.adaptationTransform = adaptationTransform(builder->whiteBalance); } size_t lutElementCount = c.lutDimension * c.lutDimension * c.lutDimension; @@ -574,7 +629,11 @@ FColorGrading::FColorGrading(FEngine& engine, const Builder& builder) { } // Tone mapping - v = config.toneMapper(v); + if (builder->luminanceScaling) { + v = luminanceScaling(v, config.toneMapper, config.luminanceScalingTransform); + } else { + v = config.toneMapper(v); + } // Convert to output color space // TODO: allow to customize the output color space, diff --git a/filament/src/ToneMapping.cpp b/filament/src/ToneMapping.cpp index 34610188a6..74b51aa220 100644 --- a/filament/src/ToneMapping.cpp +++ b/filament/src/ToneMapping.cpp @@ -188,8 +188,19 @@ float3 ACES_Legacy(float3 x) noexcept { return aces::ACES(x, 1.0f / 0.6f); } -float genericTonemap(float x, float contrast, float shoulder, - float midGreyIn, float midGreyOut, float hdrMax) noexcept { +// TODO: These constants were chosen to match our ACES tone mappers as closely as possible +// in terms of compression. We should expose these parameters to users via an API. +// We must however carefully validate exposed parameters as it is easy to get the +// generic tonemapper to produce invalid curves. +// TODO: Expose this as a public tone mapper +float genericTonemap( + float x, + float contrast = 1.6f, + float shoulder = 1.0f, + float midGreyIn = 0.18f, + float midGreyOut = 0.227f, + float hdrMax = 64.0f +) noexcept { // Lottes, 2016,"Advanced Techniques and Optimization of VDR Color Pipelines" // https://gpuopen.com/wp-content/uploads/2016/03/GdcVdrLottes.pdf float mc = std::pow(midGreyIn, contrast); @@ -210,46 +221,6 @@ float genericTonemap(float x, float contrast, float shoulder, return saturate(xc / (std::pow(xc, shoulder) * b + c)); } -constexpr float luminance(float3 v) noexcept { - return dot(v, LUMA_HK_REC709); -} - -float3 EVILS(float3 x) noexcept { - // Troy Sobotka, 2021, "EVILS - Exposure Value Invariant Luminance Scaling" - // https://colab.research.google.com/drive/1iPJzNNKR7PynFmsqSnQm3bCZmQ3CvAJ-#scrollTo=psU43hb-BLzB - - // TODO: These constants were chosen to match our ACES tone mappers as closely as possible - // in terms of compression. We should expose these parameters to users via an API. - // We must however carefully validate exposed parameters as it is easy to get the - // generic tonemapper to produce invalid curves. - constexpr float contrast = 1.6f; - constexpr float shoulder = 1.0f; - constexpr float midGreyIn = 0.18f; - constexpr float midGreyOut = 0.227f; - constexpr float hdrMax = 64.0f; - - // We assume an input compatible with Rec.709 luminance weights - float luminanceIn = luminance(x); - float luminanceOut = genericTonemap(luminanceIn, contrast, shoulder, midGreyIn, midGreyOut, hdrMax); - - float peak = max(x); - float3 chromaRatio = max(x / peak, 0.0f); - - float chromaRatioLuminance = luminance(chromaRatio); - - float3 maxReserves = 1.0f - chromaRatio; - float maxReservesLuminance = luminance(maxReserves); - - float luminanceDifference = std::max(luminanceOut - chromaRatioLuminance, 0.0f); - float scaledLuminanceDifference = - luminanceDifference / std::max(maxReservesLuminance, std::numeric_limits::min()); - - float chromaScale = (luminanceOut - luminanceDifference) / - std::max(chromaRatioLuminance, std::numeric_limits::min()); - - return chromaScale * chromaRatio + scaledLuminanceDifference * maxReserves; -} - float3 DisplayRange(float3 x) noexcept { // 16 debug colors + 1 duplicated at the end for easy indexing diff --git a/filament/src/ToneMapping.h b/filament/src/ToneMapping.h index f4073ee381..6502f81610 100644 --- a/filament/src/ToneMapping.h +++ b/filament/src/ToneMapping.h @@ -67,8 +67,6 @@ float3 ACES(float3 x) noexcept; float3 ACES_Legacy(float3 x) noexcept; -float3 EVILS(float3 x) noexcept; - /** * Converts the input HDR RGB color into one of 16 debug colors that represent * the pixel's exposure. When the output is cyan, the input color represents diff --git a/libs/viewer/include/viewer/Settings.h b/libs/viewer/include/viewer/Settings.h index 578f17ddcd..65f1b9d9b3 100644 --- a/libs/viewer/include/viewer/Settings.h +++ b/libs/viewer/include/viewer/Settings.h @@ -98,6 +98,7 @@ struct ColorGradingSettings { bool enabled = true; filament::ColorGrading::QualityLevel quality = filament::ColorGrading::QualityLevel::MEDIUM; ToneMapping toneMapping = ToneMapping::ACES_LEGACY; + bool luminanceScaling = false; float exposure = 0.0f; float temperature = 0.0f; float tint = 0.0f; diff --git a/libs/viewer/src/Settings.cpp b/libs/viewer/src/Settings.cpp index 91f845f92c..93de1a75e6 100644 --- a/libs/viewer/src/Settings.cpp +++ b/libs/viewer/src/Settings.cpp @@ -186,7 +186,7 @@ static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, ToneMapp else if (0 == compare(tokens[i], jsonChunk, "ACES_LEGACY")) { *out = ToneMapping::ACES_LEGACY; } else if (0 == compare(tokens[i], jsonChunk, "ACES")) { *out = ToneMapping::ACES; } else if (0 == compare(tokens[i], jsonChunk, "FILMIC")) { *out = ToneMapping::FILMIC; } - else if (0 == compare(tokens[i], jsonChunk, "EVILS")) { *out = ToneMapping::EVILS; } + else if (0 == compare(tokens[i], jsonChunk, "RESERVED")) { *out = ToneMapping::RESERVED; } else if (0 == compare(tokens[i], jsonChunk, "REINHARD")) { *out = ToneMapping::REINHARD; } else if (0 == compare(tokens[i], jsonChunk, "DISPLAY_RANGE")) { *out = ToneMapping::DISPLAY_RANGE; } else { @@ -279,6 +279,8 @@ static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, ColorGra i = parse(tokens, i + 1, jsonChunk, &out->quality); } else if (compare(tok, jsonChunk, "toneMapping") == 0) { i = parse(tokens, i + 1, jsonChunk, &out->toneMapping); + } else if (compare(tok, jsonChunk, "luminanceScaling") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->luminanceScaling); } else if (compare(tok, jsonChunk, "exposure") == 0) { i = parse(tokens, i + 1, jsonChunk, &out->exposure); } else if (compare(tok, jsonChunk, "temperature") == 0) { @@ -980,6 +982,7 @@ ColorGrading* createColorGrading(const ColorGradingSettings& settings, Engine* e .saturation(settings.saturation) .curves(settings.gamma, settings.midPoint, settings.scale) .toneMapping(settings.toneMapping) + .luminanceScaling(settings.luminanceScaling) .build(*engine); } @@ -1049,7 +1052,7 @@ static std::ostream& operator<<(std::ostream& out, ToneMapping in) { case ToneMapping::ACES_LEGACY: return out << "\"ACES_LEGACY\""; case ToneMapping::ACES: return out << "\"ACES\""; case ToneMapping::FILMIC: return out << "\"FILMIC\""; - case ToneMapping::EVILS: return out << "\"EVILS\""; + case ToneMapping::RESERVED: return out << "\"RESERVED\""; case ToneMapping::REINHARD: return out << "\"REINHARD\""; case ToneMapping::DISPLAY_RANGE: return out << "\"DISPLAY_RANGE\""; } @@ -1089,6 +1092,7 @@ static std::ostream& operator<<(std::ostream& out, const ColorGradingSettings& i << "\"enabled\": " << to_string(in.enabled) << ",\n" << "\"quality\": " << (in.quality) << ",\n" << "\"toneMapping\": " << (in.toneMapping) << ",\n" + << "\"luminanceScaling\": " << (in.luminanceScaling) << ",\n" << "\"exposure\": " << (in.exposure) << ",\n" << "\"temperature\": " << (in.temperature) << ",\n" << "\"tint\": " << (in.tint) << ",\n" @@ -1347,6 +1351,7 @@ bool ColorGradingSettings::operator==(const ColorGradingSettings &rhs) const { return enabled == rhs.enabled && quality == rhs.quality && toneMapping == rhs.toneMapping && + luminanceScaling == rhs.luminanceScaling && exposure == rhs.exposure && temperature == rhs.temperature && tint == rhs.tint && diff --git a/libs/viewer/src/SimpleViewer.cpp b/libs/viewer/src/SimpleViewer.cpp index a87c315738..ffc8b97333 100644 --- a/libs/viewer/src/SimpleViewer.cpp +++ b/libs/viewer/src/SimpleViewer.cpp @@ -151,8 +151,9 @@ static void colorGradingUI(Settings& settings, float* rangePlot, float* curvePlo int toneMapping = (int) colorGrading.toneMapping; ImGui::Combo("Tone-mapping", &toneMapping, - "Linear\0ACES (legacy)\0ACES\0Filmic\0EVILS\0Reinhard\0Display Range\0\0"); + "Linear\0ACES (legacy)\0ACES\0Filmic\0Reserved\0Reinhard\0Display Range\0\0"); colorGrading.toneMapping = (decltype(colorGrading.toneMapping)) toneMapping; + ImGui::Checkbox("Luminance scaling", &colorGrading.luminanceScaling); ImGui::SliderFloat("Exposure", &colorGrading.exposure, -10.0f, 10.0f); diff --git a/libs/viewer/tests/test_settings.cpp b/libs/viewer/tests/test_settings.cpp index 3e106b3ead..3273fb8f8d 100644 --- a/libs/viewer/tests/test_settings.cpp +++ b/libs/viewer/tests/test_settings.cpp @@ -37,6 +37,7 @@ static const char* JSON_TEST_DEFAULTS = R"TXT( "enabled": true, "quality": "MEDIUM", "toneMapping": "ACES_LEGACY", + "luminanceScaling": false, "exposure": 0, "temperature": 0, "tint": 0, diff --git a/samples/material_sandbox.cpp b/samples/material_sandbox.cpp index c7a70b4064..f3b2c53a62 100644 --- a/samples/material_sandbox.cpp +++ b/samples/material_sandbox.cpp @@ -716,7 +716,8 @@ static void gui(filament::Engine* engine, filament::View*) { ImGui::Indent(); ImGui::Checkbox("Enabled##colorGrading", ¶ms.colorGrading); ImGui::Combo("Tone-mapping", &colorGrading.toneMapping, - "Linear\0ACES (legacy)\0ACES\0Filmic\0EVILS\0Reinhard\0Display Range\0\0"); + "Linear\0ACES (legacy)\0ACES\0Filmic\0Reserved\0Reinhard\0Display Range\0\0"); + ImGui::Checkbox("Luminance scaling", &colorGrading.luminanceScaling); if (ImGui::CollapsingHeader("While balance")) { ImGui::SliderInt("Temperature", &colorGrading.temperature, -100, 100); ImGui::SliderInt("Tint", &colorGrading.tint, -100, 100); @@ -984,6 +985,7 @@ static void preRender(filament::Engine* engine, filament::View* view, filament:: .saturation(options.saturation) .curves(options.gamma, options.midPoint, options.scale) .toneMapping(static_cast(options.toneMapping)) + .luminanceScaling(options.luminanceScaling) .build(*engine); if (g_colorGrading) { diff --git a/samples/material_sandbox.h b/samples/material_sandbox.h index 2e6c258db9..022966fe0d 100644 --- a/samples/material_sandbox.h +++ b/samples/material_sandbox.h @@ -62,6 +62,7 @@ using namespace filament; struct ColorGradingOptions { int toneMapping = static_cast(ColorGrading::ToneMapping::ACES_LEGACY); + bool luminanceScaling = false; int temperature = 0; int tint = 0; math::float3 outRed{1.0f, 0.0f, 0.0f}; @@ -88,6 +89,7 @@ struct ColorGradingOptions { bool operator==(const ColorGradingOptions &rhs) const { return toneMapping == rhs.toneMapping && + luminanceScaling == rhs.luminanceScaling && temperature == rhs.temperature && outRed == rhs.outRed && outGreen == rhs.outGreen && diff --git a/web/filament-js/jsenums.cpp b/web/filament-js/jsenums.cpp index de0524ce38..ed7037aad7 100644 --- a/web/filament-js/jsenums.cpp +++ b/web/filament-js/jsenums.cpp @@ -164,7 +164,7 @@ enum_("ColorGrading$ToneMapping") .value("ACES_LEGACY", ColorGrading::ToneMapping::ACES_LEGACY) .value("ACES", ColorGrading::ToneMapping::ACES) .value("FILMIC", ColorGrading::ToneMapping::FILMIC) - .value("EVILS", ColorGrading::ToneMapping::EVILS) + .value("RESERVED", ColorGrading::ToneMapping::RESERVED) .value("REINHARD", ColorGrading::ToneMapping::REINHARD) .value("DISPLAY_RANGE", ColorGrading::ToneMapping::DISPLAY_RANGE);