From a10eea6e4ce647061813519d5b0ea496f29495b9 Mon Sep 17 00:00:00 2001
From: leonard Wu <364452445@qq.com>
Date: 星期四, 09 八月 2018 09:47:08 +0800
Subject: [PATCH] 同步最新svn内容

---
 Assets/Plugins/PostProcessing/Runtime/Components/ColorGradingComponent.cs |  872 +++++++++++++++++++++++++++++-----------------------------
 1 files changed, 436 insertions(+), 436 deletions(-)

diff --git a/Assets/Plugins/PostProcessing/Runtime/Components/ColorGradingComponent.cs b/Assets/Plugins/PostProcessing/Runtime/Components/ColorGradingComponent.cs
index 5cb5ab9..11ffcf8 100644
--- a/Assets/Plugins/PostProcessing/Runtime/Components/ColorGradingComponent.cs
+++ b/Assets/Plugins/PostProcessing/Runtime/Components/ColorGradingComponent.cs
@@ -1,436 +1,436 @@
-namespace UnityEngine.PostProcessing
-{
-    using DebugMode = BuiltinDebugViewsModel.Mode;
-
-    public sealed class ColorGradingComponent : PostProcessingComponentRenderTexture<ColorGradingModel>
-    {
-        static class Uniforms
-        {
-            internal static readonly int _LutParams                = Shader.PropertyToID("_LutParams");
-            internal static readonly int _NeutralTonemapperParams1 = Shader.PropertyToID("_NeutralTonemapperParams1");
-            internal static readonly int _NeutralTonemapperParams2 = Shader.PropertyToID("_NeutralTonemapperParams2");
-            internal static readonly int _HueShift                 = Shader.PropertyToID("_HueShift");
-            internal static readonly int _Saturation               = Shader.PropertyToID("_Saturation");
-            internal static readonly int _Contrast                 = Shader.PropertyToID("_Contrast");
-            internal static readonly int _Balance                  = Shader.PropertyToID("_Balance");
-            internal static readonly int _Lift                     = Shader.PropertyToID("_Lift");
-            internal static readonly int _InvGamma                 = Shader.PropertyToID("_InvGamma");
-            internal static readonly int _Gain                     = Shader.PropertyToID("_Gain");
-            internal static readonly int _Slope                    = Shader.PropertyToID("_Slope");
-            internal static readonly int _Power                    = Shader.PropertyToID("_Power");
-            internal static readonly int _Offset                   = Shader.PropertyToID("_Offset");
-            internal static readonly int _ChannelMixerRed          = Shader.PropertyToID("_ChannelMixerRed");
-            internal static readonly int _ChannelMixerGreen        = Shader.PropertyToID("_ChannelMixerGreen");
-            internal static readonly int _ChannelMixerBlue         = Shader.PropertyToID("_ChannelMixerBlue");
-            internal static readonly int _Curves                   = Shader.PropertyToID("_Curves");
-            internal static readonly int _LogLut                   = Shader.PropertyToID("_LogLut");
-            internal static readonly int _LogLut_Params            = Shader.PropertyToID("_LogLut_Params");
-            internal static readonly int _ExposureEV               = Shader.PropertyToID("_ExposureEV");
-        }
-
-        const int k_InternalLogLutSize = 32;
-        const int k_CurvePrecision = 128;
-        const float k_CurveStep = 1f / k_CurvePrecision;
-
-        Texture2D m_GradingCurves;
-        Color[] m_pixels = new Color[k_CurvePrecision * 2];
-
-        public override bool active
-        {
-            get
-            {
-                return model != null && model.enabled
-                       && !context.interrupted;
-            }
-        }
-
-        // An analytical model of chromaticity of the standard illuminant, by Judd et al.
-        // http://en.wikipedia.org/wiki/Standard_illuminant#Illuminant_series_D
-        // Slightly modifed to adjust it with the D65 white point (x=0.31271, y=0.32902).
-        float StandardIlluminantY(float x)
-        {
-            return 2.87f * x - 3f * x * x - 0.27509507f;
-        }
-
-        // CIE xy chromaticity to CAT02 LMS.
-        // http://en.wikipedia.org/wiki/LMS_color_space#CAT02
-        Vector3 CIExyToLMS(float x, float y)
-        {
-            float Y = 1f;
-            float X = Y * x / y;
-            float Z = Y * (1f - x - y) / y;
-
-            float L =  0.7328f * X + 0.4296f * Y - 0.1624f * Z;
-            float M = -0.7036f * X + 1.6975f * Y + 0.0061f * Z;
-            float S =  0.0030f * X + 0.0136f * Y + 0.9834f * Z;
-
-            return new Vector3(L, M, S);
-        }
-
-        Vector3 CalculateColorBalance(float temperature, float tint)
-        {
-            // Range ~[-1.8;1.8] ; using higher ranges is unsafe
-            float t1 = temperature / 55f;
-            float t2 = tint / 55f;
-
-            // Get the CIE xy chromaticity of the reference white point.
-            // Note: 0.31271 = x value on the D65 white point
-            float x = 0.31271f - t1 * (t1 < 0f ? 0.1f : 0.05f);
-            float y = StandardIlluminantY(x) + t2 * 0.05f;
-
-            // Calculate the coefficients in the LMS space.
-            var w1 = new Vector3(0.949237f, 1.03542f, 1.08728f); // D65 white point
-            var w2 = CIExyToLMS(x, y);
-            return new Vector3(w1.x / w2.x, w1.y / w2.y, w1.z / w2.z);
-        }
-
-        static Color NormalizeColor(Color c)
-        {
-            float sum = (c.r + c.g + c.b) / 3f;
-
-            if (Mathf.Approximately(sum, 0f))
-                return new Color(1f, 1f, 1f, c.a);
-
-            return new Color
-                   {
-                       r = c.r / sum,
-                       g = c.g / sum,
-                       b = c.b / sum,
-                       a = c.a
-                   };
-        }
-
-        static Vector3 ClampVector(Vector3 v, float min, float max)
-        {
-            return new Vector3(
-                Mathf.Clamp(v.x, min, max),
-                Mathf.Clamp(v.y, min, max),
-                Mathf.Clamp(v.z, min, max)
-                );
-        }
-
-        public static Vector3 GetLiftValue(Color lift)
-        {
-            const float kLiftScale = 0.1f;
-
-            var nLift = NormalizeColor(lift);
-            float avgLift = (nLift.r + nLift.g + nLift.b) / 3f;
-
-            // Getting some artifacts when going into the negatives using a very low offset (lift.a) with non ACES-tonemapping
-            float liftR = (nLift.r - avgLift) * kLiftScale + lift.a;
-            float liftG = (nLift.g - avgLift) * kLiftScale + lift.a;
-            float liftB = (nLift.b - avgLift) * kLiftScale + lift.a;
-
-            return ClampVector(new Vector3(liftR, liftG, liftB), -1f, 1f);
-        }
-
-        public static Vector3 GetGammaValue(Color gamma)
-        {
-            const float kGammaScale = 0.5f;
-            const float kMinGamma = 0.01f;
-
-            var nGamma = NormalizeColor(gamma);
-            float avgGamma = (nGamma.r + nGamma.g + nGamma.b) / 3f;
-
-            gamma.a *= gamma.a < 0f ? 0.8f : 5f;
-            float gammaR = Mathf.Pow(2f, (nGamma.r - avgGamma) * kGammaScale) + gamma.a;
-            float gammaG = Mathf.Pow(2f, (nGamma.g - avgGamma) * kGammaScale) + gamma.a;
-            float gammaB = Mathf.Pow(2f, (nGamma.b - avgGamma) * kGammaScale) + gamma.a;
-
-            float invGammaR = 1f / Mathf.Max(kMinGamma, gammaR);
-            float invGammaG = 1f / Mathf.Max(kMinGamma, gammaG);
-            float invGammaB = 1f / Mathf.Max(kMinGamma, gammaB);
-
-            return ClampVector(new Vector3(invGammaR, invGammaG, invGammaB), 0f, 5f);
-        }
-
-        public static Vector3 GetGainValue(Color gain)
-        {
-            const float kGainScale = 0.5f;
-
-            var nGain = NormalizeColor(gain);
-            float avgGain = (nGain.r + nGain.g + nGain.b) / 3f;
-
-            gain.a *= gain.a > 0f ? 3f : 1f;
-            float gainR = Mathf.Pow(2f, (nGain.r - avgGain) * kGainScale) + gain.a;
-            float gainG = Mathf.Pow(2f, (nGain.g - avgGain) * kGainScale) + gain.a;
-            float gainB = Mathf.Pow(2f, (nGain.b - avgGain) * kGainScale) + gain.a;
-
-            return ClampVector(new Vector3(gainR, gainG, gainB), 0f, 4f);
-        }
-
-        public static void CalculateLiftGammaGain(Color lift, Color gamma, Color gain, out Vector3 outLift, out Vector3 outGamma, out Vector3 outGain)
-        {
-            outLift = GetLiftValue(lift);
-            outGamma = GetGammaValue(gamma);
-            outGain = GetGainValue(gain);
-        }
-
-        public static Vector3 GetSlopeValue(Color slope)
-        {
-            const float kSlopeScale = 0.1f;
-
-            var nSlope = NormalizeColor(slope);
-            float avgSlope = (nSlope.r + nSlope.g + nSlope.b) / 3f;
-
-            slope.a *= 0.5f;
-            float slopeR = (nSlope.r - avgSlope) * kSlopeScale + slope.a + 1f;
-            float slopeG = (nSlope.g - avgSlope) * kSlopeScale + slope.a + 1f;
-            float slopeB = (nSlope.b - avgSlope) * kSlopeScale + slope.a + 1f;
-
-            return ClampVector(new Vector3(slopeR, slopeG, slopeB), 0f, 2f);
-        }
-
-        public static Vector3 GetPowerValue(Color power)
-        {
-            const float kPowerScale = 0.1f;
-            const float minPower = 0.01f;
-
-            var nPower = NormalizeColor(power);
-            float avgPower = (nPower.r + nPower.g + nPower.b) / 3f;
-
-            power.a *= 0.5f;
-            float powerR = (nPower.r - avgPower) * kPowerScale + power.a + 1f;
-            float powerG = (nPower.g - avgPower) * kPowerScale + power.a + 1f;
-            float powerB = (nPower.b - avgPower) * kPowerScale + power.a + 1f;
-
-            float invPowerR = 1f / Mathf.Max(minPower, powerR);
-            float invPowerG = 1f / Mathf.Max(minPower, powerG);
-            float invPowerB = 1f / Mathf.Max(minPower, powerB);
-
-            return ClampVector(new Vector3(invPowerR, invPowerG, invPowerB), 0.5f, 2.5f);
-        }
-
-        public static Vector3 GetOffsetValue(Color offset)
-        {
-            const float kOffsetScale = 0.05f;
-
-            var nOffset = NormalizeColor(offset);
-            float avgOffset = (nOffset.r + nOffset.g + nOffset.b) / 3f;
-
-            offset.a *= 0.5f;
-            float offsetR = (nOffset.r - avgOffset) * kOffsetScale + offset.a;
-            float offsetG = (nOffset.g - avgOffset) * kOffsetScale + offset.a;
-            float offsetB = (nOffset.b - avgOffset) * kOffsetScale + offset.a;
-
-            return ClampVector(new Vector3(offsetR, offsetG, offsetB), -0.8f, 0.8f);
-        }
-
-        public static void CalculateSlopePowerOffset(Color slope, Color power, Color offset, out Vector3 outSlope, out Vector3 outPower, out Vector3 outOffset)
-        {
-            outSlope = GetSlopeValue(slope);
-            outPower = GetPowerValue(power);
-            outOffset = GetOffsetValue(offset);
-        }
-
-        TextureFormat GetCurveFormat()
-        {
-            if (SystemInfo.SupportsTextureFormat(TextureFormat.RGBAHalf))
-                return TextureFormat.RGBAHalf;
-
-            return TextureFormat.RGBA32;
-        }
-
-        Texture2D GetCurveTexture()
-        {
-            if (m_GradingCurves == null)
-            {
-                m_GradingCurves = new Texture2D(k_CurvePrecision, 2, GetCurveFormat(), false, true)
-                {
-                    name = "Internal Curves Texture",
-                    hideFlags = HideFlags.DontSave,
-                    anisoLevel = 0,
-                    wrapMode = TextureWrapMode.Clamp,
-                    filterMode = FilterMode.Bilinear
-                };
-            }
-
-            var curves = model.settings.curves;
-            curves.hueVShue.Cache();
-            curves.hueVSsat.Cache();
-
-            for (int i = 0; i < k_CurvePrecision; i++)
-            {
-                float t = i * k_CurveStep;
-
-                // HSL
-                float x = curves.hueVShue.Evaluate(t);
-                float y = curves.hueVSsat.Evaluate(t);
-                float z = curves.satVSsat.Evaluate(t);
-                float w = curves.lumVSsat.Evaluate(t);
-                m_pixels[i] = new Color(x, y, z, w);
-
-                // YRGB
-                float m = curves.master.Evaluate(t);
-                float r = curves.red.Evaluate(t);
-                float g = curves.green.Evaluate(t);
-                float b = curves.blue.Evaluate(t);
-                m_pixels[i + k_CurvePrecision] = new Color(r, g, b, m);
-            }
-
-            m_GradingCurves.SetPixels(m_pixels);
-            m_GradingCurves.Apply(false, false);
-
-            return m_GradingCurves;
-        }
-
-        bool IsLogLutValid(RenderTexture lut)
-        {
-            return lut != null && lut.IsCreated() && lut.height == k_InternalLogLutSize;
-        }
-
-        RenderTextureFormat GetLutFormat()
-        {
-            if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf))
-                return RenderTextureFormat.ARGBHalf;
-
-            return RenderTextureFormat.ARGB32;
-        }
-
-        void GenerateLut()
-        {
-            var settings = model.settings;
-
-            if (!IsLogLutValid(model.bakedLut))
-            {
-                GraphicsUtils.Destroy(model.bakedLut);
-
-                model.bakedLut = new RenderTexture(k_InternalLogLutSize * k_InternalLogLutSize, k_InternalLogLutSize, 0, GetLutFormat())
-                {
-                    name = "Color Grading Log LUT",
-                    hideFlags = HideFlags.DontSave,
-                    filterMode = FilterMode.Bilinear,
-                    wrapMode = TextureWrapMode.Clamp,
-                    anisoLevel = 0
-                };
-            }
-
-            var lutMaterial = context.materialFactory.Get("Hidden/Post FX/Lut Generator");
-            lutMaterial.SetVector(Uniforms._LutParams, new Vector4(
-                    k_InternalLogLutSize,
-                    0.5f / (k_InternalLogLutSize * k_InternalLogLutSize),
-                    0.5f / k_InternalLogLutSize,
-                    k_InternalLogLutSize / (k_InternalLogLutSize - 1f))
-                );
-
-            // Tonemapping
-            lutMaterial.shaderKeywords = null;
-
-            var tonemapping = settings.tonemapping;
-            switch (tonemapping.tonemapper)
-            {
-                case ColorGradingModel.Tonemapper.Neutral:
-                {
-                    lutMaterial.EnableKeyword("TONEMAPPING_NEUTRAL");
-
-                    const float scaleFactor = 20f;
-                    const float scaleFactorHalf = scaleFactor * 0.5f;
-
-                    float inBlack = tonemapping.neutralBlackIn * scaleFactor + 1f;
-                    float outBlack = tonemapping.neutralBlackOut * scaleFactorHalf + 1f;
-                    float inWhite = tonemapping.neutralWhiteIn / scaleFactor;
-                    float outWhite = 1f - tonemapping.neutralWhiteOut / scaleFactor;
-                    float blackRatio = inBlack / outBlack;
-                    float whiteRatio = inWhite / outWhite;
-
-                    const float a = 0.2f;
-                    float b = Mathf.Max(0f, Mathf.LerpUnclamped(0.57f, 0.37f, blackRatio));
-                    float c = Mathf.LerpUnclamped(0.01f, 0.24f, whiteRatio);
-                    float d = Mathf.Max(0f, Mathf.LerpUnclamped(0.02f, 0.20f, blackRatio));
-                    const float e = 0.02f;
-                    const float f = 0.30f;
-
-                    lutMaterial.SetVector(Uniforms._NeutralTonemapperParams1, new Vector4(a, b, c, d));
-                    lutMaterial.SetVector(Uniforms._NeutralTonemapperParams2, new Vector4(e, f, tonemapping.neutralWhiteLevel, tonemapping.neutralWhiteClip / scaleFactorHalf));
-                    break;
-                }
-
-                case ColorGradingModel.Tonemapper.ACES:
-                {
-                    lutMaterial.EnableKeyword("TONEMAPPING_FILMIC");
-                    break;
-                }
-            }
-
-            // Color balance & basic grading settings
-            lutMaterial.SetFloat(Uniforms._HueShift, settings.basic.hueShift / 360f);
-            lutMaterial.SetFloat(Uniforms._Saturation, settings.basic.saturation);
-            lutMaterial.SetFloat(Uniforms._Contrast, settings.basic.contrast);
-            lutMaterial.SetVector(Uniforms._Balance, CalculateColorBalance(settings.basic.temperature, settings.basic.tint));
-
-            // Lift / Gamma / Gain
-            Vector3 lift, gamma, gain;
-            CalculateLiftGammaGain(
-                settings.colorWheels.linear.lift,
-                settings.colorWheels.linear.gamma,
-                settings.colorWheels.linear.gain,
-                out lift, out gamma, out gain
-                );
-
-            lutMaterial.SetVector(Uniforms._Lift, lift);
-            lutMaterial.SetVector(Uniforms._InvGamma, gamma);
-            lutMaterial.SetVector(Uniforms._Gain, gain);
-
-            // Slope / Power / Offset
-            Vector3 slope, power, offset;
-            CalculateSlopePowerOffset(
-                settings.colorWheels.log.slope,
-                settings.colorWheels.log.power,
-                settings.colorWheels.log.offset,
-                out slope, out power, out offset
-                );
-
-            lutMaterial.SetVector(Uniforms._Slope, slope);
-            lutMaterial.SetVector(Uniforms._Power, power);
-            lutMaterial.SetVector(Uniforms._Offset, offset);
-
-            // Channel mixer
-            lutMaterial.SetVector(Uniforms._ChannelMixerRed, settings.channelMixer.red);
-            lutMaterial.SetVector(Uniforms._ChannelMixerGreen, settings.channelMixer.green);
-            lutMaterial.SetVector(Uniforms._ChannelMixerBlue, settings.channelMixer.blue);
-
-            // Selective grading & YRGB curves
-            lutMaterial.SetTexture(Uniforms._Curves, GetCurveTexture());
-
-            // Generate the lut
-            Graphics.Blit(null, model.bakedLut, lutMaterial, 0);
-        }
-
-        public override void Prepare(Material uberMaterial)
-        {
-            if (model.isDirty || !IsLogLutValid(model.bakedLut))
-            {
-                GenerateLut();
-                model.isDirty = false;
-            }
-
-            uberMaterial.EnableKeyword(
-                context.profile.debugViews.IsModeActive(DebugMode.PreGradingLog)
-                ? "COLOR_GRADING_LOG_VIEW"
-                : "COLOR_GRADING"
-                );
-
-            var bakedLut = model.bakedLut;
-            uberMaterial.SetTexture(Uniforms._LogLut, bakedLut);
-            uberMaterial.SetVector(Uniforms._LogLut_Params, new Vector3(1f / bakedLut.width, 1f / bakedLut.height, bakedLut.height - 1f));
-
-            float ev = Mathf.Exp(model.settings.basic.postExposure * 0.69314718055994530941723212145818f);
-            uberMaterial.SetFloat(Uniforms._ExposureEV, ev);
-        }
-
-        public void OnGUI()
-        {
-            var bakedLut = model.bakedLut;
-            var rect = new Rect(context.viewport.x * Screen.width + 8f, 8f, bakedLut.width, bakedLut.height);
-            GUI.DrawTexture(rect, bakedLut);
-        }
-
-        public override void OnDisable()
-        {
-            GraphicsUtils.Destroy(m_GradingCurves);
-            GraphicsUtils.Destroy(model.bakedLut);
-            m_GradingCurves = null;
-            model.bakedLut = null;
-        }
-    }
-}
+namespace UnityEngine.PostProcessing
+{
+    using DebugMode = BuiltinDebugViewsModel.Mode;
+
+    public sealed class ColorGradingComponent : PostProcessingComponentRenderTexture<ColorGradingModel>
+    {
+        static class Uniforms
+        {
+            internal static readonly int _LutParams                = Shader.PropertyToID("_LutParams");
+            internal static readonly int _NeutralTonemapperParams1 = Shader.PropertyToID("_NeutralTonemapperParams1");
+            internal static readonly int _NeutralTonemapperParams2 = Shader.PropertyToID("_NeutralTonemapperParams2");
+            internal static readonly int _HueShift                 = Shader.PropertyToID("_HueShift");
+            internal static readonly int _Saturation               = Shader.PropertyToID("_Saturation");
+            internal static readonly int _Contrast                 = Shader.PropertyToID("_Contrast");
+            internal static readonly int _Balance                  = Shader.PropertyToID("_Balance");
+            internal static readonly int _Lift                     = Shader.PropertyToID("_Lift");
+            internal static readonly int _InvGamma                 = Shader.PropertyToID("_InvGamma");
+            internal static readonly int _Gain                     = Shader.PropertyToID("_Gain");
+            internal static readonly int _Slope                    = Shader.PropertyToID("_Slope");
+            internal static readonly int _Power                    = Shader.PropertyToID("_Power");
+            internal static readonly int _Offset                   = Shader.PropertyToID("_Offset");
+            internal static readonly int _ChannelMixerRed          = Shader.PropertyToID("_ChannelMixerRed");
+            internal static readonly int _ChannelMixerGreen        = Shader.PropertyToID("_ChannelMixerGreen");
+            internal static readonly int _ChannelMixerBlue         = Shader.PropertyToID("_ChannelMixerBlue");
+            internal static readonly int _Curves                   = Shader.PropertyToID("_Curves");
+            internal static readonly int _LogLut                   = Shader.PropertyToID("_LogLut");
+            internal static readonly int _LogLut_Params            = Shader.PropertyToID("_LogLut_Params");
+            internal static readonly int _ExposureEV               = Shader.PropertyToID("_ExposureEV");
+        }
+
+        const int k_InternalLogLutSize = 32;
+        const int k_CurvePrecision = 128;
+        const float k_CurveStep = 1f / k_CurvePrecision;
+
+        Texture2D m_GradingCurves;
+        Color[] m_pixels = new Color[k_CurvePrecision * 2];
+
+        public override bool active
+        {
+            get
+            {
+                return model != null && model.enabled
+                       && !context.interrupted;
+            }
+        }
+
+        // An analytical model of chromaticity of the standard illuminant, by Judd et al.
+        // http://en.wikipedia.org/wiki/Standard_illuminant#Illuminant_series_D
+        // Slightly modifed to adjust it with the D65 white point (x=0.31271, y=0.32902).
+        float StandardIlluminantY(float x)
+        {
+            return 2.87f * x - 3f * x * x - 0.27509507f;
+        }
+
+        // CIE xy chromaticity to CAT02 LMS.
+        // http://en.wikipedia.org/wiki/LMS_color_space#CAT02
+        Vector3 CIExyToLMS(float x, float y)
+        {
+            float Y = 1f;
+            float X = Y * x / y;
+            float Z = Y * (1f - x - y) / y;
+
+            float L =  0.7328f * X + 0.4296f * Y - 0.1624f * Z;
+            float M = -0.7036f * X + 1.6975f * Y + 0.0061f * Z;
+            float S =  0.0030f * X + 0.0136f * Y + 0.9834f * Z;
+
+            return new Vector3(L, M, S);
+        }
+
+        Vector3 CalculateColorBalance(float temperature, float tint)
+        {
+            // Range ~[-1.8;1.8] ; using higher ranges is unsafe
+            float t1 = temperature / 55f;
+            float t2 = tint / 55f;
+
+            // Get the CIE xy chromaticity of the reference white point.
+            // Note: 0.31271 = x value on the D65 white point
+            float x = 0.31271f - t1 * (t1 < 0f ? 0.1f : 0.05f);
+            float y = StandardIlluminantY(x) + t2 * 0.05f;
+
+            // Calculate the coefficients in the LMS space.
+            var w1 = new Vector3(0.949237f, 1.03542f, 1.08728f); // D65 white point
+            var w2 = CIExyToLMS(x, y);
+            return new Vector3(w1.x / w2.x, w1.y / w2.y, w1.z / w2.z);
+        }
+
+        static Color NormalizeColor(Color c)
+        {
+            float sum = (c.r + c.g + c.b) / 3f;
+
+            if (Mathf.Approximately(sum, 0f))
+                return new Color(1f, 1f, 1f, c.a);
+
+            return new Color
+                   {
+                       r = c.r / sum,
+                       g = c.g / sum,
+                       b = c.b / sum,
+                       a = c.a
+                   };
+        }
+
+        static Vector3 ClampVector(Vector3 v, float min, float max)
+        {
+            return new Vector3(
+                Mathf.Clamp(v.x, min, max),
+                Mathf.Clamp(v.y, min, max),
+                Mathf.Clamp(v.z, min, max)
+                );
+        }
+
+        public static Vector3 GetLiftValue(Color lift)
+        {
+            const float kLiftScale = 0.1f;
+
+            var nLift = NormalizeColor(lift);
+            float avgLift = (nLift.r + nLift.g + nLift.b) / 3f;
+
+            // Getting some artifacts when going into the negatives using a very low offset (lift.a) with non ACES-tonemapping
+            float liftR = (nLift.r - avgLift) * kLiftScale + lift.a;
+            float liftG = (nLift.g - avgLift) * kLiftScale + lift.a;
+            float liftB = (nLift.b - avgLift) * kLiftScale + lift.a;
+
+            return ClampVector(new Vector3(liftR, liftG, liftB), -1f, 1f);
+        }
+
+        public static Vector3 GetGammaValue(Color gamma)
+        {
+            const float kGammaScale = 0.5f;
+            const float kMinGamma = 0.01f;
+
+            var nGamma = NormalizeColor(gamma);
+            float avgGamma = (nGamma.r + nGamma.g + nGamma.b) / 3f;
+
+            gamma.a *= gamma.a < 0f ? 0.8f : 5f;
+            float gammaR = Mathf.Pow(2f, (nGamma.r - avgGamma) * kGammaScale) + gamma.a;
+            float gammaG = Mathf.Pow(2f, (nGamma.g - avgGamma) * kGammaScale) + gamma.a;
+            float gammaB = Mathf.Pow(2f, (nGamma.b - avgGamma) * kGammaScale) + gamma.a;
+
+            float invGammaR = 1f / Mathf.Max(kMinGamma, gammaR);
+            float invGammaG = 1f / Mathf.Max(kMinGamma, gammaG);
+            float invGammaB = 1f / Mathf.Max(kMinGamma, gammaB);
+
+            return ClampVector(new Vector3(invGammaR, invGammaG, invGammaB), 0f, 5f);
+        }
+
+        public static Vector3 GetGainValue(Color gain)
+        {
+            const float kGainScale = 0.5f;
+
+            var nGain = NormalizeColor(gain);
+            float avgGain = (nGain.r + nGain.g + nGain.b) / 3f;
+
+            gain.a *= gain.a > 0f ? 3f : 1f;
+            float gainR = Mathf.Pow(2f, (nGain.r - avgGain) * kGainScale) + gain.a;
+            float gainG = Mathf.Pow(2f, (nGain.g - avgGain) * kGainScale) + gain.a;
+            float gainB = Mathf.Pow(2f, (nGain.b - avgGain) * kGainScale) + gain.a;
+
+            return ClampVector(new Vector3(gainR, gainG, gainB), 0f, 4f);
+        }
+
+        public static void CalculateLiftGammaGain(Color lift, Color gamma, Color gain, out Vector3 outLift, out Vector3 outGamma, out Vector3 outGain)
+        {
+            outLift = GetLiftValue(lift);
+            outGamma = GetGammaValue(gamma);
+            outGain = GetGainValue(gain);
+        }
+
+        public static Vector3 GetSlopeValue(Color slope)
+        {
+            const float kSlopeScale = 0.1f;
+
+            var nSlope = NormalizeColor(slope);
+            float avgSlope = (nSlope.r + nSlope.g + nSlope.b) / 3f;
+
+            slope.a *= 0.5f;
+            float slopeR = (nSlope.r - avgSlope) * kSlopeScale + slope.a + 1f;
+            float slopeG = (nSlope.g - avgSlope) * kSlopeScale + slope.a + 1f;
+            float slopeB = (nSlope.b - avgSlope) * kSlopeScale + slope.a + 1f;
+
+            return ClampVector(new Vector3(slopeR, slopeG, slopeB), 0f, 2f);
+        }
+
+        public static Vector3 GetPowerValue(Color power)
+        {
+            const float kPowerScale = 0.1f;
+            const float minPower = 0.01f;
+
+            var nPower = NormalizeColor(power);
+            float avgPower = (nPower.r + nPower.g + nPower.b) / 3f;
+
+            power.a *= 0.5f;
+            float powerR = (nPower.r - avgPower) * kPowerScale + power.a + 1f;
+            float powerG = (nPower.g - avgPower) * kPowerScale + power.a + 1f;
+            float powerB = (nPower.b - avgPower) * kPowerScale + power.a + 1f;
+
+            float invPowerR = 1f / Mathf.Max(minPower, powerR);
+            float invPowerG = 1f / Mathf.Max(minPower, powerG);
+            float invPowerB = 1f / Mathf.Max(minPower, powerB);
+
+            return ClampVector(new Vector3(invPowerR, invPowerG, invPowerB), 0.5f, 2.5f);
+        }
+
+        public static Vector3 GetOffsetValue(Color offset)
+        {
+            const float kOffsetScale = 0.05f;
+
+            var nOffset = NormalizeColor(offset);
+            float avgOffset = (nOffset.r + nOffset.g + nOffset.b) / 3f;
+
+            offset.a *= 0.5f;
+            float offsetR = (nOffset.r - avgOffset) * kOffsetScale + offset.a;
+            float offsetG = (nOffset.g - avgOffset) * kOffsetScale + offset.a;
+            float offsetB = (nOffset.b - avgOffset) * kOffsetScale + offset.a;
+
+            return ClampVector(new Vector3(offsetR, offsetG, offsetB), -0.8f, 0.8f);
+        }
+
+        public static void CalculateSlopePowerOffset(Color slope, Color power, Color offset, out Vector3 outSlope, out Vector3 outPower, out Vector3 outOffset)
+        {
+            outSlope = GetSlopeValue(slope);
+            outPower = GetPowerValue(power);
+            outOffset = GetOffsetValue(offset);
+        }
+
+        TextureFormat GetCurveFormat()
+        {
+            if (SystemInfo.SupportsTextureFormat(TextureFormat.RGBAHalf))
+                return TextureFormat.RGBAHalf;
+
+            return TextureFormat.RGBA32;
+        }
+
+        Texture2D GetCurveTexture()
+        {
+            if (m_GradingCurves == null)
+            {
+                m_GradingCurves = new Texture2D(k_CurvePrecision, 2, GetCurveFormat(), false, true)
+                {
+                    name = "Internal Curves Texture",
+                    hideFlags = HideFlags.DontSave,
+                    anisoLevel = 0,
+                    wrapMode = TextureWrapMode.Clamp,
+                    filterMode = FilterMode.Bilinear
+                };
+            }
+
+            var curves = model.settings.curves;
+            curves.hueVShue.Cache();
+            curves.hueVSsat.Cache();
+
+            for (int i = 0; i < k_CurvePrecision; i++)
+            {
+                float t = i * k_CurveStep;
+
+                // HSL
+                float x = curves.hueVShue.Evaluate(t);
+                float y = curves.hueVSsat.Evaluate(t);
+                float z = curves.satVSsat.Evaluate(t);
+                float w = curves.lumVSsat.Evaluate(t);
+                m_pixels[i] = new Color(x, y, z, w);
+
+                // YRGB
+                float m = curves.master.Evaluate(t);
+                float r = curves.red.Evaluate(t);
+                float g = curves.green.Evaluate(t);
+                float b = curves.blue.Evaluate(t);
+                m_pixels[i + k_CurvePrecision] = new Color(r, g, b, m);
+            }
+
+            m_GradingCurves.SetPixels(m_pixels);
+            m_GradingCurves.Apply(false, false);
+
+            return m_GradingCurves;
+        }
+
+        bool IsLogLutValid(RenderTexture lut)
+        {
+            return lut != null && lut.IsCreated() && lut.height == k_InternalLogLutSize;
+        }
+
+        RenderTextureFormat GetLutFormat()
+        {
+            if (SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf))
+                return RenderTextureFormat.ARGBHalf;
+
+            return RenderTextureFormat.ARGB32;
+        }
+
+        void GenerateLut()
+        {
+            var settings = model.settings;
+
+            if (!IsLogLutValid(model.bakedLut))
+            {
+                GraphicsUtils.Destroy(model.bakedLut);
+
+                model.bakedLut = new RenderTexture(k_InternalLogLutSize * k_InternalLogLutSize, k_InternalLogLutSize, 0, GetLutFormat())
+                {
+                    name = "Color Grading Log LUT",
+                    hideFlags = HideFlags.DontSave,
+                    filterMode = FilterMode.Bilinear,
+                    wrapMode = TextureWrapMode.Clamp,
+                    anisoLevel = 0
+                };
+            }
+
+            var lutMaterial = context.materialFactory.Get("Hidden/Post FX/Lut Generator");
+            lutMaterial.SetVector(Uniforms._LutParams, new Vector4(
+                    k_InternalLogLutSize,
+                    0.5f / (k_InternalLogLutSize * k_InternalLogLutSize),
+                    0.5f / k_InternalLogLutSize,
+                    k_InternalLogLutSize / (k_InternalLogLutSize - 1f))
+                );
+
+            // Tonemapping
+            lutMaterial.shaderKeywords = null;
+
+            var tonemapping = settings.tonemapping;
+            switch (tonemapping.tonemapper)
+            {
+                case ColorGradingModel.Tonemapper.Neutral:
+                {
+                    lutMaterial.EnableKeyword("TONEMAPPING_NEUTRAL");
+
+                    const float scaleFactor = 20f;
+                    const float scaleFactorHalf = scaleFactor * 0.5f;
+
+                    float inBlack = tonemapping.neutralBlackIn * scaleFactor + 1f;
+                    float outBlack = tonemapping.neutralBlackOut * scaleFactorHalf + 1f;
+                    float inWhite = tonemapping.neutralWhiteIn / scaleFactor;
+                    float outWhite = 1f - tonemapping.neutralWhiteOut / scaleFactor;
+                    float blackRatio = inBlack / outBlack;
+                    float whiteRatio = inWhite / outWhite;
+
+                    const float a = 0.2f;
+                    float b = Mathf.Max(0f, Mathf.LerpUnclamped(0.57f, 0.37f, blackRatio));
+                    float c = Mathf.LerpUnclamped(0.01f, 0.24f, whiteRatio);
+                    float d = Mathf.Max(0f, Mathf.LerpUnclamped(0.02f, 0.20f, blackRatio));
+                    const float e = 0.02f;
+                    const float f = 0.30f;
+
+                    lutMaterial.SetVector(Uniforms._NeutralTonemapperParams1, new Vector4(a, b, c, d));
+                    lutMaterial.SetVector(Uniforms._NeutralTonemapperParams2, new Vector4(e, f, tonemapping.neutralWhiteLevel, tonemapping.neutralWhiteClip / scaleFactorHalf));
+                    break;
+                }
+
+                case ColorGradingModel.Tonemapper.ACES:
+                {
+                    lutMaterial.EnableKeyword("TONEMAPPING_FILMIC");
+                    break;
+                }
+            }
+
+            // Color balance & basic grading settings
+            lutMaterial.SetFloat(Uniforms._HueShift, settings.basic.hueShift / 360f);
+            lutMaterial.SetFloat(Uniforms._Saturation, settings.basic.saturation);
+            lutMaterial.SetFloat(Uniforms._Contrast, settings.basic.contrast);
+            lutMaterial.SetVector(Uniforms._Balance, CalculateColorBalance(settings.basic.temperature, settings.basic.tint));
+
+            // Lift / Gamma / Gain
+            Vector3 lift, gamma, gain;
+            CalculateLiftGammaGain(
+                settings.colorWheels.linear.lift,
+                settings.colorWheels.linear.gamma,
+                settings.colorWheels.linear.gain,
+                out lift, out gamma, out gain
+                );
+
+            lutMaterial.SetVector(Uniforms._Lift, lift);
+            lutMaterial.SetVector(Uniforms._InvGamma, gamma);
+            lutMaterial.SetVector(Uniforms._Gain, gain);
+
+            // Slope / Power / Offset
+            Vector3 slope, power, offset;
+            CalculateSlopePowerOffset(
+                settings.colorWheels.log.slope,
+                settings.colorWheels.log.power,
+                settings.colorWheels.log.offset,
+                out slope, out power, out offset
+                );
+
+            lutMaterial.SetVector(Uniforms._Slope, slope);
+            lutMaterial.SetVector(Uniforms._Power, power);
+            lutMaterial.SetVector(Uniforms._Offset, offset);
+
+            // Channel mixer
+            lutMaterial.SetVector(Uniforms._ChannelMixerRed, settings.channelMixer.red);
+            lutMaterial.SetVector(Uniforms._ChannelMixerGreen, settings.channelMixer.green);
+            lutMaterial.SetVector(Uniforms._ChannelMixerBlue, settings.channelMixer.blue);
+
+            // Selective grading & YRGB curves
+            lutMaterial.SetTexture(Uniforms._Curves, GetCurveTexture());
+
+            // Generate the lut
+            Graphics.Blit(null, model.bakedLut, lutMaterial, 0);
+        }
+
+        public override void Prepare(Material uberMaterial)
+        {
+            if (model.isDirty || !IsLogLutValid(model.bakedLut))
+            {
+                GenerateLut();
+                model.isDirty = false;
+            }
+
+            uberMaterial.EnableKeyword(
+                context.profile.debugViews.IsModeActive(DebugMode.PreGradingLog)
+                ? "COLOR_GRADING_LOG_VIEW"
+                : "COLOR_GRADING"
+                );
+
+            var bakedLut = model.bakedLut;
+            uberMaterial.SetTexture(Uniforms._LogLut, bakedLut);
+            uberMaterial.SetVector(Uniforms._LogLut_Params, new Vector3(1f / bakedLut.width, 1f / bakedLut.height, bakedLut.height - 1f));
+
+            float ev = Mathf.Exp(model.settings.basic.postExposure * 0.69314718055994530941723212145818f);
+            uberMaterial.SetFloat(Uniforms._ExposureEV, ev);
+        }
+
+        public void OnGUI()
+        {
+            var bakedLut = model.bakedLut;
+            var rect = new Rect(context.viewport.x * Screen.width + 8f, 8f, bakedLut.width, bakedLut.height);
+            GUI.DrawTexture(rect, bakedLut);
+        }
+
+        public override void OnDisable()
+        {
+            GraphicsUtils.Destroy(m_GradingCurves);
+            GraphicsUtils.Destroy(model.bakedLut);
+            m_GradingCurves = null;
+            model.bakedLut = null;
+        }
+    }
+}

--
Gitblit v1.8.0