Пример #1
0
        public override void Render(PostProcessRenderContext context)
        {
            var cmd = context.command;

            cmd.BeginSample("AutoExposureLookup");

            var sheet = context.propertySheets.Get(context.resources.shaders.autoExposure);

            sheet.ClearKeywords();

            // Prepare autoExpo texture pool
            CheckTexture(0);
            CheckTexture(1);

            // Make sure filtering values are correct to avoid apocalyptic consequences
            float       lowPercent  = settings.filtering.value.x;
            float       highPercent = settings.filtering.value.y;
            const float kMinDelta   = 1e-2f;

            highPercent = Mathf.Clamp(highPercent, 1f + kMinDelta, 99f);
            lowPercent  = Mathf.Clamp(lowPercent, 1f, highPercent - kMinDelta);

            // Compute auto exposure
            sheet.properties.SetBuffer(ShaderIDs.HistogramBuffer, context.logHistogram.data);
            sheet.properties.SetVector(ShaderIDs.Params, new Vector4(lowPercent * 0.01f, highPercent * 0.01f, RuntimeUtilities.Exp2(settings.minLuminance.value), RuntimeUtilities.Exp2(settings.maxLuminance.value)));
            sheet.properties.SetVector(ShaderIDs.Speed, new Vector2(settings.speedDown.value, settings.speedUp.value));
            sheet.properties.SetVector(ShaderIDs.ScaleOffsetRes, context.logHistogram.GetHistogramScaleOffsetRes(context));
            sheet.properties.SetFloat(ShaderIDs.ExposureCompensation, settings.keyValue.value);

            if (m_FirstFrame || !Application.isPlaying)
            {
                // We don't want eye adaptation when not in play mode because the GameView isn't
                // animated, thus making it harder to tweak. Just use the final audo exposure value.
                m_CurrentAutoExposure = m_AutoExposurePool[0];
                cmd.BlitFullscreenTriangle(BuiltinRenderTextureType.None, m_CurrentAutoExposure, sheet, (int)EyeAdaptation.Fixed);

                // Copy current exposure to the other pingpong target to avoid adapting from black
                RuntimeUtilities.CopyTexture(cmd, m_AutoExposurePool[0], m_AutoExposurePool[1]);
            }
            else
            {
                int pp  = m_AutoExposurePingPong;
                var src = m_AutoExposurePool[++pp % 2];
                var dst = m_AutoExposurePool[++pp % 2];
                cmd.BlitFullscreenTriangle(src, dst, sheet, (int)settings.eyeAdaptation.value);
                m_AutoExposurePingPong = ++pp % 2;
                m_CurrentAutoExposure  = dst;
            }

            cmd.EndSample("AutoExposureLookup");

            context.autoExposureTexture = m_CurrentAutoExposure;
            context.autoExposure        = settings;
            m_FirstFrame = false;
        }
Пример #2
0
        public override void Render(PostProcessRenderContext context)
        {
            var cmd = context.command;

            cmd.BeginSample("AutoExposureLookup");

            // Prepare autoExpo texture pool
            CheckTexture(context.xrActiveEye, 0);
            CheckTexture(context.xrActiveEye, 1);

            // Make sure filtering values are correct to avoid apocalyptic consequences
            float       lowPercent  = settings.filtering.value.x;
            float       highPercent = settings.filtering.value.y;
            const float kMinDelta   = 1e-2f;

            highPercent = Mathf.Clamp(highPercent, 1f + kMinDelta, 99f);
            lowPercent  = Mathf.Clamp(lowPercent, 1f, highPercent - kMinDelta);

            // Clamp min/max adaptation values as well
            float minLum = settings.minLuminance.value;
            float maxLum = settings.maxLuminance.value;

            settings.minLuminance.value = Mathf.Min(minLum, maxLum);
            settings.maxLuminance.value = Mathf.Max(minLum, maxLum);

            // Compute average luminance & auto exposure
            bool   firstFrame = m_ResetHistory || !Application.isPlaying;
            string adaptation = null;

            if (firstFrame || settings.eyeAdaptation.value == EyeAdaptation.Fixed)
            {
                adaptation = "KAutoExposureAvgLuminance_fixed";
            }
            else
            {
                adaptation = "KAutoExposureAvgLuminance_progressive";
            }

            var compute = context.resources.computeShaders.autoExposure;
            int kernel  = compute.FindKernel(adaptation);

            cmd.SetComputeBufferParam(compute, kernel, "_HistogramBuffer", context.logHistogram.data);
            cmd.SetComputeVectorParam(compute, "_Params1", new Vector4(lowPercent * 0.01f, highPercent * 0.01f, RuntimeUtilities.Exp2(settings.minLuminance.value), RuntimeUtilities.Exp2(settings.maxLuminance.value)));
            cmd.SetComputeVectorParam(compute, "_Params2", new Vector4(settings.speedDown.value, settings.speedUp.value, settings.keyValue.value, Time.deltaTime));
            cmd.SetComputeVectorParam(compute, "_ScaleOffsetRes", context.logHistogram.GetHistogramScaleOffsetRes(context));

            if (firstFrame)
            {
                // We don't want eye adaptation when not in play mode because the GameView isn't
                // animated, thus making it harder to tweak. Just use the final audo exposure value.
                m_CurrentAutoExposure = m_AutoExposurePool[context.xrActiveEye][0];
                cmd.SetComputeTextureParam(compute, kernel, "_Destination", m_CurrentAutoExposure);
                cmd.DispatchCompute(compute, kernel, 1, 1, 1);

                // Copy current exposure to the other pingpong target to avoid adapting from black
                RuntimeUtilities.CopyTexture(cmd, m_AutoExposurePool[context.xrActiveEye][0], m_AutoExposurePool[context.xrActiveEye][1]);
                m_ResetHistory = false;
            }
            else
            {
                int pp  = m_AutoExposurePingPong[context.xrActiveEye];
                var src = m_AutoExposurePool[context.xrActiveEye][++pp % 2];
                var dst = m_AutoExposurePool[context.xrActiveEye][++pp % 2];

                cmd.SetComputeTextureParam(compute, kernel, "_Source", src);
                cmd.SetComputeTextureParam(compute, kernel, "_Destination", dst);
                cmd.DispatchCompute(compute, kernel, 1, 1, 1);

                m_AutoExposurePingPong[context.xrActiveEye] = ++pp % 2;
                m_CurrentAutoExposure = dst;
            }

            cmd.EndSample("AutoExposureLookup");

            context.autoExposureTexture = m_CurrentAutoExposure;
            context.autoExposure        = settings;
        }