From a77a9ade29c16ea27528418703573b0bcc756bf9 Mon Sep 17 00:00:00 2001 From: Romain Guy Date: Mon, 19 Jul 2021 17:19:53 -0700 Subject: [PATCH] New tone mapper API (#4330) * WIP New tone mapper API * Implement tone mapper constructors and destructors * Add new genertic tone mapper * Make the generic tone mapper available in our sample UIs * Fix warnings and crashes * Fix generic tone mapper and graph mappers in the UI * Add Java APIs for ToneMapper * Implement copy/move operators for GenericToneMapper --- android/filament-android/CMakeLists.txt | 1 + android/filament-android/libfilament-jni.map | 1 + .../src/main/cpp/ColorGrading.cpp | 21 +- .../src/main/cpp/ToneMapper.cpp | 109 ++++ .../google/android/filament/ColorGrading.java | 34 +- .../google/android/filament/ToneMapper.java | 226 ++++++++ docs/math/Tone mapping operators.nb | 538 +++++++++--------- filament/CMakeLists.txt | 4 +- filament/include/filament/ColorGrading.h | 30 +- filament/include/filament/FilamentAPI.h | 2 +- filament/include/filament/ToneMapper.h | 235 ++++++++ filament/include/filament/View.h | 32 -- filament/src/ColorGrading.cpp | 191 ++----- filament/src/ColorSpace.h | 7 + .../src/{ToneMapping.cpp => ToneMapper.cpp} | 251 ++++++-- filament/src/ToneMapping.h | 101 ---- filament/src/View.cpp | 8 - filament/src/details/View.h | 11 +- libs/viewer/include/viewer/Settings.h | 21 +- libs/viewer/include/viewer/SimpleViewer.h | 1 + libs/viewer/src/Settings.cpp | 119 +++- libs/viewer/src/SimpleViewer.cpp | 69 ++- libs/viewer/tests/test_settings.cpp | 7 + samples/material_sandbox.cpp | 6 +- samples/material_sandbox.h | 4 + web/filament-js/jsenums.cpp | 2 - 26 files changed, 1379 insertions(+), 652 deletions(-) create mode 100644 android/filament-android/src/main/cpp/ToneMapper.cpp create mode 100644 android/filament-android/src/main/java/com/google/android/filament/ToneMapper.java create mode 100644 filament/include/filament/ToneMapper.h rename filament/src/{ToneMapping.cpp => ToneMapper.cpp} (52%) delete mode 100644 filament/src/ToneMapping.h diff --git a/android/filament-android/CMakeLists.txt b/android/filament-android/CMakeLists.txt index 87e9fb8500..e0d4147def 100644 --- a/android/filament-android/CMakeLists.txt +++ b/android/filament-android/CMakeLists.txt @@ -81,6 +81,7 @@ add_library(filament-jni SHARED src/main/cpp/SwapChain.cpp src/main/cpp/Texture.cpp src/main/cpp/TextureSampler.cpp + src/main/cpp/ToneMapper.cpp src/main/cpp/TransformManager.cpp src/main/cpp/VertexBuffer.cpp src/main/cpp/View.cpp diff --git a/android/filament-android/libfilament-jni.map b/android/filament-android/libfilament-jni.map index 42408587a5..1731352a93 100644 --- a/android/filament-android/libfilament-jni.map +++ b/android/filament-android/libfilament-jni.map @@ -15,6 +15,7 @@ LIBFILAMENT { *filament*Renderer*; *filament*RenderTarget*; *filament*Scene*; + *filament*ToneMapper*; *filament*Transform*; *filament*Material*; *filament*IndexBuffer*; diff --git a/android/filament-android/src/main/cpp/ColorGrading.cpp b/android/filament-android/src/main/cpp/ColorGrading.cpp index 725e88dd4f..91c3e3ad76 100644 --- a/android/filament-android/src/main/cpp/ColorGrading.cpp +++ b/android/filament-android/src/main/cpp/ColorGrading.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -30,28 +31,35 @@ Java_com_google_android_filament_ColorGrading_nCreateBuilder(JNIEnv*, jclass) { } extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_ColorGrading_nDestroyBuilder(JNIEnv*, jclass, - jlong nativeBuilder) { +Java_com_google_android_filament_ColorGrading_nDestroyBuilder(JNIEnv*, jclass, jlong nativeBuilder) { ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder; delete builder; } extern "C" JNIEXPORT jlong JNICALL -Java_com_google_android_filament_ColorGrading_nBuilderBuild(JNIEnv*, jclass, - jlong nativeBuilder, jlong nativeEngine) { +Java_com_google_android_filament_ColorGrading_nBuilderBuild(JNIEnv*, jclass, jlong nativeBuilder, jlong nativeEngine) { ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder; Engine *engine = (Engine *) nativeEngine; return (jlong) builder->build(*engine); } extern "C" JNIEXPORT void JNICALL -Java_com_google_android_filament_ColorGrading_nBuilderQuality(JNIEnv*, jclass, - jlong nativeBuilder, jint quality_) { +Java_com_google_android_filament_ColorGrading_nBuilderQuality(JNIEnv*, jclass, jlong nativeBuilder, jint quality_) { ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder; ColorGrading::QualityLevel quality = (ColorGrading::QualityLevel) quality_; builder->quality(quality); } +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_ColorGrading_nBuilderToneMapper(JNIEnv*, jclass, + jlong nativeBuilder, jlong toneMapper_) { + ColorGrading::Builder* builder = (ColorGrading::Builder*) nativeBuilder; + const ToneMapper* toneMapper = (const ToneMapper*) toneMapper_; + builder->toneMapper(toneMapper); +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_ColorGrading_nBuilderToneMapping(JNIEnv*, jclass, jlong nativeBuilder, jint toneMapping_) { @@ -59,6 +67,7 @@ Java_com_google_android_filament_ColorGrading_nBuilderToneMapping(JNIEnv*, jclas ColorGrading::ToneMapping toneMapping = (ColorGrading::ToneMapping) toneMapping_; builder->toneMapping(toneMapping); } +#pragma clang diagnostic pop extern "C" JNIEXPORT void JNICALL Java_com_google_android_filament_ColorGrading_nBuilderLuminanceScaling(JNIEnv*, jclass, diff --git a/android/filament-android/src/main/cpp/ToneMapper.cpp b/android/filament-android/src/main/cpp/ToneMapper.cpp new file mode 100644 index 0000000000..9318d450fd --- /dev/null +++ b/android/filament-android/src/main/cpp/ToneMapper.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2021 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include + +using namespace filament; + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_ToneMapper_nDestroyToneMapper(JNIEnv *env, jclass clazz, + jlong toneMapper_) { + ToneMapper* toneMapper = (ToneMapper*) toneMapper_; + delete toneMapper; +} + +extern "C" JNIEXPORT jlong JNICALL +Java_com_google_android_filament_ToneMapper_nCreateLinearToneMapper(JNIEnv*, jclass) { + return (jlong) new LinearToneMapper(); +} + +extern "C" JNIEXPORT jlong JNICALL +Java_com_google_android_filament_ToneMapper_nCreateACESToneMapper(JNIEnv*, jclass) { + return (jlong) new ACESToneMapper(); +} + +extern "C" JNIEXPORT jlong JNICALL +Java_com_google_android_filament_ToneMapper_nCreateACESLegacyToneMapper(JNIEnv*, jclass) { + return (jlong) new ACESLegacyToneMapper(); +} + +extern "C" JNIEXPORT jlong JNICALL +Java_com_google_android_filament_ToneMapper_nCreateFilmicToneMapper(JNIEnv*, jclass) { + return (jlong) new FilmicToneMapper(); +} + +extern "C" JNIEXPORT jlong JNICALL +Java_com_google_android_filament_ToneMapper_nCreateGenericToneMapper(JNIEnv*, jclass, + jfloat contrast, jfloat shoulder, jfloat midGrayIn, jfloat midGrayOut, jfloat hdrMax) { + return (jlong) new GenericToneMapper(contrast, shoulder, midGrayIn, midGrayOut, hdrMax); +} + +extern "C" JNIEXPORT jfloat JNICALL +Java_com_google_android_filament_ToneMapper_nGenericGetContrast(JNIEnv*, jclass, jlong nativeObject) { + return ((GenericToneMapper*) nativeObject)->getContrast(); +} + +extern "C" JNIEXPORT jfloat JNICALL +Java_com_google_android_filament_ToneMapper_nGenericGetShoulder(JNIEnv*, jclass, jlong nativeObject) { + return ((GenericToneMapper*) nativeObject)->getShoulder(); +} + +extern "C" JNIEXPORT jfloat JNICALL +Java_com_google_android_filament_ToneMapper_nGenericGetMidGrayIn(JNIEnv*, jclass, jlong nativeObject) { + return ((GenericToneMapper*) nativeObject)->getMidGrayIn(); +} + +extern "C" JNIEXPORT jfloat JNICALL +Java_com_google_android_filament_ToneMapper_nGenericGetMidGrayOut(JNIEnv*, jclass, jlong nativeObject) { + return ((GenericToneMapper*) nativeObject)->getMidGrayOut(); +} + +extern "C" JNIEXPORT jfloat JNICALL +Java_com_google_android_filament_ToneMapper_nGenericGetHdrMax(JNIEnv*, jclass, jlong nativeObject) { + return ((GenericToneMapper*) nativeObject)->getHdrMax(); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_ToneMapper_nGenericSetContrast(JNIEnv*, jclass, + jlong nativeObject, jfloat contrast) { + ((GenericToneMapper*) nativeObject)->setContrast(contrast); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_ToneMapper_nGenericSetShoulder(JNIEnv*, jclass, + jlong nativeObject, jfloat shoulder) { + ((GenericToneMapper*) nativeObject)->setShoulder(shoulder); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_ToneMapper_nGenericSetMidGrayIn(JNIEnv*, jclass, + jlong nativeObject, jfloat midGrayIn) { + ((GenericToneMapper*) nativeObject)->setMidGrayIn(midGrayIn); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_ToneMapper_nGenericSetMidGrayOut(JNIEnv*, jclass, + jlong nativeObject, jfloat midGrayOut) { + ((GenericToneMapper*) nativeObject)->setMidGrayOut(midGrayOut); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_android_filament_ToneMapper_nGenericSetHdrMax(JNIEnv*, jclass, + jlong nativeObject, jfloat hdrMax) { + ((GenericToneMapper*) nativeObject)->setHdrMax(hdrMax); +} 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 2118257ba6..01401a1eaa 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 @@ -81,12 +81,12 @@ import static com.google.android.filament.Asserts.assertFloat4In; *
  • Vibrance: 1.0
  • *
  • Saturation: 1.0
  • *
  • Curves: gamma {1,1,1}, midPoint {1,1,1}, and scale {1,1,1}
  • - *
  • Tone mapping: {@link ToneMapping#ACES_LEGACY}
  • + *
  • Tone mapping: {@link ToneMapper.ACESLegacy}
  • *
  • Luminance scaling: false
  • * * * @see View - * @see ToneMapping + * @see ToneMapper */ public class ColorGrading { long mNativeObject; @@ -103,6 +103,8 @@ public class ColorGrading { /** * List of available tone-mapping operators. + * + * @deprecated Use {@link ColorGrading.Builder#toneMapper(ToneMapper)} */ public enum ToneMapping { /** Linear tone mapping (i.e. no tone mapping). */ @@ -113,10 +115,6 @@ public class ColorGrading { ACES, /** Filmic tone mapping, modelled after ACES but applied in sRGB space. */ FILMIC, - /** Reserved for future use. */ - RESERVED, - /** Reinhard luma-based tone mapping. */ - REINHARD, /** Tone mapping used to validate/debug scene exposure. */ DISPLAY_RANGE, } @@ -160,6 +158,25 @@ public class ColorGrading { return this; } + /** + * Selects the tone mapping operator to apply to the HDR color buffer as the last + * operation of the color grading post-processing step. + * + * The default tone mapping operator is {@link ToneMapper.ACESLegacy}. + * + * The specified tone mapper must have a lifecycle that exceeds the lifetime of + * this builder. Since the build(Engine&) method is synchronous, it is safe to + * delete the tone mapper object after that finishes executing. + * + * @param toneMapper The tone mapping operator to apply to the HDR color buffer + * + * @return This Builder, for chaining calls + */ + public Builder toneMapper(ToneMapper toneMapper) { + nBuilderToneMapper(mNativeBuilder, toneMapper.getNativeObject()); + return this; + } + /** * Selects the tone mapping operator to apply to the HDR color buffer as the last * operation of the color grading post-processing step. @@ -169,6 +186,8 @@ public class ColorGrading { * @param toneMapping The tone mapping operator to apply to the HDR color buffer * * @return This Builder, for chaining calls + * + * @deprecated Use {@link #toneMapper(ToneMapper)} */ public Builder toneMapping(ToneMapping toneMapping) { nBuilderToneMapping(mNativeBuilder, toneMapping.ordinal()); @@ -502,7 +521,8 @@ public class ColorGrading { private static native void nDestroyBuilder(long nativeBuilder); private static native void nBuilderQuality(long nativeBuilder, int quality); - private static native void nBuilderToneMapping(long nativeBuilder, int toneMapper); + private static native void nBuilderToneMapper(long nativeBuilder, long toneMapper); + private static native void nBuilderToneMapping(long nativeBuilder, int toneMapping); 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); diff --git a/android/filament-android/src/main/java/com/google/android/filament/ToneMapper.java b/android/filament-android/src/main/java/com/google/android/filament/ToneMapper.java new file mode 100644 index 0000000000..22a64bbf3f --- /dev/null +++ b/android/filament-android/src/main/java/com/google/android/filament/ToneMapper.java @@ -0,0 +1,226 @@ +package com.google.android.filament; + +/** + * Interface for tone mapping operators. A tone mapping operator, or tone mapper, + * is responsible for compressing the dynamic range of the rendered scene to a + * dynamic range suitable for display. + * + * In Filament, tone mapping is a color grading step. ToneMapper instances are + * created and passed to the ColorGrading::Builder to produce a 3D LUT that will + * be used during post-processing to prepare the final color buffer for display. + * + * Filament provides several default tone mapping operators that fall into three + * categories: + * + *
      + *
    • Configurable tone mapping operators
    • + *
        + *
      • GenericToneMapper
      • + *
      + *
    • Fixed-aesthetic tone mapping operators
    • + *
        + *
      • ACESToneMapper
      • + *
      • ACESLegacyToneMapper
      • + *
      • FilmicToneMapper
      • + *
      + *
    • Debug/validation tone mapping operators
    • + *
        + *
      • LinearToneMapper
      • + *
      • DisplayRangeToneMapper
      • + *
      + *
    + * + * You can create custom tone mapping operators by subclassing ToneMapper. + */ +public class ToneMapper { + private final long mNativeObject; + + private ToneMapper(long nativeObject) { + mNativeObject = nativeObject; + } + + public long getNativeObject() { + if (mNativeObject == 0) { + throw new IllegalStateException("Calling method on destroyed ToneMapper"); + } + return mNativeObject; + } + + @Override + protected void finalize() throws Throwable { + try { + super.finalize(); + } finally { + nDestroyToneMapper(mNativeObject); + } + } + + /** + * Linear tone mapping operator that returns the input color but clamped to + * the 0..1 range. This operator is mostly useful for debugging. + */ + public static class Linear extends ToneMapper { + public Linear() { + super(nCreateLinearToneMapper()); + } + } + + /** + * ACES tone mapping operator. This operator is an implementation of the + * ACES Reference Rendering Transform (RRT) combined with the Output Device + * Transform (ODT) for sRGB monitors (dim surround, 100 nits). + */ + public static class ACES extends ToneMapper { + public ACES() { + super(nCreateACESToneMapper()); + } + } + + /** + * ACES tone mapping operator, modified to match the perceived brightness + * of FilmicToneMapper. This operator is the same as ACESToneMapper but + * applies a brightness multiplier of ~1.6 to the input color value to + * target brighter viewing environments. + */ + public static class ACESLegacy extends ToneMapper { + public ACESLegacy() { + super(nCreateACESLegacyToneMapper()); + } + } + + /** + * "Filmic" tone mapping operator. This tone mapper was designed to + * approximate the aesthetics of the ACES RRT + ODT for Rec.709 + * and historically Filament's default tone mapping operator. It exists + * only for backward compatibility purposes and is not otherwise recommended. + */ + public static class Filmic extends ToneMapper { + public Filmic() { + super(nCreateFilmicToneMapper()); + } + } + + /** + * Generic tone mapping operator that gives control over the tone mapping + * curve. This operator can be used to control the aesthetics of the final + * image. This operator also allows to control the dynamic range of the + * scene referred values. + * + * The tone mapping curve is defined by 5 parameters: + *
      + *
    • contrast: controls the contrast of the curve
    • + *
    • shoulder: controls the shoulder of the curve, i.e. how quickly scene + * referred values map to output white
    • + *
    • midGrayIn: sets the input middle gray
    • + *
    • midGrayOut: sets the output middle gray
    • + *
    • hdrMax: defines the maximum input value that will be mapped to + * output white
    • + *
    + */ + public static class Generic extends ToneMapper { + /** + * Builds a new generic tone mapper parameterized to closely approximate + * the {@link ACESLegacy} tone mapper. The default values are: + * + *
      + *
    • contrast = 1.4f
    • + *
    • shoulder = 0.5f
    • + *
    • midGrayIn = 0.18f
    • + *
    • midGrayOut = 0.266f
    • + *
    • hdrMax = 10.0f
    • + *
    + */ + public Generic() { + this(1.4f, 0.5f, 0.18f, 0.266f, 10.0f); + } + + /** + * Builds a new generic tone mapper. + * + * @param contrast: controls the contrast of the curve, must be > 0.0, values + * in the range 0.5..2.0 are recommended. + * @param shoulder: controls the shoulder of the curve, i.e. how quickly scene + * referred values map to output white, between 0.0 and 1.0. + * @param midGrayIn: sets the input middle gray, between 0.0 and 1.0. + * @param midGrayOut: sets the output middle gray, between 0.0 and 1.0. + * @param hdrMax: defines the maximum input value that will be mapped to + * output white. Must be >= 1.0. + */ + public Generic( + float contrast, float shoulder, float midGrayIn, float midGrayOut, float hdrMax) { + super(nCreateGenericToneMapper(contrast, shoulder, midGrayIn, midGrayOut, hdrMax)); + } + + /** Returns the contrast of the curve as a strictly positive value. */ + public float getContrast() { + return nGenericGetContrast(getNativeObject()); + } + + /** Sets the contrast of the curve, must be > 0.0, values in the range 0.5..2.0 are recommended. */ + public void setContrast(float contrast) { + nGenericSetContrast(getNativeObject(), contrast); + } + + /** Returns how fast scene referred values map to output white as a value between 0.0 and 1.0. */ + public float getShoulder() { + return nGenericGetShoulder(getNativeObject()); + } + + /** Sets how quickly scene referred values map to output white, between 0.0 and 1.0. */ + public void setShoulder(float shoulder) { + nGenericSetShoulder(getNativeObject(), shoulder); + } + + /** Returns the middle gray point for input values as a value between 0.0 and 1.0. */ + public float getMidGrayIn() { + return nGenericGetMidGrayIn(getNativeObject()); + } + + /** Sets the input middle gray, between 0.0 and 1.0. */ + public void setMidGrayIn(float midGrayIn) { + nGenericSetMidGrayIn(getNativeObject(), midGrayIn); + } + + /** Returns the middle gray point for output values as a value between 0.0 and 1.0. */ + public float getMidGrayOut() { + return nGenericGetMidGrayOut(getNativeObject()); + } + + /** Sets the output middle gray, between 0.0 and 1.0. */ + public void setMidGrayOut(float midGrayOut) { + nGenericSetMidGrayOut(getNativeObject(), midGrayOut); + } + + /** Returns the maximum input value that will map to output white, as a value >= 1.0. */ + public float getHdrMax() { + return nGenericGetHdrMax(getNativeObject()); + } + + /** Defines the maximum input value that will be mapped to output white. Must be >= 1.0. */ + public void setHdrMax(float hdrMax) { + nGenericSetHdrMax(getNativeObject(), hdrMax); + } + } + + private static native void nDestroyToneMapper(long nativeObject); + + private static native long nCreateLinearToneMapper(); + private static native long nCreateACESToneMapper(); + private static native long nCreateACESLegacyToneMapper(); + private static native long nCreateFilmicToneMapper(); + private static native long nCreateGenericToneMapper( + float contrast, float shoulder, float midGrayIn, float midGrayOut, float hdrMax); + + // Generic tone mappper + private static native float nGenericGetContrast(long nativeObject); + private static native float nGenericGetShoulder(long nativeObject); + private static native float nGenericGetMidGrayIn(long nativeObject); + private static native float nGenericGetMidGrayOut(long nativeObject); + private static native float nGenericGetHdrMax(long nativeObject); + + private static native void nGenericSetContrast(long nativeObject, float contrast); + private static native void nGenericSetShoulder(long nativeObject, float shoulder); + private static native void nGenericSetMidGrayIn(long nativeObject, float midGrayIn); + private static native void nGenericSetMidGrayOut(long nativeObject, float midGrayOut); + private static native void nGenericSetHdrMax(long nativeObject, float hdrMax); +} diff --git a/docs/math/Tone mapping operators.nb b/docs/math/Tone mapping operators.nb index 33c351fd1c..3d8e66783a 100644 --- a/docs/math/Tone mapping operators.nb +++ b/docs/math/Tone mapping operators.nb @@ -10,10 +10,10 @@ NotebookFileLineBreakTest NotebookFileLineBreakTest NotebookDataPosition[ 158, 7] -NotebookDataLength[ 465788, 8885] -NotebookOptionsPosition[ 462584, 8822] -NotebookOutlinePosition[ 462947, 8838] -CellTagsIndexPosition[ 462904, 8835] +NotebookDataLength[ 464050, 8883] +NotebookOptionsPosition[ 460790, 8819] +NotebookOutlinePosition[ 461209, 8836] +CellTagsIndexPosition[ 461166, 8833] WindowFrame->Normal*) (* Beginning of Notebook Content *) @@ -36,7 +36,7 @@ e8c139fd8433"], Cell[BoxData[ RowBox[{"ClearAll", "[", "\"\\"", "]"}]], "Input", CellChangeTimes->{3.647273285923099*^9}, - CellLabel->"In[39]:=",ExpressionUUID->"410c9ead-a5b2-4c59-a953-4ebe80279cd3"], + CellLabel->"In[1]:=",ExpressionUUID->"410c9ead-a5b2-4c59-a953-4ebe80279cd3"], Cell[BoxData[ RowBox[{ @@ -361,7 +361,7 @@ Cell[BoxData[ 3.8282159387720203`*^9, 3.8282159894788837`*^9}, {3.828216033197357*^9, 3.82821604093042*^9}, {3.8282162342269487`*^9, 3.828216234336994*^9}, { 3.8290751162842712`*^9, 3.829075117401083*^9}}, - CellLabel->"In[40]:=",ExpressionUUID->"37bf4303-de95-435d-b24b-32a661b82f4c"] + CellLabel->"In[2]:=",ExpressionUUID->"37bf4303-de95-435d-b24b-32a661b82f4c"] }, Open ]], Cell[CellGroupData[{ @@ -427,30 +427,52 @@ Cell[BoxData[ RowBox[{"Module", "[", "\[IndentingNewLine]", RowBox[{ RowBox[{"{", - RowBox[{"b", ",", "c"}], "}"}], ",", "\[IndentingNewLine]", + RowBox[{"b", ",", "c", ",", "u", ",", "v"}], "}"}], ",", + "\[IndentingNewLine]", RowBox[{ - RowBox[{"b", ":=", + RowBox[{"u", ":=", + RowBox[{"(", + RowBox[{ + RowBox[{"(", + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"hdrMax", "^", "contrast"}], ")"}], "^", "shoulder"}], + "-", + RowBox[{ + RowBox[{"(", + RowBox[{"midIn", "^", "contrast"}], ")"}], "^", "shoulder"}]}], + ")"}], "*", "midOut"}], ")"}]}], ";", "\[IndentingNewLine]", + RowBox[{"v", ":=", RowBox[{ RowBox[{"(", RowBox[{ - RowBox[{"-", - RowBox[{"midIn", "^", "contrast"}]}], "+", - RowBox[{ - RowBox[{"(", - RowBox[{"hdrMax", "^", "contrast"}], ")"}], "*", "midOut"}]}], - ")"}], "/", + RowBox[{"(", + RowBox[{"midIn", "^", "contrast"}], ")"}], "^", "shoulder"}], + ")"}], "*", "midOut"}]}], ";", "\[IndentingNewLine]", + RowBox[{"b", ":=", + RowBox[{"-", RowBox[{"(", RowBox[{ RowBox[{"(", RowBox[{ + RowBox[{"-", + RowBox[{"midIn", "^", "contrast"}]}], "+", RowBox[{ RowBox[{"(", - RowBox[{"hdrMax", "^", "contrast"}], ")"}], "^", "shoulder"}], - "-", - RowBox[{ - RowBox[{"(", - RowBox[{"midIn", "^", "contrast"}], ")"}], "^", "shoulder"}]}], - ")"}], "*", "midOut"}], ")"}]}]}], ";", "\[IndentingNewLine]", + RowBox[{"midOut", "*", + RowBox[{"(", + RowBox[{ + RowBox[{ + RowBox[{ + RowBox[{"(", + RowBox[{"hdrMax", "^", "contrast"}], ")"}], "^", + "shoulder"}], "*", + RowBox[{"midIn", "^", "contrast"}]}], "-", + RowBox[{ + RowBox[{"hdrMax", "^", "contrast"}], "*", "v"}]}], ")"}]}], + ")"}], "/", "u"}]}], ")"}], "/", "v"}], ")"}]}]}], ";", + "\[IndentingNewLine]", RowBox[{"c", ":=", RowBox[{ RowBox[{"(", @@ -463,24 +485,8 @@ Cell[BoxData[ ")"}], "*", RowBox[{"midIn", "^", "contrast"}]}], "-", RowBox[{ - RowBox[{"hdrMax", "^", "contrast"}], "*", - RowBox[{"(", - RowBox[{ - RowBox[{"(", - RowBox[{"midIn", "^", "contrast"}], ")"}], "^", "shoulder"}], - ")"}], "*", "midOut"}]}], ")"}], "/", - RowBox[{"(", - RowBox[{ - RowBox[{"(", - RowBox[{ - RowBox[{ - RowBox[{"(", - RowBox[{"hdrMax", "^", "contrast"}], ")"}], "^", "shoulder"}], - "-", - RowBox[{ - RowBox[{"(", - RowBox[{"midIn", "^", "contrast"}], ")"}], "^", "shoulder"}]}], - ")"}], "*", "midOut"}], ")"}]}]}], ";", "\[IndentingNewLine]", + RowBox[{"hdrMax", "^", "contrast"}], "*", "v"}]}], ")"}], "/", + "u"}]}], ";", "\[IndentingNewLine]", RowBox[{"Clip", "[", RowBox[{ RowBox[{ @@ -511,8 +517,14 @@ Cell[BoxData[ 3.68157419395932*^9, 3.6815741963772993`*^9}, {3.6815764433067923`*^9, 3.68157650410535*^9}, {3.6815765444344*^9, 3.681576553628613*^9}, { 3.6815766779076223`*^9, 3.681576683504825*^9}, {3.681576791776896*^9, - 3.681576801635625*^9}, {3.681577130551074*^9, 3.681577145078849*^9}}, - CellLabel->"In[64]:=",ExpressionUUID->"64a40cba-fe9b-420c-bc1f-e2b70d44b247"], + 3.681576801635625*^9}, {3.681577130551074*^9, 3.681577145078849*^9}, { + 3.835448616137144*^9, 3.835448672061781*^9}, 3.835448718592013*^9, { + 3.8354493939519176`*^9, 3.8354494638612022`*^9}, {3.835449542277781*^9, + 3.835449565587693*^9}, {3.835449676874386*^9, 3.835449679705332*^9}, { + 3.835449812254682*^9, 3.835449815965712*^9}, {3.835449854066792*^9, + 3.835449890030797*^9}, {3.8354499345326567`*^9, 3.8354499549855556`*^9}, + 3.835450007110338*^9, {3.8354500887817793`*^9, 3.835450297667041*^9}}, + CellLabel->"In[58]:=",ExpressionUUID->"64a40cba-fe9b-420c-bc1f-e2b70d44b247"], Cell[CellGroupData[{ @@ -551,21 +563,21 @@ Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{"{", - RowBox[{"hdrMax", ",", " ", "8.0"}], "}"}], ",", " ", "1.0", ",", " ", - "64.0", ",", + RowBox[{"hdrMax", ",", " ", "10.0"}], "}"}], ",", " ", "1.0", ",", + " ", "64.0", ",", RowBox[{"Appearance", "\[Rule]", "\"\\""}]}], "}"}], ",", "\[IndentingNewLine]", " ", RowBox[{"{", RowBox[{ RowBox[{"{", - RowBox[{"contrast", ",", " ", "1.6"}], "}"}], ",", " ", "0.2", ",", + RowBox[{"contrast", ",", " ", "1.4"}], "}"}], ",", " ", "0.2", ",", " ", "4.0", ",", RowBox[{"Appearance", "\[Rule]", "\"\\""}]}], "}"}], ",", "\[IndentingNewLine]", " ", RowBox[{"{", RowBox[{ RowBox[{"{", - RowBox[{"shoulder", ",", " ", "0.977"}], "}"}], ",", " ", "0.8", ",", + RowBox[{"shoulder", ",", " ", "1.0"}], "}"}], ",", " ", "0.8", ",", " ", "1.1", ",", RowBox[{"Appearance", "\[Rule]", "\"\\""}]}], "}"}], ",", "\[IndentingNewLine]", " ", @@ -579,7 +591,7 @@ Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{"{", - RowBox[{"midOut", ",", " ", "0.267"}], "}"}], ",", " ", "0.01", ",", + RowBox[{"midOut", ",", " ", "0.266"}], "}"}], ",", " ", "0.01", ",", " ", "1.0", ",", RowBox[{"Appearance", "\[Rule]", "\"\\""}]}], "}"}]}], "\[IndentingNewLine]", "]"}], "\[IndentingNewLine]"}]}]], "Input", @@ -599,37 +611,33 @@ Cell[BoxData[ 3.6815767583633633`*^9, 3.681576787392421*^9}, {3.681577249487246*^9, 3.681577249582507*^9}, {3.6815772923183823`*^9, 3.681577345973983*^9}, { 3.828216441863907*^9, 3.828216442176573*^9}, {3.8282196475098047`*^9, - 3.8282196532681303`*^9}, {3.829075192883951*^9, 3.8290751931232347`*^9}}, - CellLabel->"In[78]:=",ExpressionUUID->"ed06a09c-d067-4495-8651-30989ac4c29c"], + 3.8282196532681303`*^9}, {3.829075192883951*^9, 3.8290751931232347`*^9}, { + 3.835453429995984*^9, 3.83545343769248*^9}, {3.835458120849481*^9, + 3.835458140489389*^9}, {3.8354598602280397`*^9, 3.8354598687779617`*^9}, { + 3.835459910575705*^9, 3.835459910670258*^9}}, + CellLabel->"In[87]:=",ExpressionUUID->"ed06a09c-d067-4495-8651-30989ac4c29c"], Cell[BoxData[ TagBox[ StyleBox[ - DynamicModuleBox[{$CellContext`contrast$$ = 1.6, $CellContext`hdrMax$$ = - 8., $CellContext`midIn$$ = 0.18, $CellContext`midOut$$ = - 0.267, $CellContext`shoulder$$ = 0.977, Typeset`show$$ = True, + DynamicModuleBox[{$CellContext`contrast$$ = 1.4, $CellContext`hdrMax$$ = + 10., $CellContext`midIn$$ = 0.18, $CellContext`midOut$$ = + 0.266, $CellContext`shoulder$$ = 1., Typeset`show$$ = True, Typeset`bookmarkList$$ = {}, Typeset`bookmarkMode$$ = "Menu", Typeset`animator$$, Typeset`animvar$$ = 1, Typeset`name$$ = "\"untitled\"", Typeset`specs$$ = {{{ - Hold[$CellContext`hdrMax$$], 8.}, 1., 64.}, {{ - Hold[$CellContext`contrast$$], 1.6}, 0.2, 4.}, {{ - Hold[$CellContext`shoulder$$], 0.977}, 0.8, 1.1}, {{ + Hold[$CellContext`hdrMax$$], 10.}, 1., 64.}, {{ + Hold[$CellContext`contrast$$], 1.4}, 0.2, 4.}, {{ + Hold[$CellContext`shoulder$$], 1.}, 0.8, 1.1}, {{ Hold[$CellContext`midIn$$], 0.18}, 0.01, 1.}, {{ - Hold[$CellContext`midOut$$], 0.267}, 0.01, 1.}}, Typeset`size$$ = { + Hold[$CellContext`midOut$$], 0.266}, 0.01, 1.}}, Typeset`size$$ = { 576., {175., 179.}}, Typeset`update$$ = 0, Typeset`initDone$$, - Typeset`skipInitDone$$ = True, $CellContext`hdrMax$118281$$ = - 0, $CellContext`contrast$118282$$ = 0, $CellContext`shoulder$118283$$ = - 0, $CellContext`midIn$118284$$ = 0, $CellContext`midOut$118285$$ = 0}, + Typeset`skipInitDone$$ = True}, DynamicBox[Manipulate`ManipulateBoxes[ 1, StandardForm, - "Variables" :> {$CellContext`contrast$$ = 1.6, $CellContext`hdrMax$$ = - 8., $CellContext`midIn$$ = 0.18, $CellContext`midOut$$ = - 0.267, $CellContext`shoulder$$ = 0.977}, "ControllerVariables" :> { - Hold[$CellContext`hdrMax$$, $CellContext`hdrMax$118281$$, 0], - Hold[$CellContext`contrast$$, $CellContext`contrast$118282$$, 0], - Hold[$CellContext`shoulder$$, $CellContext`shoulder$118283$$, 0], - Hold[$CellContext`midIn$$, $CellContext`midIn$118284$$, 0], - Hold[$CellContext`midOut$$, $CellContext`midOut$118285$$, 0]}, + "Variables" :> {$CellContext`contrast$$ = 1.4, $CellContext`hdrMax$$ = + 10., $CellContext`midIn$$ = 0.18, $CellContext`midOut$$ = + 0.266, $CellContext`shoulder$$ = 1.}, "ControllerVariables" :> {}, "OtherVariables" :> { Typeset`show$$, Typeset`bookmarkList$$, Typeset`bookmarkMode$$, Typeset`animator$$, Typeset`animvar$$, Typeset`name$$, @@ -640,11 +648,11 @@ $CellContext`contrast$$, $CellContext`shoulder$$, $CellContext`midIn$$, \ $CellContext`midOut$$], $CellContext`linearACES[$CellContext`x]}, {$CellContext`x, 0.01, $CellContext`hdrMax$$ 2.}, ImageSize -> Large], - "Specifications" :> {{{$CellContext`hdrMax$$, 8.}, 1., 64., Appearance -> - "Labeled"}, {{$CellContext`contrast$$, 1.6}, 0.2, 4., Appearance -> - "Labeled"}, {{$CellContext`shoulder$$, 0.977}, 0.8, 1.1, Appearance -> + "Specifications" :> {{{$CellContext`hdrMax$$, 10.}, 1., 64., Appearance -> + "Labeled"}, {{$CellContext`contrast$$, 1.4}, 0.2, 4., Appearance -> + "Labeled"}, {{$CellContext`shoulder$$, 1.}, 0.8, 1.1, Appearance -> "Labeled"}, {{$CellContext`midIn$$, 0.18}, 0.01, 1., Appearance -> - "Labeled"}, {{$CellContext`midOut$$, 0.267}, 0.01, 1., Appearance -> + "Labeled"}, {{$CellContext`midOut$$, 0.266}, 0.01, 1., Appearance -> "Labeled"}}, "Options" :> {}, "DefaultOptions" :> {}], ImageSizeCache->{621., {276., 282.}}, SingleEvaluation->True], @@ -677,8 +685,12 @@ $CellContext`midOut$$], 3.769265415320115*^9}, 3.828213903386292*^9, 3.828213969527108*^9, 3.82821633309171*^9, 3.8282164442445498`*^9, 3.828219572670334*^9, 3.828219638020262*^9, 3.828219686933632*^9, 3.829074722398052*^9, - 3.829075127004231*^9, 3.829075195850285*^9}, - CellLabel->"Out[78]=",ExpressionUUID->"a30d7fbc-a755-4233-a527-6fed4a693589"] + 3.829075127004231*^9, 3.829075195850285*^9, 3.83544720066486*^9, + 3.835449467742729*^9, 3.835450305028063*^9, 3.835450368746719*^9, + 3.835453438064548*^9, 3.835458109583084*^9, 3.835458140802999*^9, + 3.8354583348534727`*^9, {3.835459908223538*^9, 3.835459910993792*^9}, + 3.835460943063118*^9}, + CellLabel->"Out[87]=",ExpressionUUID->"6b1dd3b9-aead-47ff-a023-bad9bf13c501"] }, Open ]] }, Open ]], @@ -735,26 +747,26 @@ Cell[BoxData[ RowBox[{ RowBox[{"linearSiragusanoSmithImpl", "[", RowBox[{ - "x", ",", "contrast", ",", "midIn", ",", "midOut", ",", "hdrMax"}], - "]"}], ",", + RowBox[{"x", "*", "1.6"}], ",", "contrast", ",", "midIn", ",", + "midOut", ",", "hdrMax"}], "]"}], ",", RowBox[{"linearACES", "[", "x", "]"}]}], "}"}], ",", " ", RowBox[{"{", RowBox[{"x", ",", " ", "0.01", ",", " ", - RowBox[{"hdrMax", "*", "2.0"}]}], "}"}], ",", "\[IndentingNewLine]", + RowBox[{"hdrMax", "*", "1.5"}]}], "}"}], ",", "\[IndentingNewLine]", " ", RowBox[{"ImageSize", "\[Rule]", "Large"}]}], "\[IndentingNewLine]", " ", "]"}], ",", "\[IndentingNewLine]", " ", RowBox[{"{", RowBox[{ RowBox[{"{", - RowBox[{"hdrMax", ",", "5.5"}], "}"}], ",", " ", "1.0", ",", " ", + RowBox[{"hdrMax", ",", "10.0"}], "}"}], ",", " ", "1.0", ",", " ", "16.0", ",", RowBox[{"Appearance", "\[Rule]", "\"\\""}]}], "}"}], ",", "\[IndentingNewLine]", " ", RowBox[{"{", RowBox[{ RowBox[{"{", - RowBox[{"contrast", ",", " ", "4.24"}], "}"}], ",", " ", "0.2", ",", + RowBox[{"contrast", ",", " ", "1.75"}], "}"}], ",", " ", "0.2", ",", " ", "8.0", ",", RowBox[{"Appearance", "\[Rule]", "\"\\""}]}], "}"}], ",", "\[IndentingNewLine]", " ", @@ -768,57 +780,53 @@ Cell[BoxData[ RowBox[{"{", RowBox[{ RowBox[{"{", - RowBox[{"midOut", ",", " ", "0.281"}], "}"}], ",", " ", "0.01", ",", - " ", "1.0", ",", + RowBox[{"midOut", ",", " ", "0.18"}], "}"}], ",", " ", "0.01", ",", " ", + "1.0", ",", RowBox[{"Appearance", "\[Rule]", "\"\\""}]}], "}"}]}], "\[IndentingNewLine]", "]"}]], "Input", CellChangeTimes->{{3.8282144101229486`*^9, 3.828214478627986*^9}, { 3.828214881087673*^9, 3.828214910755719*^9}, {3.8282161343858356`*^9, 3.828216138249515*^9}, {3.828216177374241*^9, 3.828216188372609*^9}, { 3.828216220346726*^9, 3.828216228729636*^9}, {3.829075131924676*^9, - 3.829075136377384*^9}, {3.829075186029532*^9, 3.829075190546693*^9}}, - CellLabel->"In[79]:=",ExpressionUUID->"572cd540-59b1-4415-8369-fb210674631e"], + 3.829075136377384*^9}, {3.829075186029532*^9, 3.829075190546693*^9}, { + 3.835447447096184*^9, 3.835447447622985*^9}, {3.83544757775528*^9, + 3.835447603585886*^9}, {3.8354476896906023`*^9, 3.83544768977808*^9}, { + 3.835451476405488*^9, 3.835451517961009*^9}}, + CellLabel->"In[76]:=",ExpressionUUID->"572cd540-59b1-4415-8369-fb210674631e"], Cell[BoxData[ TagBox[ StyleBox[ - DynamicModuleBox[{$CellContext`contrast$$ = - 3.2700000000000005`, $CellContext`hdrMax$$ = 5.5, $CellContext`midIn$$ = - 0.18, $CellContext`midOut$$ = 0.281, Typeset`show$$ = True, - Typeset`bookmarkList$$ = {}, Typeset`bookmarkMode$$ = "Menu", - Typeset`animator$$, Typeset`animvar$$ = 1, Typeset`name$$ = - "\"untitled\"", Typeset`specs$$ = {{{ - Hold[$CellContext`hdrMax$$], 5.5}, 1., 16.}, {{ - Hold[$CellContext`contrast$$], 4.24}, 0.2, 8.}, {{ + DynamicModuleBox[{$CellContext`contrast$$ = 1.75, $CellContext`hdrMax$$ = + 10., $CellContext`midIn$$ = 0.18, $CellContext`midOut$$ = 0.18, + Typeset`show$$ = True, Typeset`bookmarkList$$ = {}, + Typeset`bookmarkMode$$ = "Menu", Typeset`animator$$, Typeset`animvar$$ = + 1, Typeset`name$$ = "\"untitled\"", Typeset`specs$$ = {{{ + Hold[$CellContext`hdrMax$$], 10.}, 1., 16.}, {{ + Hold[$CellContext`contrast$$], 1.75}, 0.2, 8.}, {{ Hold[$CellContext`midIn$$], 0.18}, 0.01, 1.}, {{ - Hold[$CellContext`midOut$$], 0.281}, 0.01, 1.}}, Typeset`size$$ = { + Hold[$CellContext`midOut$$], 0.18}, 0.01, 1.}}, Typeset`size$$ = { 576., {175., 179.}}, Typeset`update$$ = 0, Typeset`initDone$$, - Typeset`skipInitDone$$ = True, $CellContext`hdrMax$119299$$ = - 0, $CellContext`contrast$119300$$ = 0, $CellContext`midIn$119301$$ = - 0, $CellContext`midOut$119302$$ = 0}, + Typeset`skipInitDone$$ = True}, DynamicBox[Manipulate`ManipulateBoxes[ 1, StandardForm, - "Variables" :> {$CellContext`contrast$$ = 4.24, $CellContext`hdrMax$$ = - 5.5, $CellContext`midIn$$ = 0.18, $CellContext`midOut$$ = 0.281}, - "ControllerVariables" :> { - Hold[$CellContext`hdrMax$$, $CellContext`hdrMax$119299$$, 0], - Hold[$CellContext`contrast$$, $CellContext`contrast$119300$$, 0], - Hold[$CellContext`midIn$$, $CellContext`midIn$119301$$, 0], - Hold[$CellContext`midOut$$, $CellContext`midOut$119302$$, 0]}, + "Variables" :> {$CellContext`contrast$$ = 1.75, $CellContext`hdrMax$$ = + 10., $CellContext`midIn$$ = 0.18, $CellContext`midOut$$ = 0.18}, + "ControllerVariables" :> {}, "OtherVariables" :> { Typeset`show$$, Typeset`bookmarkList$$, Typeset`bookmarkMode$$, Typeset`animator$$, Typeset`animvar$$, Typeset`name$$, Typeset`specs$$, Typeset`size$$, Typeset`update$$, Typeset`initDone$$, Typeset`skipInitDone$$}, "Body" :> LogLinearPlot[{ - $CellContext`linearSiragusanoSmithImpl[$CellContext`x, \ -$CellContext`contrast$$, $CellContext`midIn$$, $CellContext`midOut$$, \ -$CellContext`hdrMax$$], + $CellContext`linearSiragusanoSmithImpl[$CellContext`x + 1.6, $CellContext`contrast$$, $CellContext`midIn$$, \ +$CellContext`midOut$$, $CellContext`hdrMax$$], $CellContext`linearACES[$CellContext`x]}, {$CellContext`x, - 0.01, $CellContext`hdrMax$$ 2.}, ImageSize -> Large], - "Specifications" :> {{{$CellContext`hdrMax$$, 5.5}, 1., 16., Appearance -> - "Labeled"}, {{$CellContext`contrast$$, 4.24}, 0.2, 8., Appearance -> + 0.01, $CellContext`hdrMax$$ 1.5}, ImageSize -> Large], + "Specifications" :> {{{$CellContext`hdrMax$$, 10.}, 1., 16., Appearance -> + "Labeled"}, {{$CellContext`contrast$$, 1.75}, 0.2, 8., Appearance -> "Labeled"}, {{$CellContext`midIn$$, 0.18}, 0.01, 1., Appearance -> - "Labeled"}, {{$CellContext`midOut$$, 0.281}, 0.01, 1., Appearance -> + "Labeled"}, {{$CellContext`midOut$$, 0.18}, 0.01, 1., Appearance -> "Labeled"}}, "Options" :> {}, "DefaultOptions" :> {}], ImageSizeCache->{621., {262., 268.}}, SingleEvaluation->True], @@ -836,8 +844,10 @@ $CellContext`hdrMax$$], 3.828216138674839*^9, {3.828216177790884*^9, 3.828216188667598*^9}, { 3.828216220720991*^9, 3.828216229116953*^9}, 3.8282163332414083`*^9, 3.828219572886441*^9, 3.829074723057993*^9, {3.829075127220955*^9, - 3.829075141313972*^9}, 3.829075197767853*^9}, - CellLabel->"Out[79]=",ExpressionUUID->"f99f5796-ecdd-42d7-a6b6-f31b1a2b9276"] + 3.829075141313972*^9}, 3.829075197767853*^9, 3.835447200861053*^9, + 3.835447448168345*^9, {3.835447578239978*^9, 3.8354476038554688`*^9}, { + 3.835451469688581*^9, 3.835451518279397*^9}}, + CellLabel->"Out[76]=",ExpressionUUID->"07c8965f-0e25-48b0-9508-0543006a9e84"] }, Open ]] }, Open ]], @@ -925,10 +935,11 @@ Cell[BoxData[{ 3.6611825845991983`*^9, 3.661182623850226*^9}, {3.661182700881919*^9, 3.6611827058815527`*^9}, {3.661183995743362*^9, 3.6611840139014072`*^9}, { 3.6617916813195972`*^9, 3.661791691374861*^9}}, - CellLabel->"In[67]:=",ExpressionUUID->"68982d2b-cd3f-4394-b9b7-bc306b15c89c"], + CellLabel->"In[29]:=",ExpressionUUID->"68982d2b-cd3f-4394-b9b7-bc306b15c89c"], Cell[BoxData[ - TemplateBox[{GraphicsBox[{{{{}, {}, + TemplateBox[{ + GraphicsBox[{{{{}, {}, TagBox[{ Directive[ Opacity[1.], @@ -1007,7 +1018,7 @@ jfPI5IHcwRHi4rL/BxQnrzk= 2.0149261220954124`, 1.}, {2.0828887964840312`, 1.}, { 2.15085147087265, 1.}, {2.226718211446049, 1.}, { 2.3025849520194486`, 1.}}]}, - Annotation[#, "Charting`Private`Tag$114555#1"]& ], + Annotation[#, "Charting`Private`Tag$3753#1"]& ], TagBox[{ Directive[ Opacity[1.], @@ -1089,7 +1100,7 @@ mBHBgQSwz+3WITG7yjS0DkdxQDg3LrdCn8QMa1T8UbHmcCo7N9pwrd/Q5SYZ zQG/vvV5uqYk5o7WLxWcNS/q6ORJWZKYA+2hPmYxHPAocs1bsiExh5vt+J+t eUokNa/DnsT8EJpqqhDLAUfv5rwyJxJzsdf4Ytya/wciaVKM "]]}, - Annotation[#, "Charting`Private`Tag$114555#2"]& ], + Annotation[#, "Charting`Private`Tag$3753#2"]& ], TagBox[{ Directive[ Opacity[1.], @@ -1125,7 +1136,7 @@ aag9Tqy9LPTtLUeQDQFlKjec8Hy0xHFYimB+WWZZzS6cuJe8yyCkGkEKiywT 7MWJycCaNZoaBHz1YrG7N05s3q2KGa9HMOPmJl7pixMJUa9vn25EcLYiXDzr hxOZ7Ha7cRmC8YUF4t6A//6j2DisGUFwtEIsDcEJgXndtvctCP4Fc05nmw== - "]]}, Annotation[#, "Charting`Private`Tag$114555#3"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$3753#3"]& ], TagBox[{ Directive[ Opacity[1.], @@ -1196,7 +1207,7 @@ pRFP0mk3ZHNICGUIsqL0aITaBBHb/Y+9P8lk7zahESf31a53ySVhksPJXmFB I1xNwxu35ZHgkueYPXWCRnQF7xERyidhaN7N7CYbGsFcql5d849tPWqyC3k0 4sPuK4uu3CXhf7rBYIg= "]]}, - Annotation[#, "Charting`Private`Tag$114555#4"]& ], + Annotation[#, "Charting`Private`Tag$3753#4"]& ], TagBox[{ Directive[ Opacity[1.], @@ -1232,7 +1243,7 @@ A+0/lD9mp9lEAkABSMfpVArtPw+nkqe0SQJAxUxZ1fUL7T+KDr+nj04CQHxA yPKVDe0/f90XqEVYAkDONG7E0xDtP/pERKggXQJA7NU9eXES7T90rHCo+2EC QLKmG2EOFO0/7xOdqNZmAkA391N8qhXtP2p7yaixawJAORczy0UX7T8xZ2Ms - "]]}, Annotation[#, "Charting`Private`Tag$114555#5"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$3753#5"]& ], TagBox[{ Directive[ Opacity[1.], @@ -1322,7 +1333,7 @@ Dma/l/j5o6KTIJh9O/vpfg5mxGeF4ftrjqSysmNMOZi8Zx/KDK455LNojr41 B7Pm1uIeN7FJWNLTy5G052BaDZMIxWv2feyZs3ySg3mxqeXB3JonhJJzus5w MDv/OPylIT4JZwMbc4pdOZg0tU63C2v+HzjHAm4= "]]}, - Annotation[#, "Charting`Private`Tag$114555#6"]& ], + Annotation[#, "Charting`Private`Tag$3753#6"]& ], TagBox[{ Directive[ Opacity[1.], @@ -1346,14 +1357,8 @@ eaKRKl7gv5/RmyOVXOk/t+S8/bgX2L+Fv9LHnffqPxgt6OeAcM2/XRkRYdPS 7D8G+I5IhOG3vx6Awgnnq+4/U7U5Xg3bpD99pb6Vi0zwP/fV5ZsB1Mc/jGJG cq1p8T+sKSbIBpnUP85PyjBBhfI/JFto5LWX2T8zMzMzMzPzP9x9Y74= "]]}, - Annotation[#, - "Charting`Private`Tag$114555#7"]& ], {}}, {{}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}}, {{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}}}, \ -{}}, {DisplayFunction -> Identity, + Annotation[#, "Charting`Private`Tag$3753#7"]& ], {}}}, {}}, { + DisplayFunction -> Identity, Method -> { "DefaultBoundaryStyle" -> Automatic, "DefaultGraphicsInteraction" -> { @@ -1367,8 +1372,8 @@ cq1p8T+sKSbIBpnUP85PyjBBhfI/JFto5LWX2T8zMzMzMzPzP9x9Y74= None}, DisplayFunction -> Identity, DisplayFunction -> Identity, Ticks -> {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Automatic}, - AxesOrigin -> {-4.605170045013494, 0}, FrameTicks -> {{Automatic, - Charting`ScaledFrameTicks[{Identity, Identity}]}, {Quiet[ + AxesOrigin -> {-4.605170045013494, 0}, + FrameTicks -> {{Automatic, Automatic}, {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Charting`ScaledFrameTicks[{Log, Exp}]}}, GridLines -> {None, None}, DisplayFunction -> Identity, PlotRangePadding -> {{ @@ -1413,11 +1418,13 @@ cq1p8T+sKSbIBpnUP85PyjBBhfI/JFto5LWX2T8zMzMzMzPzP9x9Y74= "freeformCursorMode" -> True, "placement" -> {"x" -> "All", "y" -> "None"}}}}, "DefaultMeshStyle" -> AbsolutePointSize[6], "ScalingFunctions" -> - None}, PlotRange -> {{-4.605170045013494, 2.3025849520194486`}, { - 0, 1.2}}, PlotRangeClipping -> True, PlotRangePadding -> {{ + None}, + PlotRange -> {{-4.605170045013494, 2.3025849520194486`}, {0, 1.2}}, + PlotRangeClipping -> True, PlotRangePadding -> {{ Scaled[0.02], Scaled[0.02]}, {Automatic, Automatic}}, - Ticks -> {Automatic, Automatic}}],FormBox[ + Ticks -> {Automatic, Automatic}}], + FormBox[ FormBox[ TemplateBox[{ "\"ACES\"", "\"Unreal\"", "\"Uncharted 2\"", "\"FilmicALU\"", @@ -1985,11 +1992,13 @@ cq1p8T+sKSbIBpnUP85PyjBBhfI/JFto5LWX2T8zMzMzMzPzP9x9Y74= 3.8282139036958523`*^9, 3.828213969751474*^9, 3.828214111317655*^9, 3.8282142008868*^9, {3.828214234665811*^9, 3.828214279564385*^9}, 3.828215966170525*^9, 3.828216048945711*^9, 3.828216333521703*^9, - 3.828219573265332*^9, 3.82907472379275*^9, 3.829075127596117*^9}, - CellLabel->"Out[68]=",ExpressionUUID->"e5fead6a-d2f8-4e08-b029-dde7f7c9c501"], + 3.828219573265332*^9, 3.82907472379275*^9, 3.829075127596117*^9, + 3.8354472012332478`*^9}, + CellLabel->"Out[30]=",ExpressionUUID->"6ef38163-1cbf-4b9b-86ca-ec90ebdeada7"], Cell[BoxData[ - TemplateBox[{GraphicsBox[{{{{}, {}, + TemplateBox[{ + GraphicsBox[{{{{}, {}, TagBox[{ Directive[ Opacity[1.], @@ -2025,7 +2034,7 @@ l+k/Xa1j32Llib/espX7qKLpP7uwHhe4qIa/nXr6mG2l6T8ZtNlODWyDv9Nu XlYxqOk/qnWffG/leb+0WZsxtq3pP2Z8FewZbHO/A3GwT3ew6T9FBhe3iOVp v7v1PI43s+k/eicGLLvlWb91WV/t9rXpP6WcmpB3Onm+YTQ2bbW46T9W33Fn - "]]}, Annotation[#, "Charting`Private`Tag$114850#1"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$4119#1"]& ], TagBox[{ Directive[ Opacity[1.], @@ -2076,7 +2085,7 @@ nzAt8zMI0Kvq2qsZeBqFGlt6TWURID6RHxMii0SiK/nl+XkE+MRoj+oFclHR 0vKuyWsE7FDVrU2W+SH3uJQDtrcIiDJSXdUgc0Wig9orc0UE3LqcmxpuHtkk PrfeefQOAf8CVRir7A== "]]}, - Annotation[#, "Charting`Private`Tag$114850#2"]& ], + Annotation[#, "Charting`Private`Tag$4119#2"]& ], TagBox[{ Directive[ Opacity[1.], @@ -2112,7 +2121,7 @@ Ld8/Xa1j32Llib/kJDfe6EzfP7uwHhe4qIa/t+rrYshU3z8ZtNlODWyDv7S9 j6moXN8/qnWffG/leb8uqH56a2zfP2Z8FewZbHO/jj22A0503z9FBhe3iOVp vxzctUwxfN8/eicGLLvlWb+3MvNUFYTfP6WcmpB3Onm+6bbjG/qL3z/CwXcl - "]]}, Annotation[#, "Charting`Private`Tag$114850#3"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$4119#3"]& ], TagBox[{ Directive[ Opacity[1.], @@ -2163,7 +2172,7 @@ H4TFTAkFUy1bpeT5aYgnypWsq6LAsdi134VKRE9N7qjZNVBQdVdLvUIcj7j7 VH26iwJzOfXys5QXihV5HE/ooSBcX86girJHBZabIi68ouD6tcyUENOwmn6n LbS0fgr+BY5ur6A= "]]}, - Annotation[#, "Charting`Private`Tag$114850#4"]& ], + Annotation[#, "Charting`Private`Tag$4119#4"]& ], TagBox[{ Directive[ Opacity[1.], @@ -2199,7 +2208,7 @@ st8/Xa1j32Llib9xYHpnNczfP7uwHhe4qIa/jJodrq7S3z8ZtNlODWyDv2x7 dvgn2d8/qnWffG/leb84kiqWGubfP2Z8FewZbHO/EXZ26JPs3z9FBhe3iOVp v+dcWTwN898/eicGLLvlWb8JnEuRhvnfP6WcmpB3Onm+b4jF5v//3z8UuWtE - "]]}, Annotation[#, "Charting`Private`Tag$114850#5"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$4119#5"]& ], TagBox[{ Directive[ Opacity[1.], @@ -2290,7 +2299,7 @@ N74tw22QTUS7inO8UGFBxsuIlvLiTCKhbxvdX40F86+02Li90wlhi42/O/ey xILSs7fO+46HECOWC+a7zFngdl7wi4h3AGFyqs3itSUL9LmEnsaPexBFSUXX z1mzIFSKS6Zm3JbI787dJmHHgsKbOSnBmiF1xnb1PxodWPA/oycXEA== "]]}, - Annotation[#, "Charting`Private`Tag$114850#6"]& ], + Annotation[#, "Charting`Private`Tag$4119#6"]& ], TagBox[{ Directive[ Opacity[1.], @@ -2326,7 +2335,7 @@ ue8/Xa1j32Llib8nipYkDdHvP7uwHhe4qIa/L4XBtufW7z8ZtNlODWyDv36b o1zD3O8/qnWffG/leb9RDFjkfejvP2Z8FewZbHO/YPePxlzu7z9FBhe3iOVp v8oeSr089O8/eicGLLvlWb80YrnIHfrvP6WcmpB3Onm+nKoQ6f//7z+Q63WU - "]]}, Annotation[#, "Charting`Private`Tag$114850#7"]& ]}}, {}}, { + "]]}, Annotation[#, "Charting`Private`Tag$4119#7"]& ]}}, {}}, { DisplayFunction -> Identity, Method -> { "DefaultBoundaryStyle" -> Automatic, @@ -2341,8 +2350,8 @@ v8oeSr089O8/eicGLLvlWb80YrnIHfrvP6WcmpB3Onm+nKoQ6f//7z+Q63WU None}, DisplayFunction -> Identity, DisplayFunction -> Identity, Ticks -> {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Automatic}, - AxesOrigin -> {-4.605170092005026, 0}, FrameTicks -> {{Automatic, - Charting`ScaledFrameTicks[{Identity, Identity}]}, {Quiet[ + AxesOrigin -> {-4.605170092005026, 0}, + FrameTicks -> {{Automatic, Automatic}, {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Charting`ScaledFrameTicks[{Log, Exp}]}}, GridLines -> {None, None}, DisplayFunction -> Identity, PlotRangePadding -> {{ @@ -2394,7 +2403,8 @@ v8oeSr089O8/eicGLLvlWb80YrnIHfrvP6WcmpB3Onm+nKoQ6f//7z+Q63WU Scaled[0.02], Scaled[0.02]}, { Scaled[0.02], - Scaled[0.02]}}, Ticks -> {Automatic, Automatic}}],FormBox[ + Scaled[0.02]}}, Ticks -> {Automatic, Automatic}}], + FormBox[ FormBox[ TemplateBox[{ "\"ACES\"", "\"Unreal\"", "\"Uncharted 2\"", "\"FilmicALU\"", @@ -2962,11 +2972,13 @@ v8oeSr089O8/eicGLLvlWb80YrnIHfrvP6WcmpB3Onm+nKoQ6f//7z+Q63WU 3.8282139036958523`*^9, 3.828213969751474*^9, 3.828214111317655*^9, 3.8282142008868*^9, {3.828214234665811*^9, 3.828214279564385*^9}, 3.828215966170525*^9, 3.828216048945711*^9, 3.828216333521703*^9, - 3.828219573265332*^9, 3.82907472379275*^9, 3.829075127779908*^9}, - CellLabel->"Out[69]=",ExpressionUUID->"b1d485ba-4af0-4fad-a439-0355ec4bddd0"], + 3.828219573265332*^9, 3.82907472379275*^9, 3.829075127596117*^9, + 3.835447201356091*^9}, + CellLabel->"Out[31]=",ExpressionUUID->"ff04d788-1bb5-49c3-ab5f-f3b4468aaf5b"], Cell[BoxData[ - TemplateBox[{GraphicsBox[{{{{}, {}, + TemplateBox[{ + GraphicsBox[{{{{}, {}, TagBox[{ Directive[ Opacity[1.], @@ -3123,7 +3135,7 @@ ewpQTblxzNfV7EpqBYR+DF78YMCNfiVNPCfrKoCVfXbi+iZuLC3xnUz4UAHR lPKmTWu4Uf5G+usL1ErQ5Z4/40rmxnzTlSBVz0q49TXpX8HgKiRWjkcfYq8C L34Tt5M3V+Has0oPHR9Wwf8AaJWeuA== "]]}, - Annotation[#, "Charting`Private`Tag$115097#1"]& ], + Annotation[#, "Charting`Private`Tag$4363#1"]& ], TagBox[{ Directive[ Opacity[1.], @@ -3329,7 +3341,7 @@ KsFCKSlnWcAlyYr/0o0S3It9DDfcWSAvsmGM+V0JlmihJbebs0AFs6Dy02Ol uODjLf0TJBZ4EtFYN7K7DL9h8EhMe8EMVsN/hc5ceIzFjydOvWtghqtLO1Vc Yx/j069Aj6mGGfKUwmdPZj7GlsXkwpgyZth2g15nU/cY/w9kbtPG "]]}, - Annotation[#, "Charting`Private`Tag$115097#2"]& ], + Annotation[#, "Charting`Private`Tag$4363#2"]& ], TagBox[{ Directive[ Opacity[1.], @@ -3456,7 +3468,7 @@ cJUv8j7IKbR9pUyzoAtFv9es/D4Y/ElNMf7Igj+o0lcbucrhSCkXI6iQBbl0 VySWOT+A6aE6zUUyC7YavQ6+cfIBcD8L7xPkYEHjQdV+7rIHYDxDsp5YI6F6 guJTh6cP4H9CYBJ9 "]]}, - Annotation[#, "Charting`Private`Tag$115097#3"]& ], + Annotation[#, "Charting`Private`Tag$4363#3"]& ], TagBox[{ Directive[ Opacity[1.], @@ -3556,7 +3568,7 @@ UDJo0GKdaQ702mrLhNwTQumsg+7W1rnwVsGZThgK4cvamskOvwcQ8bR4eD1X EIMKa5KFYgugXapP/7CfIPb+o+kfercANM4Q8fHegihfOLhlSXEBVI7vg14v QVwXqlxiU1IA/wdnq7a6 "]]}, - Annotation[#, "Charting`Private`Tag$115097#4"]& ], + Annotation[#, "Charting`Private`Tag$4363#4"]& ], TagBox[{ Directive[ Opacity[1.], @@ -3672,7 +3684,7 @@ uyW74yHMfBCNHeUW3yCCOlY73Apc8iFf/talRZoI9lHE1t+vzoeGbavfdVUL Y7FPkEdnSgGQus2tM74JoWL4zjPha4vgFPy+fi5KEAVesnRmvxcD3ylhtVlh AXzHt8XFSf8GpFXVTKyKXYGtntfbfrvehX1n7/TwtPKh1nFOrWvtPfgfBwIA 6g== - "]]}, Annotation[#, "Charting`Private`Tag$115097#5"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$4363#5"]& ], TagBox[{ Directive[ Opacity[1.], @@ -3951,7 +3963,7 @@ qvb5j32BdKDEMmVwfm8FPi74Vff8dTp4+GNZcd+pClwlgDc11YsOQgwut+27 X4EP4pd1d87TwZvqD+fefavARbolU/pM6eBSSmpVh9VT/PHnGG0XAh1AqGhg hFAlblPD7UncooW9EdKNVo2V+P8AubECYQ== "]]}, - Annotation[#, "Charting`Private`Tag$115097#6"]& ], + Annotation[#, "Charting`Private`Tag$4363#6"]& ], TagBox[{ Directive[ Opacity[1.], @@ -3974,14 +3986,8 @@ wC6xJg08kKM/pyNv73D/G8Bjzl3YKUKlP3VmB77sRxvA/yinKgwQpz9Lme8u ou4dATgYwBXlKaymVLA/DKF4xZ5/F8Bn1IxZN7mxPwamS7idfhfALYcmu1S7 sT9BOCGu "]]}, - Annotation[#, - "Charting`Private`Tag$115097#7"]& ], {}}, {{}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}}, {{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}}}, \ -{}}, {DisplayFunction -> Identity, + Annotation[#, "Charting`Private`Tag$4363#7"]& ], {}}}, {}}, { + DisplayFunction -> Identity, Method -> { "DefaultBoundaryStyle" -> Automatic, "DefaultGraphicsInteraction" -> { @@ -3995,8 +4001,8 @@ sT9BOCGu None}, DisplayFunction -> Identity, DisplayFunction -> Identity, Ticks -> {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Automatic}, - AxesOrigin -> {-11.512925277004099`, 0}, FrameTicks -> {{Automatic, - Charting`ScaledFrameTicks[{Identity, Identity}]}, {Quiet[ + AxesOrigin -> {-11.512925277004099`, 0}, + FrameTicks -> {{Automatic, Automatic}, {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Charting`ScaledFrameTicks[{Log, Exp}]}}, GridLines -> {None, None}, DisplayFunction -> Identity, PlotRangePadding -> {{ @@ -4048,7 +4054,8 @@ sT9BOCGu Scaled[0.02], Scaled[0.02]}, { Scaled[0.02], - Scaled[0.02]}}, Ticks -> {Automatic, Automatic}}],FormBox[ + Scaled[0.02]}}, Ticks -> {Automatic, Automatic}}], + FormBox[ FormBox[ TemplateBox[{ "\"ACES\"", "\"Unreal\"", "\"Uncharted 2\"", "\"FilmicALU\"", @@ -4616,8 +4623,9 @@ sT9BOCGu 3.8282139036958523`*^9, 3.828213969751474*^9, 3.828214111317655*^9, 3.8282142008868*^9, {3.828214234665811*^9, 3.828214279564385*^9}, 3.828215966170525*^9, 3.828216048945711*^9, 3.828216333521703*^9, - 3.828219573265332*^9, 3.82907472379275*^9, 3.829075128052208*^9}, - CellLabel->"Out[70]=",ExpressionUUID->"5252c3f2-e36c-4cac-abc5-4cebb92e9767"] + 3.828219573265332*^9, 3.82907472379275*^9, 3.829075127596117*^9, + 3.835447201605631*^9}, + CellLabel->"Out[32]=",ExpressionUUID->"c85963ab-1c7d-41ff-bc3a-2dd458ecbd3a"] }, Open ]] }, Open ]], @@ -4695,10 +4703,11 @@ Cell[BoxData[{ 3.6611822457483683`*^9, 3.661182319186528*^9}, {3.6611824483634167`*^9, 3.661182462538444*^9}, {3.6611827846096888`*^9, 3.661182801081038*^9}, { 3.661184057215249*^9, 3.661184059245432*^9}}, - CellLabel->"In[71]:=",ExpressionUUID->"b2cdebdd-b060-471e-8ddd-416664a1997c"], + CellLabel->"In[33]:=",ExpressionUUID->"b2cdebdd-b060-471e-8ddd-416664a1997c"], Cell[BoxData[ - TemplateBox[{GraphicsBox[{{{{}, {}, + TemplateBox[{ + GraphicsBox[{{{{}, {}, TagBox[{ Directive[ Opacity[1.], @@ -4779,7 +4788,7 @@ atH/A55NUeQ= 1.99306016080119, 1.}, {2.0213779417964477`, 1.}, { 2.0496957227917054`, 1.}, {2.176140290414044, 1.}, { 2.3025848580363832`, 1.}}]}, - Annotation[#, "Charting`Private`Tag$115423#1"]& ], + Annotation[#, "Charting`Private`Tag$4686#1"]& ], TagBox[{ Directive[ Opacity[1.], @@ -4890,7 +4899,7 @@ qnwSv5uG9HBS6djnf54cuqe9IkVDagk0MecBCpwLu05mVKAhOTAZ9Tn9c6+i V9IeVRpSYONu5hf/3BxpRTE1oCEdTpmMNSVRQEXFKPmSGQ1J/mDseMY/l3/X 1Ak+S0N63iQ0tfTPUg+P/Eh0oCFNX+pKUdOgQCbIpJS50pDOMi/SR/zz/wCl lhm4 - "]]}, Annotation[#, "Charting`Private`Tag$115423#2"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$4686#2"]& ], TagBox[{ Directive[ Opacity[1.], @@ -4929,7 +4938,7 @@ TGh+ZtOnEQeunl+GujEJUxAUKkY04dASa4/bnSJhN309SssRDkZGNpme50jY IidgX3szDpUT5ifu/UHCxq1X2z604D9+PvI93ZmEXd926/5MKw55oJlV4UXC QnVcqfw2HP4DbiWeGQ== "]]}, - Annotation[#, "Charting`Private`Tag$115423#3"]& ], + Annotation[#, "Charting`Private`Tag$4686#3"]& ], TagBox[{ Directive[ Opacity[1.], @@ -4994,7 +5003,7 @@ mGYnJGP7f84vZngQoNTeaHF8now9d7yw04xBwCrt0vTUNRTMQHa5JtKTgMGe 24SjLQUrnGqaDfYmwMTE7s5fThSsgaqWIuVDQMmwhVWUBwWT3bwzrfCXtVP2 /MjwoWCsZPYqC18CckDnLjeQgnW6Pujt+eX/AQz1IuU= "]]}, - Annotation[#, "Charting`Private`Tag$115423#4"]& ], + Annotation[#, "Charting`Private`Tag$4686#4"]& ], TagBox[{ Directive[ Opacity[1.], @@ -5034,7 +5043,7 @@ g8x0XRKW7WLLn7yOw3cpa7PSjoRtSqztovFw2H/p1KCeAwl7pJ6i87JxkDjG 8Ba6kLDYlExubw4ODSm+P3duJ2Eya6vaxDwcnJ3p2eE+JIw8WsVtzcfhfs/G ref3kbDXFzQ7LAX4n1/WDmUFkbCM3sa+4Js43IBlOeURJOzzSFdgaQEO/wHR Yc4f - "]]}, Annotation[#, "Charting`Private`Tag$115423#5"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$4686#5"]& ], TagBox[{ Directive[ Opacity[1.], @@ -5187,8 +5196,8 @@ u3kaZD37J1XH6Slswj/4gWUaEra1xRjP0lPIvTO1NzYs0FRzwHGFntIURDPM 2aahee+VeGlNBkrkoTtfT2647OGp6aOGDJTdBZrtpRvW0DB+evEYA4XMKcm9 sOG84QN6fqcZKNudDwsqbJne+N/2z8TZMVB4GKfGrDacDDuf5TozUCZ/awZH bPh/DBbI2Q== - "]]}, - Annotation[#, "Charting`Private`Tag$115423#6"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$4686#6"]& ], + TagBox[{ Directive[ Opacity[1.], @@ -5336,14 +5345,8 @@ EFFhzk1XKoO2fP6nWfKLYDUy9VOjuwLc1tTfRfssQsm+nFNn+Gqg89WtOYrf i1C1waB+uusjBIYpOqiv/4Erj8v7Llo1gAVfLMMc4xLs03G5Et3WAENuU+pV IksgxchznsO+EVT//5bg/wAoBzs1 "]]}, - Annotation[#, - "Charting`Private`Tag$115423#7"]& ], {}}, {{}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}}, {{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}}}, \ -{}}, {DisplayFunction -> Identity, + Annotation[#, "Charting`Private`Tag$4686#7"]& ], {}}}, {}}, { + DisplayFunction -> Identity, Method -> { "DefaultBoundaryStyle" -> Automatic, "DefaultGraphicsInteraction" -> { @@ -5357,8 +5360,8 @@ IksgxchznsO+EVT//5bg/wAoBzs1 None}, DisplayFunction -> Identity, DisplayFunction -> Identity, Ticks -> {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Automatic}, - AxesOrigin -> {-9.21034013701852, 0}, FrameTicks -> {{Automatic, - Charting`ScaledFrameTicks[{Identity, Identity}]}, {Quiet[ + AxesOrigin -> {-9.21034013701852, 0}, + FrameTicks -> {{Automatic, Automatic}, {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Charting`ScaledFrameTicks[{Log, Exp}]}}, GridLines -> {None, None}, DisplayFunction -> Identity, PlotRangePadding -> {{ @@ -5402,11 +5405,13 @@ IksgxchznsO+EVT//5bg/wAoBzs1 "freeformCursorMode" -> True, "placement" -> {"x" -> "All", "y" -> "None"}}}}, "DefaultMeshStyle" -> AbsolutePointSize[6], "ScalingFunctions" -> - None}, PlotRange -> {{-9.21034013701852, 2.3025848580363832`}, { - 0, 1.2}}, PlotRangeClipping -> True, PlotRangePadding -> {{ + None}, + PlotRange -> {{-9.21034013701852, 2.3025848580363832`}, {0, 1.2}}, + PlotRangeClipping -> True, PlotRangePadding -> {{ Scaled[0.02], Scaled[0.02]}, {Automatic, Automatic}}, - Ticks -> {Automatic, Automatic}}],FormBox[ + Ticks -> {Automatic, Automatic}}], + FormBox[ FormBox[ TemplateBox[{ "\"ACES\"", "\"Unreal\"", "\"Uncharted 2\"", "\"FilmicALU\"", @@ -5974,11 +5979,12 @@ IksgxchznsO+EVT//5bg/wAoBzs1 3.82821397022586*^9, 3.828214126107312*^9, 3.828214211992898*^9, { 3.8282142663632183`*^9, 3.828214282041113*^9}, 3.828215969020541*^9, 3.828216053649629*^9, 3.828216334183318*^9, 3.82821957417743*^9, - 3.829074725573061*^9, 3.829075128404272*^9}, - CellLabel->"Out[72]=",ExpressionUUID->"24825b91-4503-4163-b50c-82e4e331dc8f"], + 3.829074725573061*^9, 3.829075128404272*^9, 3.8354472019954042`*^9}, + CellLabel->"Out[34]=",ExpressionUUID->"5f3a1ac2-1732-4cba-b9ab-1746b32f50c9"], Cell[BoxData[ - TemplateBox[{GraphicsBox[{{{{}, {}, + TemplateBox[{ + GraphicsBox[{{{{}, {}, TagBox[{ Directive[ Opacity[1.], @@ -6015,7 +6021,7 @@ Lpo9688dVxFAqx3cQwnNRj4jS1mdQwSUnyqMDVelIv3i1IM/jxNwPNaEoIVe QCcpNXd5UwRsI5nJUlQCxHCJptj+Q8BZG5J9oyoIWZNJa+f/JaDkan7mabfU puLqoi2dcwT8B+HsdSY= "]]}, - Annotation[#, "Charting`Private`Tag$115784#1"]& ], + Annotation[#, "Charting`Private`Tag$5044#1"]& ], TagBox[{ Directive[ Opacity[1.], @@ -6096,7 +6102,7 @@ zt8n7k0Xsmuq+WBbfOa9w0gasVNKf1GvjQ/VD+lyVQUpxMD4zJXhTj7Il/cb SZxPIoIt8ueCu/lQ5J0V4D4SQ1xXHxYp7eODcwB5Uv58OKHRbH1bb4APHGG5 yugRP6Jcs2jLm/d88GcLb6kecSWiBbkt5z7x4UFGevyVPTG1RPAjt8VRPvwP YvZWyQ== - "]]}, Annotation[#, "Charting`Private`Tag$115784#2"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$5044#2"]& ], TagBox[{ Directive[ Opacity[1.], @@ -6133,7 +6139,7 @@ jXpnDuc/GbTZTg1sk7/5mB+ZsRPnP6p1n3xv5Ym/P8LXkUQe5z9mfBXsGWyD v1PdsGmNI+c/RQYXt4jleb9inVTS1SjnP3onBiy75Wm/n46cyh0u5z+lnJqQ dzqJvm9OYlFlM+c/LgtyQQ== "]]}, - Annotation[#, "Charting`Private`Tag$115784#3"]& ], + Annotation[#, "Charting`Private`Tag$5044#3"]& ], TagBox[{ Directive[ Opacity[1.], @@ -6176,7 +6182,7 @@ lr+yFS/IMNPqPxm02U4NbJO/x5X9XJ3W6j+qdZ98b+WJv0R39jRx3eo/ZnwV 7Blsg7/GKLB42ODqP0UGF7eI5Xm/dO9I9z3k6j96JwYsu+Vpv6eACrGh5+o/ pZyakHc6ib7sYT+mA+vqP7SSFPY= "]]}, - Annotation[#, "Charting`Private`Tag$115784#4"]& ], + Annotation[#, "Charting`Private`Tag$5044#4"]& ], TagBox[{ Directive[ Opacity[1.], @@ -6212,7 +6218,7 @@ Juc/Xa1j32Llmb9E2JPhjTfnP7uwHhe4qJa/ksIxYOA75z8ZtNlODWyTv3uD 6PExQOc/qnWffG/lib9K609L0kjnP2Z8FewZbIO/F8xZESFN5z9FBhe3iOV5 v+P4LuduUec/eicGLLvlab8Dm/3Lu1XnP6WcmpB3Oom+x3v0vgda5z/YXWr1 - "]]}, Annotation[#, "Charting`Private`Tag$115784#5"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$5044#5"]& ], TagBox[{ Directive[ Opacity[1.], @@ -6357,7 +6363,7 @@ QW5GFxSywabY4aP9SDIrfSit3LuSDXVlNMlHBYmsPiopkqhmA7Xy3V7B0wks PRdaFHctG4q80wPOjlxj6a3M5bvOYoNzAJlNPR3KWlk/E7nvGRuMeSSrI0Yu srztL2gL/8cGPwUe5boRV9Zg1VrRtudsyL17J85X99qTDv8PlGutbPgffkrZ qA== - "]]}, Annotation[#, "Charting`Private`Tag$115784#6"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$5044#6"]& ], TagBox[{ Directive[ Opacity[1.], @@ -6489,15 +6495,8 @@ w9m7F8Gy1G7MduoeESXQNeWquAR1z0R4a4rSiDbmX99enF4C/sohA2aXFOLN Pl9XHsclKPHKCXCbiiHKJjgOst9bAscA7nl+l1sEy67bmaXlS6BFw/siesqX mCOTfG3VsQR+UjR766auEO+qKup3TS9BQXZmord6TKOlOE/Wzs4S/A+QpM73 - "]]}, - Annotation[#, - "Charting`Private`Tag$115784#7"]& ], {}}, {{}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}}, {{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}}}, \ -{}}, {DisplayFunction -> Identity, + "]]}, Annotation[#, "Charting`Private`Tag$5044#7"]& ], {}}}, {}}, { + DisplayFunction -> Identity, Method -> { "DefaultBoundaryStyle" -> Automatic, "DefaultGraphicsInteraction" -> { @@ -6511,8 +6510,8 @@ mCOTfG3VsQR+UjR766auEO+qKup3TS9BQXZmord6TKOlOE/Wzs4S/A+QpM73 None}, DisplayFunction -> Identity, DisplayFunction -> Identity, Ticks -> {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Automatic}, - AxesOrigin -> {-9.210340184010052, 0}, FrameTicks -> {{Automatic, - Charting`ScaledFrameTicks[{Identity, Identity}]}, {Quiet[ + AxesOrigin -> {-9.210340184010052, 0}, + FrameTicks -> {{Automatic, Automatic}, {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Charting`ScaledFrameTicks[{Log, Exp}]}}, GridLines -> {None, None}, DisplayFunction -> Identity, PlotRangePadding -> {{ @@ -6563,7 +6562,8 @@ mCOTfG3VsQR+UjR766auEO+qKup3TS9BQXZmord6TKOlOE/Wzs4S/A+QpM73 Scaled[0.02], Scaled[0.02]}, { Scaled[0.02], - Scaled[0.02]}}, Ticks -> {Automatic, Automatic}}],FormBox[ + Scaled[0.02]}}, Ticks -> {Automatic, Automatic}}], + FormBox[ FormBox[ TemplateBox[{ "\"ACES\"", "\"Unreal\"", "\"Uncharted 2\"", "\"FilmicALU\"", @@ -7131,11 +7131,12 @@ mCOTfG3VsQR+UjR766auEO+qKup3TS9BQXZmord6TKOlOE/Wzs4S/A+QpM73 3.82821397022586*^9, 3.828214126107312*^9, 3.828214211992898*^9, { 3.8282142663632183`*^9, 3.828214282041113*^9}, 3.828215969020541*^9, 3.828216053649629*^9, 3.828216334183318*^9, 3.82821957417743*^9, - 3.829074725573061*^9, 3.829075128761147*^9}, - CellLabel->"Out[73]=",ExpressionUUID->"01c2383b-3dfd-4f52-844a-4b9ba0d93f61"], + 3.829074725573061*^9, 3.829075128404272*^9, 3.835447202151905*^9}, + CellLabel->"Out[35]=",ExpressionUUID->"65440c48-1b97-41ac-b448-e197bec4a3cf"], Cell[BoxData[ - TemplateBox[{GraphicsBox[{{{{}, {}, + TemplateBox[{ + GraphicsBox[{{{{}, {}, TagBox[{ Directive[ Opacity[1.], @@ -7163,7 +7164,7 @@ whDANdZScm6luj/tHzZhfQgQwObU9czrLb4/bw3nuZh9DsCiNfcxc1DBP/7A ssyQ8QzAAraw+Mfbwz993SdmIoALwAYDQPPJmMY/DNo8RI/vCcAOjP8OxQLK P4s/+6iVeQjAe+8d09unzT+7QRz5ORUHwM/5MOCiydA/WGCdOQ== "]]}, - Annotation[#, "Charting`Private`Tag$116105#1"]& ], + Annotation[#, "Charting`Private`Tag$5362#1"]& ], TagBox[{ Directive[ Opacity[1.], @@ -7260,7 +7261,7 @@ zUOei/eFcJhzT6Xo6E2YldHyjNskhLVkBY/9ES0QvHnydmGcII4stdpEbGyF NbzRl7UggN1nlTKOlSLEvZT1pSfyY9fJ+dSooH9AYFTfNHOOF53D5uYdJzvh NPy4khe1CXnduN29z/UA92k++WU+HrzWZ5JMye0HWYFt/qMiG3FgVXW8vPsx /A8+TYC5 - "]]}, Annotation[#, "Charting`Private`Tag$116105#2"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$5362#2"]& ], TagBox[{ Directive[ Opacity[1.], @@ -7289,7 +7290,7 @@ ssyQ8QzA5oghKbLfxT993SdmIoALwHnBKOZAusc/DNo8RI/vCcAy23I5kujJ P4s/+6iVeQjATgohqLEdzD8Eiwop9goHwNdVh3Rrc84/jLa57TF9BcCy/EQY 05fQPxUD8BWzSAXAz/kw4KLJ0D/yNLIF "]]}, - Annotation[#, "Charting`Private`Tag$116105#3"]& ], + Annotation[#, "Charting`Private`Tag$5362#3"]& ], TagBox[{ Directive[ Opacity[1.], @@ -7319,8 +7320,8 @@ EMBZ5ZhAj160P+0fNmF9CBDAbGqgpzP7uD9vDee5mH0OwBRY6JMUmL4//sCy zJDxDMDHUCtIg2DCP33dJ2YigAvArUFPuHeMxT8M2jxEj+8JwC+XvTSFUck/ iz/7qJV5CMAe0Ql+BSbNPwSLCin2CgfA7hTeoE6Y0D+RIbuyTeoGwM/5MOCi ydA/O3+7Dg== - "]]}, - Annotation[#, "Charting`Private`Tag$116105#4"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$5362#4"]& ], + TagBox[{ Directive[ Opacity[1.], @@ -7348,7 +7349,7 @@ CBDAQRju0ruHxD9vDee5mH0OwJg5q/zcacY//sCyzJDxDMAZb0Xn7mvIP33d J2YigAvAj2N8Hkdyyj8M2jxEj+8JwCMuYdE+0cw/iz/7qJV5CMDrY7REZTTP P7LSrhR1HwfAz/kw4KLJ0D9GcJiy "]]}, - Annotation[#, "Charting`Private`Tag$116105#5"]& ], + Annotation[#, "Charting`Private`Tag$5362#5"]& ], TagBox[{ Directive[ Opacity[1.], @@ -7532,8 +7533,8 @@ C7/I9OaA7ME2gXz1Vqy3e5uSiDMHeAUT6fcCWjFX4DQjjyEHGCR21bevtuIc 8YrMdTEOGPo39rImCHDHSYU37x6xAyHaW+xAdBvmHFbXuTW3DRa9UkxEnz7B N/Hf4jt+W2Fn1gy3pEcXZrnJLvObnQ1S5FVmWrNe4KGAzY8MNyu8+iM/ntfd h/8H1qki4w== - "]]}, - Annotation[#, "Charting`Private`Tag$116105#6"]& ], + "]]}, Annotation[#, "Charting`Private`Tag$5362#6"]& ], + TagBox[{ Directive[ Opacity[1.], @@ -7665,14 +7666,8 @@ m+B0xogySz4BdenKrSrczRDFuedDcgYBL1Gz9p6WbYbzPzSUc+MJOG9rsmRk 3gwZR4vfy0QR8Nqkgcj9/c2QPygQXXaagAkv415ZBzRDkVO0knIQAYsep6lP xTVDeddc951j/3piBizy85vhf2IYixE= "]]}, - Annotation[#, - "Charting`Private`Tag$116105#7"]& ], {}}, {{}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}}, {{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, \ -{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}}}, \ -{}}, {DisplayFunction -> Identity, + Annotation[#, "Charting`Private`Tag$5362#7"]& ], {}}}, {}}, { + DisplayFunction -> Identity, Method -> { "DefaultBoundaryStyle" -> Automatic, "DefaultGraphicsInteraction" -> { @@ -7686,8 +7681,8 @@ xTVDeddc951j/3piBizy85vhf2IYixE= None}, DisplayFunction -> Identity, DisplayFunction -> Identity, Ticks -> {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Automatic}, - AxesOrigin -> {-11.512925277004099`, 0}, FrameTicks -> {{Automatic, - Charting`ScaledFrameTicks[{Identity, Identity}]}, {Quiet[ + AxesOrigin -> {-11.512925277004099`, 0}, + FrameTicks -> {{Automatic, Automatic}, {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Charting`ScaledFrameTicks[{Log, Exp}]}}, GridLines -> {None, None}, DisplayFunction -> Identity, PlotRangePadding -> {{ @@ -7740,7 +7735,8 @@ xTVDeddc951j/3piBizy85vhf2IYixE= Scaled[0.02], Scaled[0.02]}, { Scaled[0.02], - Scaled[0.02]}}, Ticks -> {Automatic, Automatic}}],FormBox[ + Scaled[0.02]}}, Ticks -> {Automatic, Automatic}}], + FormBox[ FormBox[ TemplateBox[{ "\"ACES\"", "\"Unreal\"", "\"Uncharted 2\"", "\"FilmicALU\"", @@ -8308,8 +8304,8 @@ xTVDeddc951j/3piBizy85vhf2IYixE= 3.82821397022586*^9, 3.828214126107312*^9, 3.828214211992898*^9, { 3.8282142663632183`*^9, 3.828214282041113*^9}, 3.828215969020541*^9, 3.828216053649629*^9, 3.828216334183318*^9, 3.82821957417743*^9, - 3.829074725573061*^9, 3.829075129044258*^9}, - CellLabel->"Out[74]=",ExpressionUUID->"6324d624-4e4a-4526-85dc-1a7a380f86a3"] + 3.829074725573061*^9, 3.829075128404272*^9, 3.8354472025216208`*^9}, + CellLabel->"Out[36]=",ExpressionUUID->"45b95cdd-213f-4412-9335-ca0c706aafea"] }, Open ]] }, Open ]], @@ -8346,10 +8342,11 @@ Cell[BoxData[{ RowBox[{"PlotLegends", "\[Rule]", "acesOperatorNames"}]}], "]"}], "\[IndentingNewLine]"}], "Input", CellChangeTimes->{{3.681738302645213*^9, 3.681738406719469*^9}}, - CellLabel->"In[75]:=",ExpressionUUID->"adff9626-1268-4d99-9c85-40a974589dd7"], + CellLabel->"In[37]:=",ExpressionUUID->"adff9626-1268-4d99-9c85-40a974589dd7"], Cell[BoxData[ - TemplateBox[{GraphicsBox[{{{{}, {}, + TemplateBox[{ + GraphicsBox[{{{{}, {}, TagBox[{ Directive[ Opacity[1.], @@ -8448,7 +8445,7 @@ Js1t1zjh/Cd8nx1vVXPD+SbfrycHSvLC+frLz1owz+aD8w0t3ZPmyAnA+QuY NjReeYjg17x4pWq2UBDO/xzdvfRmgRCc72C8pW6WkTCcP4GP1Wz/PAT//svQ t4+5ROB8AEugbUw= "]]}, - Annotation[#, "Charting`Private`Tag$116427#1"]& ], + Annotation[#, "Charting`Private`Tag$5681#1"]& ], TagBox[{ Directive[ Opacity[1.], @@ -8543,9 +8540,7 @@ DfEUeRI9M1Q0uSX3c6o7DY0dPT6qNE9FbuK1Vw0f0VAl/s0V95uKnDabbjB7 0JDTZ9sLV9apSPnqoc4rnn//cX73Q8wggK7WWajwetHQP31DSZIsAujjwBax 8r/MYvGixotdAD1yLL5r9ZiGBifP//zGJYBmpZKB4k1D/wMcoaAT "]]}, - Annotation[#, - "Charting`Private`Tag$116427#2"]& ], {}}, {{}, {}, {}, {}, {}}, {{}, \ -{}, {}, {}, {}}}, {}}, { + Annotation[#, "Charting`Private`Tag$5681#2"]& ], {}}}, {}}, { DisplayFunction -> Identity, Method -> { "DefaultBoundaryStyle" -> Automatic, @@ -8560,8 +8555,8 @@ DfEUeRI9M1Q0uSX3c6o7DY0dPT6qNE9FbuK1Vw0f0VAl/s0V95uKnDabbjB7 None}, DisplayFunction -> Identity, DisplayFunction -> Identity, Ticks -> {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Automatic}, - AxesOrigin -> {-4.6051699897471625`, 0}, FrameTicks -> {{Automatic, - Charting`ScaledFrameTicks[{Identity, Identity}]}, {Quiet[ + AxesOrigin -> {-4.6051699897471625`, 0}, + FrameTicks -> {{Automatic, Automatic}, {Quiet[ Charting`ScaledTicks[{Log, Exp}][#, #2, {6, 6}]]& , Charting`ScaledFrameTicks[{Log, Exp}]}}, GridLines -> {None, None}, DisplayFunction -> Identity, PlotRangePadding -> {{ @@ -8610,7 +8605,8 @@ DfEUeRI9M1Q0uSX3c6o7DY0dPT6qNE9FbuK1Vw0f0VAl/s0V95uKnDabbjB7 14}}, PlotRangeClipping -> True, PlotRangePadding -> {{ Scaled[0.02], Scaled[0.02]}, {Automatic, Automatic}}, - Ticks -> {Automatic, Automatic}}],FormBox[ + Ticks -> {Automatic, Automatic}}], + FormBox[ FormBox[ TemplateBox[{"\"ACES\"", "\"ACES Rec.2020 1k\""}, "LineLegend", DisplayFunction -> (FormBox[ @@ -8814,17 +8810,19 @@ DfEUeRI9M1Q0uSX3c6o7DY0dPT6qNE9FbuK1Vw0f0VAl/s0V95uKnDabbjB7 3.681738698493833*^9, 3.769265085469139*^9, 3.769265278475477*^9, 3.769265312958765*^9, {3.769265407327031*^9, 3.7692654167978067`*^9}, 3.828213904768588*^9, 3.828213970679736*^9, 3.828216334796075*^9, - 3.8282195748144817`*^9, 3.829074726363484*^9, 3.829075129277383*^9}, - CellLabel->"Out[76]=",ExpressionUUID->"f503bf99-aa0f-4faa-90b5-588f929b4b49"] + 3.8282195748144817`*^9, 3.829074726363484*^9, 3.829075129277383*^9, + 3.835447202707675*^9}, + CellLabel->"Out[38]=",ExpressionUUID->"e310f9b8-0a7f-4c02-a543-63a67c823baa"] }, Open ]] }, Open ]] }, Open ]] }, WindowSize->{1172, 1639}, -WindowMargins->{{Automatic, 499}, {Automatic, 0}}, +WindowMargins->{{639, Automatic}, {Automatic, 0}}, WindowStatusArea->None, -FrontEndVersion->"12.0 for Mac OS X x86 (64-bit) (April 8, 2019)", -StyleDefinitions->"Default.nb" +FrontEndVersion->"12.1 for Mac OS X x86 (64-bit) (June 19, 2020)", +StyleDefinitions->"Default.nb", +ExpressionUUID->"56e3dcab-3015-4648-a622-1af0a6f38259" ] (* End of Notebook Content *) @@ -8839,51 +8837,51 @@ CellTagsIndex->{} Notebook[{ Cell[CellGroupData[{ Cell[580, 22, 590, 11, 190, "Subtitle",ExpressionUUID->"6d88bde0-85f5-40c1-906f-e8c139fd8433"], -Cell[1173, 35, 197, 3, 30, "Input",ExpressionUUID->"410c9ead-a5b2-4c59-a953-4ebe80279cd3"], -Cell[1373, 40, 13922, 323, 1627, "Input",ExpressionUUID->"37bf4303-de95-435d-b24b-32a661b82f4c"] +Cell[1173, 35, 196, 3, 30, "Input",ExpressionUUID->"410c9ead-a5b2-4c59-a953-4ebe80279cd3"], +Cell[1372, 40, 13921, 323, 1627, "Input",ExpressionUUID->"37bf4303-de95-435d-b24b-32a661b82f4c"] }, Open ]], Cell[CellGroupData[{ -Cell[15332, 368, 664, 12, 131, "Subtitle",ExpressionUUID->"d2415515-7fdb-4cf3-a9ec-12f84688170e"], -Cell[15999, 382, 1204, 27, 134, "Subtitle",ExpressionUUID->"37397695-a526-4ab0-a6b6-5b35d7bd1ba2"], -Cell[17206, 411, 4199, 103, 199, "Input",ExpressionUUID->"64a40cba-fe9b-420c-bc1f-e2b70d44b247"], +Cell[15330, 368, 664, 12, 131, "Subtitle",ExpressionUUID->"d2415515-7fdb-4cf3-a9ec-12f84688170e"], +Cell[15997, 382, 1204, 27, 134, "Subtitle",ExpressionUUID->"37397695-a526-4ab0-a6b6-5b35d7bd1ba2"], +Cell[17204, 411, 4877, 115, 220, "Input",ExpressionUUID->"64a40cba-fe9b-420c-bc1f-e2b70d44b247"], Cell[CellGroupData[{ -Cell[21430, 518, 3929, 84, 304, "Input",ExpressionUUID->"ed06a09c-d067-4495-8651-30989ac4c29c"], -Cell[25362, 604, 4665, 76, 577, "Output",ExpressionUUID->"a30d7fbc-a755-4233-a527-6fed4a693589"] +Cell[22106, 530, 4127, 87, 304, "Input",ExpressionUUID->"ed06a09c-d067-4495-8651-30989ac4c29c"], +Cell[26236, 619, 4376, 73, 625, "Output",ExpressionUUID->"6b1dd3b9-aead-47ff-a023-bad9bf13c501"] }, Open ]] }, Open ]], Cell[CellGroupData[{ -Cell[30076, 686, 579, 8, 85, "Subtitle",ExpressionUUID->"d4e4cb94-73e2-4e2a-b1a5-b1d3555e58f5"], -Cell[30658, 696, 1095, 24, 111, "Subtitle",ExpressionUUID->"ec63d430-0dac-41fa-a4a6-191808e02e5d"], +Cell[30661, 698, 579, 8, 85, "Subtitle",ExpressionUUID->"d4e4cb94-73e2-4e2a-b1a5-b1d3555e58f5"], +Cell[31243, 708, 1095, 24, 111, "Subtitle",ExpressionUUID->"ec63d430-0dac-41fa-a4a6-191808e02e5d"], Cell[CellGroupData[{ -Cell[31778, 724, 2361, 55, 241, "Input",ExpressionUUID->"572cd540-59b1-4415-8369-fb210674631e"], -Cell[34142, 781, 3329, 58, 549, "Output",ExpressionUUID->"f99f5796-ecdd-42d7-a6b6-f31b1a2b9276"] +Cell[32363, 736, 2578, 58, 241, "Input",ExpressionUUID->"572cd540-59b1-4415-8369-fb210674631e"], +Cell[34944, 796, 3034, 53, 549, "Output",ExpressionUUID->"07c8965f-0e25-48b0-9508-0543006a9e84"] }, Open ]] }, Open ]], Cell[CellGroupData[{ -Cell[37520, 845, 200, 2, 85, "Subtitle",ExpressionUUID->"f52f3550-62ce-4c0a-8b3f-94898be33e6f"], +Cell[38027, 855, 200, 2, 85, "Subtitle",ExpressionUUID->"f52f3550-62ce-4c0a-8b3f-94898be33e6f"], Cell[CellGroupData[{ -Cell[37745, 851, 434, 9, 69, "Subsubsection",ExpressionUUID->"2698dbdd-8e80-456d-8c8a-00d3ce5f78e8"], +Cell[38252, 861, 434, 9, 69, "Subsubsection",ExpressionUUID->"2698dbdd-8e80-456d-8c8a-00d3ce5f78e8"], Cell[CellGroupData[{ -Cell[38204, 864, 3594, 63, 115, "Input",ExpressionUUID->"68982d2b-cd3f-4394-b9b7-bc306b15c89c"], -Cell[41801, 929, 55788, 1059, 394, "Output",ExpressionUUID->"e5fead6a-d2f8-4e08-b029-dde7f7c9c501"], -Cell[97592, 1990, 50514, 975, 373, "Output",ExpressionUUID->"b1d485ba-4af0-4fad-a439-0355ec4bddd0"], -Cell[148109, 2967, 91695, 1652, 371, "Output",ExpressionUUID->"5252c3f2-e36c-4cac-abc5-4cebb92e9767"] +Cell[38711, 874, 3594, 63, 115, "Input",ExpressionUUID->"68982d2b-cd3f-4394-b9b7-bc306b15c89c"], +Cell[42308, 939, 55353, 1057, 394, "Output",ExpressionUUID->"6ef38163-1cbf-4b9b-86ca-ec90ebdeada7"], +Cell[97664, 1998, 50494, 978, 373, "Output",ExpressionUUID->"ff04d788-1bb5-49c3-ab5f-f3b4468aaf5b"], +Cell[148161, 2978, 91254, 1649, 371, "Output",ExpressionUUID->"c85963ab-1c7d-41ff-bc3a-2dd458ecbd3a"] }, Open ]] }, Open ]], Cell[CellGroupData[{ -Cell[239853, 4625, 435, 9, 69, "Subsubsection",ExpressionUUID->"5e5d37fc-2c2d-4b58-a172-ec4edbd83393"], +Cell[239464, 4633, 435, 9, 69, "Subsubsection",ExpressionUUID->"5e5d37fc-2c2d-4b58-a172-ec4edbd83393"], Cell[CellGroupData[{ -Cell[240313, 4638, 3298, 59, 115, "Input",ExpressionUUID->"b2cdebdd-b060-471e-8ddd-416664a1997c"], -Cell[243614, 4699, 68957, 1278, 398, "Output",ExpressionUUID->"24825b91-4503-4163-b50c-82e4e331dc8f"], -Cell[312574, 5979, 61368, 1155, 375, "Output",ExpressionUUID->"01c2383b-3dfd-4f52-844a-4b9ba0d93f61"], -Cell[373945, 7136, 62537, 1175, 371, "Output",ExpressionUUID->"6324d624-4e4a-4526-85dc-1a7a380f86a3"] +Cell[239924, 4646, 3298, 59, 115, "Input",ExpressionUUID->"b2cdebdd-b060-471e-8ddd-416664a1997c"], +Cell[243225, 4707, 68517, 1275, 398, "Output",ExpressionUUID->"5f3a1ac2-1732-4cba-b9ab-1746b32f50c9"], +Cell[311745, 5984, 60914, 1150, 375, "Output",ExpressionUUID->"65440c48-1b97-41ac-b448-e197bec4a3cf"], +Cell[372662, 7136, 62092, 1171, 371, "Output",ExpressionUUID->"45b95cdd-213f-4412-9335-ca0c706aafea"] }, Open ]] }, Open ]], Cell[CellGroupData[{ -Cell[436531, 8317, 489, 9, 69, "Subsubsection",ExpressionUUID->"51e1f0a3-988f-4818-8a5e-654f64dbb13b"], +Cell[434803, 8313, 489, 9, 69, "Subsubsection",ExpressionUUID->"51e1f0a3-988f-4818-8a5e-654f64dbb13b"], Cell[CellGroupData[{ -Cell[437045, 8330, 765, 18, 73, "Input",ExpressionUUID->"adff9626-1268-4d99-9c85-40a974589dd7"], -Cell[437813, 8350, 24731, 467, 396, "Output",ExpressionUUID->"f503bf99-aa0f-4faa-90b5-588f929b4b49"] +Cell[435317, 8326, 765, 18, 73, "Input",ExpressionUUID->"adff9626-1268-4d99-9c85-40a974589dd7"], +Cell[436085, 8346, 24665, 468, 396, "Output",ExpressionUUID->"e310f9b8-0a7f-4c02-a543-63a67c823baa"] }, Open ]] }, Open ]] }, Open ]] diff --git a/filament/CMakeLists.txt b/filament/CMakeLists.txt index ab17f01921..b81fcce56c 100644 --- a/filament/CMakeLists.txt +++ b/filament/CMakeLists.txt @@ -38,6 +38,7 @@ set(PUBLIC_HDRS include/filament/SwapChain.h include/filament/Texture.h include/filament/TextureSampler.h + include/filament/ToneMapper.h include/filament/TransformManager.h include/filament/VertexBuffer.h include/filament/View.h @@ -79,7 +80,7 @@ set(SRCS src/Stream.cpp src/SwapChain.cpp src/Texture.cpp - src/ToneMapping.cpp + src/ToneMapper.cpp src/UniformBuffer.cpp src/VertexBuffer.cpp src/View.cpp @@ -107,7 +108,6 @@ set(PRIVATE_HDRS src/PostProcessManager.h src/RenderPass.h src/ResourceAllocator.h - src/ToneMapping.h src/TypedUniformBuffer.h src/UniformBuffer.h src/components/CameraManager.h diff --git a/filament/include/filament/ColorGrading.h b/filament/include/filament/ColorGrading.h index cf336c16ad..be25267b28 100644 --- a/filament/include/filament/ColorGrading.h +++ b/filament/include/filament/ColorGrading.h @@ -20,6 +20,7 @@ #define TNT_FILAMENT_COLOR_GRADING_H #include +#include #include @@ -90,7 +91,7 @@ class FColorGrading; * - Vibrance: 1.0 * - Saturation: 1.0 * - Curves: gamma {1,1,1}, midPoint {1,1,1}, and scale {1,1,1} - * - Tone mapping: ACES_LEGACY + * - Tone mapping: ACESLegacyToneMapper * - Luminance scaling: false * * @see View @@ -107,15 +108,15 @@ public: /** * List of available tone-mapping operators. + * + * @deprecated Use Builder::toneMapper(ToneMapper*) instead */ - enum class ToneMapping : uint8_t { + enum class UTILS_DEPRECATED ToneMapping : uint8_t { LINEAR = 0, //!< Linear tone mapping (i.e. no tone mapping) 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 - RESERVED = 4, //!< Currently unused - REINHARD = 5, //!< Reinhard luma-based tone mapping - DISPLAY_RANGE = 6, //!< Tone mapping used to validate/debug scene exposure + DISPLAY_RANGE = 4, //!< Tone mapping used to validate/debug scene exposure }; //! Use Builder to construct a ColorGrading object instance @@ -144,6 +145,22 @@ public: */ Builder& quality(QualityLevel qualityLevel) noexcept; + /** + * Selects the tone mapping operator to apply to the HDR color buffer as the last + * operation of the color grading post-processing step. + * + * The default tone mapping operator is ACESLegacyToneMapper. + * + * The specified tone mapper must have a lifecycle that exceeds the lifetime of + * this builder. Since the build(Engine&) method is synchronous, it is safe to + * delete the tone mapper object after that finishes executing. + * + * @param toneMapper The tone mapping operator to apply to the HDR color buffer + * + * @return This Builder, for chaining calls + */ + Builder& toneMapper(const ToneMapper* toneMapper) noexcept; + /** * Selects the tone mapping operator to apply to the HDR color buffer as the last * operation of the color grading post-processing step. @@ -153,7 +170,10 @@ public: * @param toneMapping The tone mapping operator to apply to the HDR color buffer * * @return This Builder, for chaining calls + * + * @deprecated Use toneMapper(ToneMapper*) instead */ + UTILS_DEPRECATED Builder& toneMapping(ToneMapping toneMapping) noexcept; /** diff --git a/filament/include/filament/FilamentAPI.h b/filament/include/filament/FilamentAPI.h index 21ee83e540..8b89a8c352 100644 --- a/filament/include/filament/FilamentAPI.h +++ b/filament/include/filament/FilamentAPI.h @@ -81,7 +81,7 @@ public: } protected: - T* mImpl; + T* mImpl = nullptr; inline T* operator->() noexcept { return mImpl; } inline T const* operator->() const noexcept { return mImpl; } }; diff --git a/filament/include/filament/ToneMapper.h b/filament/include/filament/ToneMapper.h new file mode 100644 index 0000000000..9f36401a49 --- /dev/null +++ b/filament/include/filament/ToneMapper.h @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef TNT_FILAMENT_TONE_MAPPER_H +#define TNT_FILAMENT_TONE_MAPPER_H + +#include + +#include + +namespace filament { + +/** + * Interface for tone mapping operators. A tone mapping operator, or tone mapper, + * is responsible for compressing the dynamic range of the rendered scene to a + * dynamic range suitable for display. + * + * In Filament, tone mapping is a color grading step. ToneMapper instances are + * created and passed to the ColorGrading::Builder to produce a 3D LUT that will + * be used during post-processing to prepare the final color buffer for display. + * + * Filament provides several default tone mapping operators that fall into three + * categories: + * + * - Configurable tone mapping operators + * - GenericToneMapper + * - Fixed-aesthetic tone mapping operators + * - ACESToneMapper + * - ACESLegacyToneMapper + * - FilmicToneMapper + * - Debug/validation tone mapping operators + * - LinearToneMapper + * - DisplayRangeToneMapper + * + * You can create custom tone mapping operators by subclassing ToneMapper. + */ +struct UTILS_PUBLIC ToneMapper { + ToneMapper() noexcept; + virtual ~ToneMapper() noexcept; + + /** + * Maps an open domain (or "scene referred" values) color value to display + * domain (or "display referred") color value. Both the input and output + * color values are defined in the Rec.2020 color space, with no transfer + * function applied ("linear Rec.2020"). + * + * @param c Input color to tone map, in the Rec.2020 color space with no + * transfer function applied ("linear") + * + * @return A tone mapped color in the Rec.2020 color space, with no transfer + * function applied ("linear") + */ + virtual math::float3 operator()(math::float3 c) const noexcept = 0; +}; + +/** + * Linear tone mapping operator that returns the input color but clamped to + * the 0..1 range. This operator is mostly useful for debugging. + */ +struct UTILS_PUBLIC LinearToneMapper final : public ToneMapper { + LinearToneMapper() noexcept; + ~LinearToneMapper() noexcept final; + + math::float3 operator()(math::float3 c) const noexcept; +}; + +/** + * ACES tone mapping operator. This operator is an implementation of the + * ACES Reference Rendering Transform (RRT) combined with the Output Device + * Transform (ODT) for sRGB monitors (dim surround, 100 nits). + */ +struct UTILS_PUBLIC ACESToneMapper final : public ToneMapper { + ACESToneMapper() noexcept; + ~ACESToneMapper() noexcept final; + + math::float3 operator()(math::float3 c) const noexcept; +}; + +/** + * ACES tone mapping operator, modified to match the perceived brightness + * of FilmicToneMapper. This operator is the same as ACESToneMapper but + * applies a brightness multiplier of ~1.6 to the input color value to + * target brighter viewing environments. + */ +struct UTILS_PUBLIC ACESLegacyToneMapper final : public ToneMapper { + ACESLegacyToneMapper() noexcept; + ~ACESLegacyToneMapper() noexcept final; + + math::float3 operator()(math::float3 c) const noexcept; +}; + +/** + * "Filmic" tone mapping operator. This tone mapper was designed to + * approximate the aesthetics of the ACES RRT + ODT for Rec.709 + * and historically Filament's default tone mapping operator. It exists + * only for backward compatibility purposes and is not otherwise recommended. + */ +struct UTILS_PUBLIC FilmicToneMapper final : public ToneMapper { + FilmicToneMapper() noexcept; + ~FilmicToneMapper() noexcept final; + + math::float3 operator()(math::float3 x) const noexcept; +}; + +/** + * Generic tone mapping operator that gives control over the tone mapping + * curve. This operator can be used to control the aesthetics of the final + * image. This operator also allows to control the dynamic range of the + * scene referred values. + * + * The tone mapping curve is defined by 5 parameters: + * - contrast: controls the contrast of the curve + * - shoulder: controls the shoulder of the curve, i.e. how quickly scene + * referred values map to output white + * - midGrayIn: sets the input middle gray + * - midGrayOut: sets the output middle gray + * - hdrMax: defines the maximum input value that will be mapped to + * output white + */ +struct UTILS_PUBLIC GenericToneMapper final : public ToneMapper { + /** + * Builds a new generic tone mapper. The default values of the + * constructor parameters approximate an ACES tone mapping curve + * and the maximum input value is set to 10.0. + * + * @param contrast: controls the contrast of the curve, must be > 0.0, values + * in the range 0.5..2.0 are recommended. + * @param shoulder: controls the shoulder of the curve, i.e. how quickly scene + * referred values map to output white, between 0.0 and 1.0. + * @param midGrayIn: sets the input middle gray, between 0.0 and 1.0. + * @param midGrayOut: sets the output middle gray, between 0.0 and 1.0. + * @param hdrMax: defines the maximum input value that will be mapped to + * output white. Must be >= 1.0. + */ + GenericToneMapper( + float contrast = 1.4f, + float shoulder = 0.5f, + float midGrayIn = 0.18f, + float midGrayOut = 0.266f, + float hdrMax = 10.0f + ) noexcept; + ~GenericToneMapper() noexcept final; + + GenericToneMapper(GenericToneMapper const&) = delete; + GenericToneMapper& operator=(GenericToneMapper const&) = delete; + GenericToneMapper(GenericToneMapper&& rhs) noexcept; + GenericToneMapper& operator=(GenericToneMapper& rhs) noexcept; + + math::float3 operator()(math::float3 x) const noexcept; + + /** Returns the contrast of the curve as a strictly positive value. */ + float getContrast() const noexcept; + + /** Returns how fast scene referred values map to output white as a value between 0.0 and 1.0. */ + float getShoulder() const noexcept; + + /** Returns the middle gray point for input values as a value between 0.0 and 1.0. */ + float getMidGrayIn() const noexcept; + + /** Returns the middle gray point for output values as a value between 0.0 and 1.0. */ + float getMidGrayOut() const noexcept; + + /** Returns the maximum input value that will map to output white, as a value >= 1.0. */ + float getHdrMax() const noexcept; + + /** Sets the contrast of the curve, must be > 0.0, values in the range 0.5..2.0 are recommended. */ + void setContrast(float contrast) noexcept; + + /** Sets how quickly scene referred values map to output white, between 0.0 and 1.0. */ + void setShoulder(float shoulder) noexcept; + + /** Sets the input middle gray, between 0.0 and 1.0. */ + void setMidGrayIn(float midGrayIn) noexcept; + + /** Sets the output middle gray, between 0.0 and 1.0. */ + void setMidGrayOut(float midGrayOut) noexcept; + + /** Defines the maximum input value that will be mapped to output white. Must be >= 1.0. */ + void setHdrMax(float hdrMax) noexcept; + +private: + struct Options; + Options* mOptions; +}; + +/** + * A tone mapper that 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 middle gray (18% exposure). Every exposure stop above or below middle + * gray causes a color shift. + * + * The relationship between exposures and colors is: + * + * - -5EV black + * - -4EV darkest blue + * - -3EV darker blue + * - -2EV dark blue + * - -1EV blue + * - OEV cyan + * - +1EV dark green + * - +2EV green + * - +3EV yellow + * - +4EV yellow-orange + * - +5EV orange + * - +6EV bright red + * - +7EV red + * - +8EV magenta + * - +9EV purple + * - +10EV white + * + * This tone mapper is useful to validate and tweak scene lighting. + */ +struct UTILS_PUBLIC DisplayRangeToneMapper final : public ToneMapper { + DisplayRangeToneMapper() noexcept; + ~DisplayRangeToneMapper() noexcept; + + math::float3 operator()(math::float3 c) const noexcept; +}; + +} // namespace filament + +#endif // TNT_FILAMENT_TONE_MAPPER_H diff --git a/filament/include/filament/View.h b/filament/include/filament/View.h index 08f81a383a..0da29221ff 100644 --- a/filament/include/filament/View.h +++ b/filament/include/filament/View.h @@ -873,17 +873,6 @@ public: //! debugging: returns a Camera from the point of view of *the* dominant directional light used for shadowing. Camera const* getDirectionalLightCamera() const noexcept; - - /** - * List of available tone-mapping operators - * - * @deprecated See ColorGrading - */ - enum class UTILS_DEPRECATED ToneMapping : uint8_t { - LINEAR = 0, //!< Linear tone mapping (i.e. no tone mapping) - ACES = 1, //!< ACES tone mapping - }; - /** * List of available ambient occlusion techniques * @deprecated use AmbientOcclusionOptions::enabled instead @@ -893,27 +882,6 @@ public: SSAO = 1 //!< Basic, sampling SSAO }; - /** - * Enables or disables tone-mapping in the post-processing stage. Enabled by default. - * - * @param type Tone-mapping function. - * - * @deprecated Use setColorGrading instead - * @see setColorGrading - */ - UTILS_DEPRECATED - void setToneMapping(ToneMapping type) noexcept; - - /** - * Returns the tone-mapping function. - * @return tone-mapping function. - * - * @deprecated Use getColorGrading instead - * @see getColorGrading - */ - UTILS_DEPRECATED - ToneMapping getToneMapping() const noexcept; - /** * Activates or deactivates ambient occlusion. * @deprecated use setAmbientOcclusionOptions() instead diff --git a/filament/src/ColorGrading.cpp b/filament/src/ColorGrading.cpp index b6dcb9b3a6..46dd1bc69a 100644 --- a/filament/src/ColorGrading.cpp +++ b/filament/src/ColorGrading.cpp @@ -23,8 +23,6 @@ #include "ColorSpace.h" -#include "ToneMapping.h" - #include #include #include @@ -33,8 +31,6 @@ #include #include -#include - #include #include @@ -49,9 +45,17 @@ using namespace backend; //------------------------------------------------------------------------------ struct ColorGrading::BuilderDetails { - ColorGrading::QualityLevel quality = QualityLevel::MEDIUM; + const ToneMapper* toneMapper = nullptr; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" ToneMapping toneMapping = ToneMapping::ACES_LEGACY; +#pragma clang diagnostic pop + + bool hasAdjustments = false; + + // Everything below must be part of the == comparison operator + ColorGrading::QualityLevel quality = QualityLevel::MEDIUM; // Luminance scaling bool luminanceScaling = false; // Exposure @@ -79,17 +83,14 @@ struct ColorGrading::BuilderDetails { float3 shadowGamma = {1.0f}; float3 midPoint = {1.0f}; float3 highlightScale = {1.0f}; - // Keep last - bool hasAdjustments = false; bool operator!=(const BuilderDetails &rhs) const { return !(rhs == *this); } bool operator==(const BuilderDetails &rhs) const { - // Note: Do NOT compare hasAdjustments + // Note: Do NOT compare hasAdjustments and toneMapper return quality == rhs.quality && - toneMapping == rhs.toneMapping && luminanceScaling == rhs.luminanceScaling && exposure == rhs.exposure && whiteBalance == rhs.whiteBalance && @@ -125,6 +126,11 @@ ColorGrading::Builder& ColorGrading::Builder::quality(ColorGrading::QualityLevel return *this; } +ColorGrading::Builder& ColorGrading::Builder::toneMapper(const ToneMapper* toneMapper) noexcept { + mImpl->toneMapper = toneMapper; + return *this; +} + ColorGrading::Builder& ColorGrading::Builder::toneMapping(ToneMapping toneMapping) noexcept { mImpl->toneMapping = toneMapping; return *this; @@ -202,16 +208,47 @@ ColorGrading::Builder& ColorGrading::Builder::curves( return *this; } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" ColorGrading* ColorGrading::Builder::build(Engine& engine) { // We want to see if any of the default adjustment values have been modified // We skip the tonemapping operator on purpose since we always want to apply it BuilderDetails defaults; - defaults.toneMapping = mImpl->toneMapping; bool hasAdjustments = defaults != *mImpl; mImpl->hasAdjustments = hasAdjustments; - return upcast(engine).createColorGrading(*this); + // Fallback for clients that still use the deprecated ToneMapping API + bool needToneMapper = mImpl->toneMapper == nullptr; + if (needToneMapper) { + switch (mImpl->toneMapping) { + case ToneMapping::LINEAR: + mImpl->toneMapper = new LinearToneMapper(); + break; + case ToneMapping::ACES_LEGACY: + mImpl->toneMapper = new ACESLegacyToneMapper(); + break; + case ToneMapping::ACES: + mImpl->toneMapper = new ACESToneMapper(); + break; + case ToneMapping::FILMIC: + mImpl->toneMapper = new FilmicToneMapper(); + break; + case ToneMapping::DISPLAY_RANGE: + mImpl->toneMapper = new DisplayRangeToneMapper(); + break; + } + } + + FColorGrading* colorGrading = upcast(engine).createColorGrading(*this); + + if (needToneMapper) { + delete mImpl->toneMapper; + mImpl->toneMapper = nullptr; + } + + return colorGrading; } +#pragma clang diagnostic pop //------------------------------------------------------------------------------ // White balance @@ -255,74 +292,6 @@ inline float3 chromaticAdaptation(float3 v, float3 adaptationTransform) { using ColorTransform = float3(*)(float3); -ColorTransform selectLinearToLogTransform(ColorGrading::ToneMapping toneMapping) { - switch (toneMapping) { - case ColorGrading::ToneMapping::ACES_LEGACY: - case ColorGrading::ToneMapping::ACES: - return linearAP1_to_ACEScct; - default: - return linear_to_LogC; - } -} - -ColorTransform selectLogToLinearTransform(ColorGrading::ToneMapping toneMapping) { - switch (toneMapping) { - case ColorGrading::ToneMapping::ACES_LEGACY: - case ColorGrading::ToneMapping::ACES: - return ACEScct_to_linearAP1; - default: - return LogC_to_linear; - } -} - -mat3f selectColorGradingTransformIn(ColorGrading::ToneMapping toneMapping) { - switch (toneMapping) { - case ColorGrading::ToneMapping::ACES_LEGACY: - case ColorGrading::ToneMapping::ACES: - return sRGB_to_AP1; - case ColorGrading::ToneMapping::FILMIC: - case ColorGrading::ToneMapping::RESERVED: - case ColorGrading::ToneMapping::DISPLAY_RANGE: - return mat3f{}; // stay in sRGB - default: - return sRGB_to_REC2020; - } -} - -mat3f selectColorGradingTransformOut(ColorGrading::ToneMapping toneMapping) { - switch (toneMapping) { - case ColorGrading::ToneMapping::ACES_LEGACY: - case ColorGrading::ToneMapping::ACES: - return AP1_to_sRGB; - case ColorGrading::ToneMapping::FILMIC: - case ColorGrading::ToneMapping::RESERVED: - case ColorGrading::ToneMapping::DISPLAY_RANGE: - return mat3f{}; // stay in sRGB - default: - return REC2020_to_sRGB; - } -} - -float3 selectLuminanceTransform(ColorGrading::ToneMapping toneMapping) { - switch (toneMapping) { - case ColorGrading::ToneMapping::ACES_LEGACY: - case ColorGrading::ToneMapping::ACES: - return LUMA_AP1; - default: - return LUMA_REC709; - } -} - -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)}; @@ -403,8 +372,8 @@ inline float3 curves(float3 v, float3 shadowGamma, float3 midPoint, float3 highl // Luminance scaling //------------------------------------------------------------------------------ -static float3 luminanceScaling( - float3 x, ColorTransform toneMapper, float3 luminanceWeights) noexcept { +static float3 luminanceScaling(float3 x, + const ToneMapper& toneMapper, float3 luminanceWeights) noexcept { // Troy Sobotka, 2021, "EVILS - Exposure Value Invariant Luminance Scaling" // https://colab.research.google.com/drive/1iPJzNNKR7PynFmsqSnQm3bCZmQ3CvAJ-#scrollTo=psU43hb-BLzB @@ -473,42 +442,11 @@ void selectLutTextureParams(ColorGrading::QualityLevel quality, } } - -//------------------------------------------------------------------------------ -// Tone mapping -//------------------------------------------------------------------------------ - -ColorTransform selectToneMapping(ColorGrading::ToneMapping toneMapping) { - switch (toneMapping) { - case ColorGrading::ToneMapping::LINEAR: - return tonemap::Linear; - case ColorGrading::ToneMapping::ACES_LEGACY: - return tonemap::ACES_Legacy; - case ColorGrading::ToneMapping::ACES: - return tonemap::ACES; - case ColorGrading::ToneMapping::FILMIC: - return tonemap::Filmic; - case ColorGrading::ToneMapping::RESERVED: - return tonemap::Linear; - case ColorGrading::ToneMapping::REINHARD: - return tonemap::Reinhard; - case ColorGrading::ToneMapping::DISPLAY_RANGE: - return tonemap::DisplayRange; - } -} - //------------------------------------------------------------------------------ // Color grading implementation //------------------------------------------------------------------------------ struct Config { - mat3f colorGradingTransformIn; - mat3f colorGradingTransformOut; - float3 luminanceTransform; - float3 luminanceScalingTransform; - ColorTransform linearToLogTransform; - ColorTransform logToLinearTransform; - ColorTransform toneMapper; size_t lutDimension; float3 adaptationTransform; }; @@ -528,15 +466,8 @@ 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.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); + c.lutDimension = selectLutDimension(builder->quality); + c.adaptationTransform = adaptationTransform(builder->whiteBalance); } size_t lutElementCount = c.lutDimension * c.lutDimension * c.lutDimension; @@ -587,7 +518,7 @@ FColorGrading::FColorGrading(FEngine& engine, const Builder& builder) { } // Convert to color grading color space - v = config.colorGradingTransformIn * v; + v = sRGB_to_REC2020 * v; if (builder->hasAdjustments) { // Kill negative values before the next transforms @@ -597,13 +528,13 @@ FColorGrading::FColorGrading(FEngine& engine, const Builder& builder) { v = channelMixer(v, builder->outRed, builder->outGreen, builder->outBlue); // Shadows/mid-tones/highlights - v = tonalRanges(v, config.luminanceTransform, + v = tonalRanges(v, LUMA_REC2020, builder->shadows, builder->midtones, builder->highlights, builder->tonalRanges); // The adjustments below behave better in log space using the ACEScct // color space. - v = config.linearToLogTransform(v); + v = linear_to_LogC(v); // ASC CDL v = colorDecisionList(v, builder->slope, builder->offset, builder->power); @@ -612,13 +543,13 @@ FColorGrading::FColorGrading(FEngine& engine, const Builder& builder) { v = contrast(v, builder->contrast); // Back to linear space - v = config.logToLinearTransform(v); + v = LogC_to_linear(v); // Vibrance in linear space - v = vibrance(v, config.luminanceTransform, builder->vibrance); + v = vibrance(v, LUMA_REC2020, builder->vibrance); // Saturation in linear space - v = saturation(v, config.luminanceTransform, builder->saturation); + v = saturation(v, LUMA_REC2020, builder->saturation); // Kill negative values before tone mapping v = max(v, 0.0f); @@ -630,14 +561,14 @@ FColorGrading::FColorGrading(FEngine& engine, const Builder& builder) { // Tone mapping if (builder->luminanceScaling) { - v = luminanceScaling(v, config.toneMapper, config.luminanceScalingTransform); + v = luminanceScaling(v, *builder->toneMapper, LUMA_HK_REC709); } else { - v = config.toneMapper(v); + v = (*builder->toneMapper)(v); } // Convert to output color space // TODO: allow to customize the output color space, - v = config.colorGradingTransformOut * v; + v = REC2020_to_sRGB * v; v = saturate(v); diff --git a/filament/src/ColorSpace.h b/filament/src/ColorSpace.h index d0a54f39a7..4dfb73f3fe 100644 --- a/filament/src/ColorSpace.h +++ b/filament/src/ColorSpace.h @@ -120,6 +120,10 @@ constexpr mat3f sRGB_to_LMS = XYZ_to_CIECAT02 * sRGB_to_XYZ; constexpr mat3f LMS_to_sRGB = XYZ_to_sRGB * CIECAT02_to_XYZ; +constexpr mat3f REC2020_to_AP0 = AP1_to_AP0 * XYZ_to_AP1 * REC2020_to_XYZ; + +constexpr mat3f AP1_to_REC2020 = XYZ_to_REC2020 * AP1_to_XYZ; + //------------------------------------------------------------------------------ // Constants //------------------------------------------------------------------------------ @@ -131,6 +135,9 @@ constexpr float3 ILLUMINANT_D65_xyY{0.31271f, 0.32902f, 1.0f}; // Result of: XYZ_to_CIECAT02 * xyY_to_XYZ(ILLUMINANT_D65_xyY); constexpr float3 ILLUMINANT_D65_LMS{0.949237f, 1.03542f, 1.08728f}; +// RGB to luminance coefficients for Rec.2020, from REC2020_to_XYZ +constexpr float3 LUMA_REC2020{0.2627002f, 0.6779981f, 0.0593017f}; + // RGB to luminance coefficients for ACEScg (AP1), from AP1_to_XYZ constexpr float3 LUMA_AP1{0.272229f, 0.674082f, 0.0536895f}; diff --git a/filament/src/ToneMapping.cpp b/filament/src/ToneMapper.cpp similarity index 52% rename from filament/src/ToneMapping.cpp rename to filament/src/ToneMapper.cpp index 74b51aa220..0063bb7ac6 100644 --- a/filament/src/ToneMapping.cpp +++ b/filament/src/ToneMapper.cpp @@ -14,11 +14,17 @@ * limitations under the License. */ -#include "ToneMapping.h" +#include -using namespace filament::math; +#include "ColorSpace.h" + +#include +#include namespace filament { + +using namespace math; + namespace aces { inline float rgb_2_saturation(float3 rgb) { @@ -114,8 +120,6 @@ inline float3 darkSurround_to_dimSurround(float3 linearCV) { float3 ACES(float3 color, float brightness) noexcept { // Some bits were removed to adapt to our desired output - // Input: ACEScg (AP1) - // Output: ACEScg (AP1) // "Glow" module constants constexpr float RRT_GLOW_GAIN = 0.05f; @@ -131,7 +135,7 @@ float3 ACES(float3 color, float brightness) noexcept { constexpr float RRT_SAT_FACTOR = 0.96f; constexpr float ODT_SAT_FACTOR = 0.93f; - float3 ap0 = AP1_to_AP0 * color; + float3 ap0 = REC2020_to_AP0 * color; // Glow module float saturation = rgb_2_saturation(ap0); @@ -173,57 +177,67 @@ float3 ACES(float3 color, float brightness) noexcept { // Apply desaturation to compensate for luminance difference linearCV = mix(float3(dot(linearCV, LUMA_AP1)), linearCV, ODT_SAT_FACTOR); - return linearCV; + return AP1_to_REC2020 * linearCV; } } // namespace aces -namespace tonemap { +//------------------------------------------------------------------------------ +// Tone mappers +//------------------------------------------------------------------------------ -float3 ACES(float3 x) noexcept { - return aces::ACES(x, 1.0f); +#define DEFAULT_CONSTRUCTORS(A) \ + A::A() noexcept = default; \ + A::~A() noexcept = default; + +DEFAULT_CONSTRUCTORS(ToneMapper) + +//------------------------------------------------------------------------------ +// Linear tone mapper +//------------------------------------------------------------------------------ + +DEFAULT_CONSTRUCTORS(LinearToneMapper) + +float3 LinearToneMapper::operator()(float3 v) const noexcept { + return saturate(v); } -float3 ACES_Legacy(float3 x) noexcept { - return aces::ACES(x, 1.0f / 0.6f); +//------------------------------------------------------------------------------ +// ACES tone mappers +//------------------------------------------------------------------------------ + +DEFAULT_CONSTRUCTORS(ACESToneMapper) + +float3 ACESToneMapper::operator()(math::float3 c) const noexcept { + return aces::ACES(c, 1.0f); } -// 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); - float mcs = std::pow(mc, shoulder); +DEFAULT_CONSTRUCTORS(ACESLegacyToneMapper) - float hc = std::pow(hdrMax, contrast); - float hcs = std::pow(hc, shoulder); - - float b1 = -mc + hc * midGreyOut; - float b2 = (hcs - mcs) * midGreyOut; - float b = b1 / b2; - - float c1 = hcs * mc - hc * mcs * midGreyOut; - float c2 = (hcs - mcs) * midGreyOut; - float c = c1 / c2; - - float xc = std::pow(x, contrast); - return saturate(xc / (std::pow(xc, shoulder) * b + c)); +float3 ACESLegacyToneMapper::operator()(math::float3 c) const noexcept { + return aces::ACES(c, 1.0f / 0.6f); } -float3 DisplayRange(float3 x) noexcept { +DEFAULT_CONSTRUCTORS(FilmicToneMapper) + +float3 FilmicToneMapper::operator()(math::float3 x) const noexcept { + // Narkowicz 2015, "ACES Filmic Tone Mapping Curve" + constexpr float a = 2.51f; + constexpr float b = 0.03f; + constexpr float c = 2.43f; + constexpr float d = 0.59f; + constexpr float e = 0.14f; + return (x * (a * x + b)) / (x * (c * x + d) + e); +} + +//------------------------------------------------------------------------------ +// Display range tone mapper +//------------------------------------------------------------------------------ + +DEFAULT_CONSTRUCTORS(DisplayRangeToneMapper) + +float3 DisplayRangeToneMapper::operator()(math::float3 c) const noexcept { // 16 debug colors + 1 duplicated at the end for easy indexing - constexpr float3 debugColors[17] = { {0.0, 0.0, 0.0}, // black {0.0, 0.0, 0.1647}, // darkest blue @@ -246,12 +260,159 @@ float3 DisplayRange(float3 x) noexcept { // The 5th color in the array (cyan) represents middle gray (18%) // Every stop above or below middle gray causes a color shift - float v = log2(dot(x, LUMA_REC709) / 0.18f); + float v = log2(dot(c, LUMA_REC709) / 0.18f); v = clamp(v + 5.0f, 0.0f, 15.0f); size_t index = size_t(v); return mix(debugColors[index], debugColors[index + 1], saturate(v - float(index))); } -} // namespace tonemap +//------------------------------------------------------------------------------ +// Generic tone mapper +//------------------------------------------------------------------------------ + +// Lottes, 2016,"Advanced Techniques and Optimization of VDR Color Pipelines": +// https://gpuopen.com/wp-content/uploads/2016/03/GdcVdrLottes.pdf +// Includes fix from Bart Wronski: +// https://bartwronski.com/2016/09/01/dynamic-range-and-evs/ + +struct GenericToneMapper::Options { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wshadow" + void setParameters( + float contrast, + float shoulder, + float midGrayIn, + float midGrayOut, + float hdrMax + ) { + contrast = max(contrast, 1e-5f); + shoulder = saturate(shoulder); + midGrayIn = clamp(midGrayIn, 1e-5f, 1.0f); + midGrayOut = clamp(midGrayOut, 1e-5f, 1.0f); + hdrMax = max(hdrMax, 1.0f); + + this->contrast = contrast; + this->shoulder = shoulder; + this->midGrayIn = midGrayIn; + this->midGrayOut = midGrayOut; + this->hdrMax = hdrMax; + + // remap shoulder + d = 0.8f + 0.4f * shoulder; + + float mc = std::pow(midGrayIn, contrast); + float mcs = std::pow(mc, d); + + float hc = std::pow(hdrMax, contrast); + float hcs = std::pow(hc, d); + + float u = (hcs - mcs) * midGrayOut; + float v = mcs * midGrayOut; + + b = -((-mc + (midGrayOut * (hcs * mc - hc * v)) / u) / v); + c = (hcs * mc - hc * v) / u; + } +#pragma clang diagnostic pop + + float contrast; + float shoulder; + float midGrayIn; + float midGrayOut; + float hdrMax; + + // Computed fields, do not modify + float b; + float c; + float d; +}; + +GenericToneMapper::GenericToneMapper( + float contrast, + float shoulder, + float midGrayIn, + float midGrayOut, + float hdrMax +) noexcept { + mOptions = new Options(); + mOptions->setParameters(contrast, shoulder, midGrayIn, midGrayOut, hdrMax); +} + +GenericToneMapper::~GenericToneMapper() noexcept { + delete mOptions; +} + +GenericToneMapper::GenericToneMapper(GenericToneMapper&& rhs) noexcept : mOptions(rhs.mOptions) { + rhs.mOptions = nullptr; +} + +GenericToneMapper& GenericToneMapper::operator=(GenericToneMapper& rhs) noexcept { + mOptions = rhs.mOptions; + rhs.mOptions = nullptr; + return *this; +} + +float3 GenericToneMapper::operator()(math::float3 x) const noexcept { + float3 xc = pow(clamp(x, 0.0f, mOptions->hdrMax), mOptions->contrast); + return saturate(xc / (pow(xc, mOptions->d) * mOptions->b + mOptions->c)); +} + +float GenericToneMapper::getContrast() const noexcept { return mOptions->contrast; } +float GenericToneMapper::getShoulder() const noexcept { return mOptions->shoulder; } +float GenericToneMapper::getMidGrayIn() const noexcept { return mOptions->midGrayIn; } +float GenericToneMapper::getMidGrayOut() const noexcept { return mOptions->midGrayOut; } +float GenericToneMapper::getHdrMax() const noexcept { return mOptions->hdrMax; } + +void GenericToneMapper::setContrast(float contrast) noexcept { + mOptions->setParameters( + contrast, + mOptions->shoulder, + mOptions->midGrayIn, + mOptions->midGrayOut, + mOptions->hdrMax + ); +} + +void GenericToneMapper::setShoulder(float shoulder) noexcept { + mOptions->setParameters( + mOptions->contrast, + shoulder, + mOptions->midGrayIn, + mOptions->midGrayOut, + mOptions->hdrMax + ); +} + +void GenericToneMapper::setMidGrayIn(float midGrayIn) noexcept { + mOptions->setParameters( + mOptions->contrast, + mOptions->shoulder, + midGrayIn, + mOptions->midGrayOut, + mOptions->hdrMax + ); +} + +void GenericToneMapper::setMidGrayOut(float midGrayOut) noexcept { + mOptions->setParameters( + mOptions->contrast, + mOptions->shoulder, + mOptions->midGrayIn, + midGrayOut, + mOptions->hdrMax + ); +} + +void GenericToneMapper::setHdrMax(float hdrMax) noexcept { + mOptions->setParameters( + mOptions->contrast, + mOptions->shoulder, + mOptions->midGrayIn, + mOptions->midGrayOut, + hdrMax + ); +} + +#undef DEFAULT_CONSTRUCTORS + } // namespace filament diff --git a/filament/src/ToneMapping.h b/filament/src/ToneMapping.h deleted file mode 100644 index 6502f81610..0000000000 --- a/filament/src/ToneMapping.h +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2020 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef TNT_FILAMENT_TONE_MAPPING_H -#define TNT_FILAMENT_TONE_MAPPING_H - -#include "ColorSpace.h" - -#include - -#include -#include -#include - -namespace filament { - -using namespace math; - -//------------------------------------------------------------------------------ -// ACES operations, from https://github.com/ampas/aces-dev -//------------------------------------------------------------------------------ - -namespace aces { - -float3 ACES(float3 color, float brightness) noexcept; - -} // namespace aces - -//------------------------------------------------------------------------------ -// Tone mapping operators -//------------------------------------------------------------------------------ - -namespace tonemap { - -constexpr float3 Linear(float3 x) noexcept { - return x; -} - -constexpr float3 Reinhard(float3 x) noexcept { - return x / (1.0f + dot(x, LUMA_REC709)); -} - -constexpr float3 Filmic(float3 x) noexcept { - // Narkowicz 2015, "ACES Filmic Tone Mapping Curve" - constexpr float a = 2.51f; - constexpr float b = 0.03f; - constexpr float c = 2.43f; - constexpr float d = 0.59f; - constexpr float e = 0.14f; - return (x * (a * x + b)) / (x * (c * x + d) + e); -} - -float3 ACES(float3 x) noexcept; - -float3 ACES_Legacy(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 - * middle gray (18% exposure). Every exposure stop above or below middle gray - * causes a color shift. - * - * The relationship between exposures and colors is: - * - * -5EV - black - * -4EV - darkest blue - * -3EV - darker blue - * -2EV - dark blue - * -1EV - blue - * OEV - cyan - * +1EV - dark green - * +2EV - green - * +3EV - yellow - * +4EV - yellow-orange - * +5EV - orange - * +6EV - bright red - * +7EV - red - * +8EV - magenta - * +9EV - purple - * +10EV - white - */ -float3 DisplayRange(float3 x) noexcept; - -} // namespace tonemap - -} // namespace filament - -#endif //TNT_FILAMENT_TONE_MAPPING_H diff --git a/filament/src/View.cpp b/filament/src/View.cpp index 96fcaa0d49..617924f70f 100644 --- a/filament/src/View.cpp +++ b/filament/src/View.cpp @@ -1038,14 +1038,6 @@ const View::TemporalAntiAliasingOptions& View::getTemporalAntiAliasingOptions() return upcast(this)->getTemporalAntiAliasingOptions(); } -void View::setToneMapping(ToneMapping type) noexcept { - upcast(this)->setToneMapping(type); -} - -View::ToneMapping View::getToneMapping() const noexcept { - return upcast(this)->getToneMapping(); -} - void View::setColorGrading(ColorGrading* colorGrading) noexcept { return upcast(this)->setColorGrading(upcast(colorGrading)); } diff --git a/filament/src/details/View.h b/filament/src/details/View.h index b50cb95505..aae6bc22f6 100644 --- a/filament/src/details/View.h +++ b/filament/src/details/View.h @@ -52,7 +52,7 @@ namespace utils { class JobSystem; } // namespace utils; -// Avoid warnings for using the ToneMapping API, which has been publicly deprecated. +// Avoid warnings for using the deprecated APIs. #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" @@ -235,14 +235,6 @@ public: return mTemporalAntiAliasingOptions; } - void setToneMapping(ToneMapping type) noexcept { - mToneMapping = type; - } - - ToneMapping getToneMapping() const noexcept { - return mToneMapping; - } - void setColorGrading(FColorGrading* colorGrading) noexcept { mColorGrading = colorGrading == nullptr ? mDefaultColorGrading : colorGrading; } @@ -496,7 +488,6 @@ private: uint8_t mVisibleLayers = 0x1; uint8_t mSampleCount = 1; AntiAliasing mAntiAliasing = AntiAliasing::FXAA; - ToneMapping mToneMapping = ToneMapping::ACES; Dithering mDithering = Dithering::TEMPORAL; bool mShadowingEnabled = true; bool mScreenSpaceRefractionEnabled = true; diff --git a/libs/viewer/include/viewer/Settings.h b/libs/viewer/include/viewer/Settings.h index 65f1b9d9b3..42e6349056 100644 --- a/libs/viewer/include/viewer/Settings.h +++ b/libs/viewer/include/viewer/Settings.h @@ -49,6 +49,15 @@ struct ViewSettings; struct LightSettings; struct ViewerOptions; +enum class ToneMapping : uint8_t { + LINEAR = 0, + ACES_LEGACY = 1, + ACES = 2, + FILMIC = 3, + GENERIC = 4, + DISPLAY_RANGE = 5, +}; + using AmbientOcclusionOptions = filament::View::AmbientOcclusionOptions; using AntiAliasing = filament::View::AntiAliasing; using BloomOptions = filament::View::BloomOptions; @@ -58,7 +67,6 @@ using FogOptions = filament::View::FogOptions; using RenderQuality = filament::View::RenderQuality; using ShadowType = filament::View::ShadowType; using TemporalAntiAliasingOptions = filament::View::TemporalAntiAliasingOptions; -using ToneMapping = filament::ColorGrading::ToneMapping; using VignetteOptions = filament::View::VignetteOptions; using VsmShadowOptions = filament::View::VsmShadowOptions; using LightManager = filament::LightManager; @@ -94,10 +102,21 @@ private: Context* context; }; +struct GenericToneMapperSettings { + float contrast = 1.4f; + float shoulder = 0.5f; + float midGrayIn = 0.18f; + float midGrayOut = 0.266f; + float hdrMax = 10.0f; + bool operator!=(const GenericToneMapperSettings &rhs) const { return !(rhs == *this); } + bool operator==(const GenericToneMapperSettings &rhs) const; +}; + struct ColorGradingSettings { bool enabled = true; filament::ColorGrading::QualityLevel quality = filament::ColorGrading::QualityLevel::MEDIUM; ToneMapping toneMapping = ToneMapping::ACES_LEGACY; + GenericToneMapperSettings genericToneMapper; bool luminanceScaling = false; float exposure = 0.0f; float temperature = 0.0f; diff --git a/libs/viewer/include/viewer/SimpleViewer.h b/libs/viewer/include/viewer/SimpleViewer.h index 8e1b7e5ed5..45703a7010 100644 --- a/libs/viewer/include/viewer/SimpleViewer.h +++ b/libs/viewer/include/viewer/SimpleViewer.h @@ -243,6 +243,7 @@ private: int mCurrentCamera = 0; // Color grading UI state. + float mToneMapPlot[1024]; float mRangePlot[1024 * 3]; float mCurvePlot[1024 * 3]; }; diff --git a/libs/viewer/src/Settings.cpp b/libs/viewer/src/Settings.cpp index ab80c1bf29..10ac4d255b 100644 --- a/libs/viewer/src/Settings.cpp +++ b/libs/viewer/src/Settings.cpp @@ -186,8 +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, "RESERVED")) { *out = ToneMapping::RESERVED; } - else if (0 == compare(tokens[i], jsonChunk, "REINHARD")) { *out = ToneMapping::REINHARD; } + else if (0 == compare(tokens[i], jsonChunk, "GENERIC")) { *out = ToneMapping::GENERIC; } else if (0 == compare(tokens[i], jsonChunk, "DISPLAY_RANGE")) { *out = ToneMapping::DISPLAY_RANGE; } else { slog.w << "Invalid ToneMapping: '" << STR(tokens[i], jsonChunk) << "'" << io::endl; @@ -267,6 +266,34 @@ static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, return i; } +static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, GenericToneMapperSettings* out) { + CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); + int size = tokens[i++].size; + for (int j = 0; j < size; ++j) { + const jsmntok_t tok = tokens[i]; + CHECK_KEY(tok); + if (compare(tok, jsonChunk, "contrast") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->contrast); + } else if (compare(tok, jsonChunk, "shoulder") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->shoulder); + } else if (compare(tok, jsonChunk, "midGrayIn") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->midGrayIn); + } else if (compare(tok, jsonChunk, "midGrayOut") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->midGrayOut); + } else if (compare(tok, jsonChunk, "hdrMax") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->hdrMax); + } else { + slog.w << "Invalid generic tone mapper key: '" << STR(tok, jsonChunk) << "'" << io::endl; + i = parse(tokens, i + 1); + } + if (i < 0) { + slog.e << "Invalid generic tone mapper value: '" << STR(tok, jsonChunk) << "'" << io::endl; + return i; + } + } + return i; +} + static int parse(jsmntok_t const* tokens, int i, const char* jsonChunk, ColorGradingSettings* out) { CHECK_TOKTYPE(tokens[i], JSMN_OBJECT); int size = tokens[i++].size; @@ -279,6 +306,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, "genericToneMapper") == 0) { + i = parse(tokens, i + 1, jsonChunk, &out->genericToneMapper); } else if (compare(tok, jsonChunk, "luminanceScaling") == 0) { i = parse(tokens, i + 1, jsonChunk, &out->luminanceScaling); } else if (compare(tok, jsonChunk, "exposure") == 0) { @@ -929,7 +958,7 @@ void applySettings(const LightSettings& settings, IndirectLight* ibl, utils::Ent ibl->setRotation(math::mat3f::rotation(settings.iblRotation, math::float3 { 0, 1, 0 })); } for (size_t i = 0; i < sceneLightCount; i++) { - auto light = lm->getInstance(sceneLights[i]); + light = lm->getInstance(sceneLights[i]); if (lm->isSpotLight(light)) { lm->setShadowCaster(light, settings.enableShadows); } @@ -964,26 +993,46 @@ void applySettings(const ViewerOptions& settings, Camera* camera, Skybox* skybox } } +constexpr ToneMapper* createToneMapper(const ColorGradingSettings& settings) noexcept { + switch (settings.toneMapping) { + case ToneMapping::LINEAR: return new LinearToneMapper; + case ToneMapping::ACES_LEGACY: return new ACESLegacyToneMapper; + case ToneMapping::ACES: return new ACESToneMapper; + case ToneMapping::FILMIC: return new FilmicToneMapper; + case ToneMapping::GENERIC: return new GenericToneMapper( + settings.genericToneMapper.contrast, + settings.genericToneMapper.shoulder, + settings.genericToneMapper.midGrayIn, + settings.genericToneMapper.midGrayOut, + settings.genericToneMapper.hdrMax + ); + case ToneMapping::DISPLAY_RANGE: return new DisplayRangeToneMapper; + } +} + ColorGrading* createColorGrading(const ColorGradingSettings& settings, Engine* engine) { - return ColorGrading::Builder() - .quality(settings.quality) - .exposure(settings.exposure) - .whiteBalance(settings.temperature, settings.tint) - .channelMixer(settings.outRed, settings.outGreen, settings.outBlue) - .shadowsMidtonesHighlights( - Color::toLinear(settings.shadows), - Color::toLinear(settings.midtones), - Color::toLinear(settings.highlights), - settings.ranges - ) - .slopeOffsetPower(settings.slope, settings.offset, settings.power) - .contrast(settings.contrast) - .vibrance(settings.vibrance) - .saturation(settings.saturation) - .curves(settings.gamma, settings.midPoint, settings.scale) - .toneMapping(settings.toneMapping) - .luminanceScaling(settings.luminanceScaling) - .build(*engine); + ToneMapper* toneMapper = createToneMapper(settings); + ColorGrading *colorGrading = ColorGrading::Builder() + .quality(settings.quality) + .exposure(settings.exposure) + .whiteBalance(settings.temperature, settings.tint) + .channelMixer(settings.outRed, settings.outGreen, settings.outBlue) + .shadowsMidtonesHighlights( + Color::toLinear(settings.shadows), + Color::toLinear(settings.midtones), + Color::toLinear(settings.highlights), + settings.ranges + ) + .slopeOffsetPower(settings.slope, settings.offset, settings.power) + .contrast(settings.contrast) + .vibrance(settings.vibrance) + .saturation(settings.saturation) + .curves(settings.gamma, settings.midPoint, settings.scale) + .toneMapper(toneMapper) + .luminanceScaling(settings.luminanceScaling) + .build(*engine); + delete toneMapper; + return colorGrading; } static std::ostream& operator<<(std::ostream& out, AntiAliasing in) { @@ -1052,8 +1101,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::RESERVED: return out << "\"RESERVED\""; - case ToneMapping::REINHARD: return out << "\"REINHARD\""; + case ToneMapping::GENERIC: return out << "\"GENERIC\""; case ToneMapping::DISPLAY_RANGE: return out << "\"DISPLAY_RANGE\""; } return out << "\"INVALID\""; @@ -1087,11 +1135,22 @@ static std::ostream& operator<<(std::ostream& out, const TemporalAntiAliasingOpt << "}"; } +static std::ostream& operator<<(std::ostream& out, const GenericToneMapperSettings& in) { + return out << "{\n" + << "\"contrast\": " << (in.contrast) << ",\n" + << "\"shoulder\": " << (in.shoulder) << ",\n" + << "\"midGrayIn\": " << (in.midGrayIn) << ",\n" + << "\"midGrayOut\": " << (in.midGrayOut) << ",\n" + << "\"hdrMax\": " << (in.hdrMax) << "\n" + << "}"; +} + static std::ostream& operator<<(std::ostream& out, const ColorGradingSettings& in) { return out << "{\n" << "\"enabled\": " << to_string(in.enabled) << ",\n" << "\"quality\": " << (in.quality) << ",\n" << "\"toneMapping\": " << (in.toneMapping) << ",\n" + << "\"genericToneMapper\": " << (in.genericToneMapper) << ",\n" << "\"luminanceScaling\": " << to_string(in.luminanceScaling) << ",\n" << "\"exposure\": " << (in.exposure) << ",\n" << "\"temperature\": " << (in.temperature) << ",\n" @@ -1344,13 +1403,23 @@ static std::ostream& operator<<(std::ostream& out, const Settings& in) { << "}"; } +bool GenericToneMapperSettings::operator==(const GenericToneMapperSettings &rhs) const { + static_assert(sizeof(GenericToneMapperSettings) == 20, "Please update Settings.cpp"); + return contrast == rhs.contrast && + shoulder == rhs.shoulder && + midGrayIn == rhs.midGrayIn && + midGrayOut == rhs.midGrayOut && + hdrMax == rhs.hdrMax; +} + bool ColorGradingSettings::operator==(const ColorGradingSettings &rhs) const { // If you had to fix the following codeline, then you likely also need to update the // implementation of operator==. - static_assert(sizeof(ColorGradingSettings) == 204, "Please update Settings.cpp"); + static_assert(sizeof(ColorGradingSettings) == 228, "Please update Settings.cpp"); return enabled == rhs.enabled && quality == rhs.quality && toneMapping == rhs.toneMapping && + genericToneMapper == rhs.genericToneMapper && luminanceScaling == rhs.luminanceScaling && exposure == rhs.exposure && temperature == rhs.temperature && diff --git a/libs/viewer/src/SimpleViewer.cpp b/libs/viewer/src/SimpleViewer.cpp index ffc8b97333..1a92d45c92 100644 --- a/libs/viewer/src/SimpleViewer.cpp +++ b/libs/viewer/src/SimpleViewer.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include @@ -119,6 +118,47 @@ static void computeCurvePlot(Settings& settings, float* curvePlot) { } } +static void computeToneMapPlot(ColorGradingSettings& settings, float* plot) { + float hdrMax = 10.0f; + ToneMapper* mapper; + switch (settings.toneMapping) { + case ToneMapping::LINEAR: + mapper = new LinearToneMapper; + break; + case ToneMapping::ACES_LEGACY: + mapper = new ACESLegacyToneMapper; + break; + case ToneMapping::ACES: + mapper = new ACESToneMapper; + break; + case ToneMapping::FILMIC: + mapper = new FilmicToneMapper; + break; + case ToneMapping::GENERIC: + mapper = new GenericToneMapper( + settings.genericToneMapper.contrast, + settings.genericToneMapper.shoulder, + settings.genericToneMapper.midGrayIn, + settings.genericToneMapper.midGrayOut, + settings.genericToneMapper.hdrMax + ); + hdrMax = settings.genericToneMapper.hdrMax; + break; + case ToneMapping::DISPLAY_RANGE: + mapper = new DisplayRangeToneMapper; + break; + } + + float a = std::log10(hdrMax * 1.5f / 1e-6f); + for (size_t i = 0; i < 1024; i++) { + float v = i; + float x = 1e-6f * std::pow(10.0f, a * v / 1023.0f); + plot[i] = (*mapper)(x).r; + } + + delete mapper; +} + static void tooltipFloat(float value) { if (ImGui::IsItemActive() || ImGui::IsItemHovered()) { ImGui::SetTooltip("%.2f", value); @@ -134,10 +174,10 @@ static void pushSliderColors(float hue) { static void popSliderColors() { ImGui::PopStyleColor(4); } -static void colorGradingUI(Settings& settings, float* rangePlot, float* curvePlot) { +static void colorGradingUI(Settings& settings, float* rangePlot, float* curvePlot, float* toneMapPlot) { const static ImVec2 verticalSliderSize(18.0f, 160.0f); - const static ImVec2 plotLinesSize(260.0f, 160.0f); - const static ImVec2 plotLinesWideSize(350.0f, 120.0f); + const static ImVec2 plotLinesSize(0.0f, 160.0f); + const static ImVec2 plotLinesWideSize(0.0f, 120.0f); if (ImGui::CollapsingHeader("Color grading")) { ColorGradingSettings& colorGrading = settings.view.colorGrading; @@ -151,8 +191,25 @@ static void colorGradingUI(Settings& settings, float* rangePlot, float* curvePlo int toneMapping = (int) colorGrading.toneMapping; ImGui::Combo("Tone-mapping", &toneMapping, - "Linear\0ACES (legacy)\0ACES\0Filmic\0Reserved\0Reinhard\0Display Range\0\0"); + "Linear\0ACES (legacy)\0ACES\0Filmic\0Generic\0Display Range\0\0"); colorGrading.toneMapping = (decltype(colorGrading.toneMapping)) toneMapping; + if (colorGrading.toneMapping == ToneMapping::GENERIC) { + if (ImGui::CollapsingHeader("Tonemap parameters")) { + GenericToneMapperSettings& generic = colorGrading.genericToneMapper; + ImGui::SliderFloat("Contrast##genericToneMapper", &generic.contrast, 1e-5f, 3.0f); + ImGui::SliderFloat("Shoulder##genericToneMapper", &generic.shoulder, 0.0f, 1.0f); + ImGui::SliderFloat("Mid-gray in##genericToneMapper", &generic.midGrayIn, 0.0f, 1.0f); + ImGui::SliderFloat("Mid-gray out##genericToneMapper", &generic.midGrayOut, 0.0f, 1.0f); + ImGui::SliderFloat("HDR max", &generic.hdrMax, 1.0f, 64.0f); + } + } + + computeToneMapPlot(colorGrading, toneMapPlot); + + ImGui::PushStyleColor(ImGuiCol_PlotLines, (ImVec4) ImColor::HSV(0.17f, 0.21f, 0.9f)); + ImGui::PlotLines("", toneMapPlot, 1024, 0, "Tone map", 0.0f, 1.05f, ImVec2(0, 160)); + ImGui::PopStyleColor(); + ImGui::Checkbox("Luminance scaling", &colorGrading.luminanceScaling); ImGui::SliderFloat("Exposure", &colorGrading.exposure, -10.0f, 10.0f); @@ -828,7 +885,7 @@ void SimpleViewer::updateUserInterface() { ImGui::Unindent(); } - colorGradingUI(mSettings, mRangePlot, mCurvePlot); + colorGradingUI(mSettings, mRangePlot, mCurvePlot, mToneMapPlot); // At this point, all View settings have been modified, // so we can now push them into the Filament View. diff --git a/libs/viewer/tests/test_settings.cpp b/libs/viewer/tests/test_settings.cpp index 3273fb8f8d..2f4f6f4a43 100644 --- a/libs/viewer/tests/test_settings.cpp +++ b/libs/viewer/tests/test_settings.cpp @@ -37,6 +37,13 @@ static const char* JSON_TEST_DEFAULTS = R"TXT( "enabled": true, "quality": "MEDIUM", "toneMapping": "ACES_LEGACY", + "genericToneMapper": { + "contrast": 1.0, + "shoulder": 1.0, + "midGrayIn": 1.0, + "midGrayOut": 1.0, + "hdrMax": 16.0 + }, "luminanceScaling": false, "exposure": 0, "temperature": 0, diff --git a/samples/material_sandbox.cpp b/samples/material_sandbox.cpp index f3b2c53a62..a0aa39ac7b 100644 --- a/samples/material_sandbox.cpp +++ b/samples/material_sandbox.cpp @@ -716,7 +716,7 @@ 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\0Reserved\0Reinhard\0Display Range\0\0"); + "Linear\0ACES (legacy)\0ACES\0Filmic\0Display Range\0\0"); ImGui::Checkbox("Luminance scaling", &colorGrading.luminanceScaling); if (ImGui::CollapsingHeader("While balance")) { ImGui::SliderInt("Temperature", &colorGrading.temperature, -100, 100); @@ -970,6 +970,9 @@ static void preRender(filament::Engine* engine, filament::View* view, filament:: if (g_params.colorGrading) { if (g_params.colorGradingOptions != g_lastColorGradingOptions) { ColorGradingOptions &options = g_params.colorGradingOptions; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" ColorGrading *colorGrading = ColorGrading::Builder() .whiteBalance(options.temperature / 100.0f, options.tint / 100.0f) .channelMixer(options.outRed, options.outGreen, options.outBlue) @@ -987,6 +990,7 @@ static void preRender(filament::Engine* engine, filament::View* view, filament:: .toneMapping(static_cast(options.toneMapping)) .luminanceScaling(options.luminanceScaling) .build(*engine); +#pragma clang diagnostic pop if (g_colorGrading) { engine->destroy(g_colorGrading); diff --git a/samples/material_sandbox.h b/samples/material_sandbox.h index 022966fe0d..8edef39f7c 100644 --- a/samples/material_sandbox.h +++ b/samples/material_sandbox.h @@ -61,7 +61,11 @@ constexpr uint8_t BLENDING_SOLID_REFRACTION = 4; using namespace filament; struct ColorGradingOptions { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" int toneMapping = static_cast(ColorGrading::ToneMapping::ACES_LEGACY); +#pragma clang diagnostic pop + bool luminanceScaling = false; int temperature = 0; int tint = 0; diff --git a/web/filament-js/jsenums.cpp b/web/filament-js/jsenums.cpp index ed7037aad7..49bb7add4e 100644 --- a/web/filament-js/jsenums.cpp +++ b/web/filament-js/jsenums.cpp @@ -164,8 +164,6 @@ enum_("ColorGrading$ToneMapping") .value("ACES_LEGACY", ColorGrading::ToneMapping::ACES_LEGACY) .value("ACES", ColorGrading::ToneMapping::ACES) .value("FILMIC", ColorGrading::ToneMapping::FILMIC) - .value("RESERVED", ColorGrading::ToneMapping::RESERVED) - .value("REINHARD", ColorGrading::ToneMapping::REINHARD) .value("DISPLAY_RANGE", ColorGrading::ToneMapping::DISPLAY_RANGE); enum_("Frustum$Plane")