public override void Render(PostProcessRenderContext context)
        {
            PropertySheet sheet = context.propertySheets.Get(shader);
            CommandBuffer cmd   = context.command;

            Camera cam = context.camera;

            #region Skybox sampling
            //Add the skybox rendering component to any camera rendering Fog
            if (settings.colorSource.value == Fog.FogColorSource.SkyboxColor)
            {
                //Ignore hidden camera's, except scene-view cam
                if (cam.hideFlags != HideFlags.None && cam.name != "SceneCamera")
                {
                    return;
                }

                if (!skyboxCams.ContainsKey(cam))
                {
                    skyboxCams[cam] = cam.gameObject.GetComponent <RenderScreenSpaceSkybox>();

                    if (!skyboxCams[cam])
                    {
                        skyboxCams[cam] = cam.gameObject.AddComponent <RenderScreenSpaceSkybox>();
                    }
                    skyboxCams[cam].manuallyAdded = false; //Don't show warning on component
                }
            }
            #endregion

            //OpenVR.System.GetProjectionMatrix(vrEye, mainCamera.nearClipPlane, mainCamera.farClipPlane, EGraphicsAPIConvention.API_DirectX)

            //Clip-space to world-space camera matrix conversion
            #region Property value composition
            var p = GL.GetGPUProjectionMatrix(cam.projectionMatrix, false);
            p[2, 3] = p[3, 2] = 0.0f;
            p[3, 3] = 1.0f;
            var clipToWorld = Matrix4x4.Inverse(p * cam.worldToCameraMatrix) * Matrix4x4.TRS(new Vector3(0, 0, -p[2, 2]), Quaternion.identity, Vector3.one);
            sheet.properties.SetMatrix("clipToWorld", clipToWorld);

            float FdotC  = cam.transform.position.y - settings.height;
            float paramK = (FdotC <= 0.0f ? 1.0f : 0.0f);
            //Always exclude skybox for skybox color mode
            //Always include when using light scattering to avoid depth discontinuity
            float skyboxInfluence = (settings.lightScattering) ? 1.0f : settings.skyboxInfluence;
            float distanceFog     = (settings.distanceFog) ? 1.0f : 0.0f;
            float heightFog       = (settings.heightFog) ? 1.0f : 0.0f;

            int colorSource  = (settings.useSceneSettings) ? 0 : (int)settings.colorSource.value;
            var sceneMode    = (settings.useSceneSettings) ? RenderSettings.fogMode : settings.fogMode;
            var sceneDensity = (settings.useSceneSettings) ? RenderSettings.fogDensity : settings.globalDensity / 100;
            var sceneStart   = (settings.useSceneSettings) ? RenderSettings.fogStartDistance : settings.fogStartDistance;
            var sceneEnd     = (settings.useSceneSettings) ? RenderSettings.fogEndDistance : settings.fogEndDistance;

            bool  linear  = (sceneMode == FogMode.Linear);
            float diff    = linear ? sceneEnd - sceneStart : 0.0f;
            float invDiff = Mathf.Abs(diff) > 0.0001f ? 1.0f / diff : 0.0f;

            Vector4 sceneParams;
            sceneParams.x = sceneDensity * 1.2011224087f; // density / sqrt(ln(2)), used by Exp2 fog mode
            sceneParams.y = sceneDensity * 1.4426950408f; // density / ln(2), used by Exp fog mode
            sceneParams.z = linear ? -invDiff : 0.0f;
            sceneParams.w = linear ? sceneEnd * invDiff : 0.0f;

            float gradientDistance = (settings.gradientUseFarClipPlane.value) ? settings.gradientDistance : context.camera.farClipPlane;
            #endregion

            #region Property assignment
            if (settings.heightNoiseTex.value)
            {
                sheet.properties.SetTexture("_NoiseTex", settings.heightNoiseTex);
            }
            if (settings.fogColorGradient.value)
            {
                sheet.properties.SetTexture("_ColorGradient", settings.fogColorGradient);
            }
            sheet.properties.SetFloat("_FarClippingPlane", gradientDistance);
            sheet.properties.SetVector("_SceneFogParams", sceneParams);
            sheet.properties.SetVector("_SceneFogMode", new Vector4((int)sceneMode, settings.useRadialDistance ? 1 : 0, colorSource, settings.heightFogNoise ? 1 : 0));
            sheet.properties.SetVector("_NoiseParams", new Vector4(settings.heightNoiseSize * 0.01f, settings.heightNoiseSpeed * 0.01f, settings.heightNoiseStrength, 0));
            sheet.properties.SetVector("_DensityParams", new Vector4(settings.distanceDensity, settings.heightNoiseStrength, settings.skyboxMipLevel, 0));
            sheet.properties.SetVector("_HeightParams", new Vector4(settings.height, FdotC, paramK, settings.heightDensity * 0.5f));
            sheet.properties.SetVector("_DistanceParams", new Vector4(-sceneStart, 0f, distanceFog, heightFog));
            sheet.properties.SetColor("_FogColor", (settings.useSceneSettings) ? RenderSettings.fogColor : settings.fogColor);
            sheet.properties.SetVector("_SkyboxParams", new Vector4(skyboxInfluence, settings.skyboxMipLevel, 0, 0));

            Vector3 sunDir       = (settings.useLightDirection) ? Fog.LightDirection : settings.lightDirection.value.normalized;
            float   sunIntensity = (settings.useLightIntensity) ? FogLightSource.intensity : settings.lightIntensity.value;
            sunIntensity = (settings.enableDirectionalLight) ? sunIntensity : 0f;
            sheet.properties.SetVector("_DirLightParams", new Vector4(sunDir.x, sunDir.y, sunDir.z, sunIntensity));

            Color sunColor = (settings.useLightColor) ? FogLightSource.color : settings.lightColor.value;
            sheet.properties.SetVector("_DirLightColor", new Vector4(sunColor.r, sunColor.g, sunColor.b, 0));

            #endregion

            #region Light scattering
            //Repurpose parts of the bloom effect
            bool enableScattering = (settings.lightScattering) ? true : false;

            if (enableScattering)
            {
                int  tw = Mathf.FloorToInt(context.screenWidth / (2f));
                int  th = Mathf.FloorToInt(context.screenHeight / (2f));
                bool singlePassDoubleWide = (context.stereoActive && (context.stereoRenderingMode == PostProcessRenderContext.StereoRenderingMode.SinglePass) && (context.camera.stereoTargetEye == StereoTargetEyeMask.Both));
                int  tw_stereo            = singlePassDoubleWide ? tw * 2 : tw;

                // Determine the iteration count
                int   s           = Mathf.Max(tw, th);
                float logs        = Mathf.Log(s, 2f) + Mathf.Min(settings.scatterDiffusion.value, 10f) - 10f;
                int   logs_i      = Mathf.FloorToInt(logs);
                int   iterations  = Mathf.Clamp(logs_i, 1, k_MaxPyramidSize);
                float sampleScale = 0.5f + logs - logs_i;
                sheet.properties.SetFloat("_SampleScale", sampleScale);

                // Prefiltering parameters
                float lthresh   = Mathf.GammaToLinearSpace(settings.scatterThreshold.value);
                float knee      = lthresh * settings.scatterSoftKnee.value + 1e-5f;
                var   threshold = new Vector4(lthresh, lthresh - knee, knee * 2f, 0.25f / knee);
                sheet.properties.SetVector("_Threshold", threshold);

                // Downsample
                var lastDown = context.source;
                for (int i = 0; i < iterations; i++)
                {
                    int mipDown = m_Pyramid[i].down;
                    int mipUp   = m_Pyramid[i].up;
                    int pass    = i == 0 ? (int)Pass.Prefilter : (int)Pass.Downsample;

                    context.GetScreenSpaceTemporaryRT(cmd, mipDown, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw_stereo, th);
                    context.GetScreenSpaceTemporaryRT(cmd, mipUp, 0, context.sourceFormat, RenderTextureReadWrite.Default, FilterMode.Bilinear, tw_stereo, th);
                    cmd.BlitFullscreenTriangle(lastDown, mipDown, sheet, pass);

                    lastDown  = mipDown;
                    tw_stereo = (singlePassDoubleWide && ((tw_stereo / 2) % 2 > 0)) ? 1 + tw_stereo / 2 : tw_stereo / 2;
                    tw_stereo = Mathf.Max(tw_stereo, 1);
                    th        = Mathf.Max(th / 2, 1);
                }

                // Upsample
                int lastUp = m_Pyramid[iterations - 1].down;
                for (int i = iterations - 2; i >= 0; i--)
                {
                    int mipDown = m_Pyramid[i].down;
                    int mipUp   = m_Pyramid[i].up;
                    cmd.SetGlobalTexture("_BloomTex", mipDown);
                    cmd.BlitFullscreenTriangle(lastUp, mipUp, sheet, (int)Pass.Upsample);
                    lastUp = mipUp;
                }

                float intensity      = RuntimeUtilities.Exp2(settings.scatterIntensity.value / 10f) - 1f;
                var   shaderSettings = new Vector4(sampleScale, intensity, 0, iterations);
                sheet.properties.SetVector("_ScatteringParams", shaderSettings);

                cmd.SetGlobalTexture("_BloomTex", lastUp);

                // Cleanup
                for (int i = 0; i < iterations; i++)
                {
                    if (m_Pyramid[i].down != lastUp)
                    {
                        cmd.ReleaseTemporaryRT(m_Pyramid[i].down);
                    }
                    if (m_Pyramid[i].up != lastUp)
                    {
                        cmd.ReleaseTemporaryRT(m_Pyramid[i].up);
                    }
                }
            }

            #endregion

            #region shader passes
            context.command.BlitFullscreenTriangle(context.source, context.destination, sheet, enableScattering ? (int)Pass.BlendScattering : (int)Pass.Blend);
            #endregion
        }
Esempio n. 2
0
        private void RenderHDRPipeline2D(PostProcessRenderContext context)
        {
            CheckInternalStripLut();
            PropertySheet propertySheet = context.propertySheets.Get(context.resources.shaders.lut2DBaker);

            propertySheet.ClearKeywords();
            propertySheet.properties.SetVector(ShaderIDs.Lut2D_Params, new Vector4(32f, 0.00048828125f, 0.015625f, 1.032258f));
            Vector3 v = ColorUtilities.ComputeColorBalance(base.settings.temperature.value, base.settings.tint.value);

            propertySheet.properties.SetVector(ShaderIDs.ColorBalance, v);
            propertySheet.properties.SetVector(ShaderIDs.ColorFilter, base.settings.colorFilter.value);
            float x = base.settings.hueShift.value / 360f;
            float y = base.settings.saturation.value / 100f + 1f;
            float z = base.settings.contrast.value / 100f + 1f;

            propertySheet.properties.SetVector(ShaderIDs.HueSatCon, new Vector3(x, y, z));
            Vector3 a  = new Vector3(base.settings.mixerRedOutRedIn, base.settings.mixerRedOutGreenIn, base.settings.mixerRedOutBlueIn);
            Vector3 a2 = new Vector3(base.settings.mixerGreenOutRedIn, base.settings.mixerGreenOutGreenIn, base.settings.mixerGreenOutBlueIn);
            Vector3 a3 = new Vector3(base.settings.mixerBlueOutRedIn, base.settings.mixerBlueOutGreenIn, base.settings.mixerBlueOutBlueIn);

            propertySheet.properties.SetVector(ShaderIDs.ChannelMixerRed, a / 100f);
            propertySheet.properties.SetVector(ShaderIDs.ChannelMixerGreen, a2 / 100f);
            propertySheet.properties.SetVector(ShaderIDs.ChannelMixerBlue, a3 / 100f);
            Vector3 v2 = ColorUtilities.ColorToLift(base.settings.lift.value * 0.2f);
            Vector3 v3 = ColorUtilities.ColorToGain(base.settings.gain.value * 0.8f);
            Vector3 v4 = ColorUtilities.ColorToInverseGamma(base.settings.gamma.value * 0.8f);

            propertySheet.properties.SetVector(ShaderIDs.Lift, v2);
            propertySheet.properties.SetVector(ShaderIDs.InvGamma, v4);
            propertySheet.properties.SetVector(ShaderIDs.Gain, v3);
            propertySheet.properties.SetTexture(ShaderIDs.Curves, GetCurveTexture(hdr: true));
            switch (base.settings.tonemapper.value)
            {
            case Tonemapper.Custom:
                propertySheet.EnableKeyword("TONEMAPPING_CUSTOM");
                m_HableCurve.Init(base.settings.toneCurveToeStrength.value, base.settings.toneCurveToeLength.value, base.settings.toneCurveShoulderStrength.value, base.settings.toneCurveShoulderLength.value, base.settings.toneCurveShoulderAngle.value, base.settings.toneCurveGamma.value);
                propertySheet.properties.SetVector(ShaderIDs.CustomToneCurve, m_HableCurve.uniforms.curve);
                propertySheet.properties.SetVector(ShaderIDs.ToeSegmentA, m_HableCurve.uniforms.toeSegmentA);
                propertySheet.properties.SetVector(ShaderIDs.ToeSegmentB, m_HableCurve.uniforms.toeSegmentB);
                propertySheet.properties.SetVector(ShaderIDs.MidSegmentA, m_HableCurve.uniforms.midSegmentA);
                propertySheet.properties.SetVector(ShaderIDs.MidSegmentB, m_HableCurve.uniforms.midSegmentB);
                propertySheet.properties.SetVector(ShaderIDs.ShoSegmentA, m_HableCurve.uniforms.shoSegmentA);
                propertySheet.properties.SetVector(ShaderIDs.ShoSegmentB, m_HableCurve.uniforms.shoSegmentB);
                break;

            case Tonemapper.ACES:
                propertySheet.EnableKeyword("TONEMAPPING_ACES");
                break;

            case Tonemapper.Neutral:
                propertySheet.EnableKeyword("TONEMAPPING_NEUTRAL");
                break;
            }
            context.command.BeginSample("HdrColorGradingLut2D");
            context.command.BlitFullscreenTriangle(BuiltinRenderTextureType.None, m_InternalLdrLut, propertySheet, 2);
            context.command.EndSample("HdrColorGradingLut2D");
            RenderTexture internalLdrLut = m_InternalLdrLut;
            PropertySheet uberSheet      = context.uberSheet;

            uberSheet.EnableKeyword("COLOR_GRADING_HDR_2D");
            uberSheet.properties.SetVector(ShaderIDs.Lut2D_Params, new Vector3(1f / (float)internalLdrLut.width, 1f / (float)internalLdrLut.height, (float)internalLdrLut.height - 1f));
            uberSheet.properties.SetTexture(ShaderIDs.Lut2D, internalLdrLut);
            uberSheet.properties.SetFloat(ShaderIDs.PostExposure, RuntimeUtilities.Exp2(base.settings.postExposure.value));
        }
Esempio n. 3
0
        private void RenderHDRPipeline3D(PostProcessRenderContext context)
        {
            CheckInternalLogLut();
            ComputeShader lut3DBaker  = context.resources.computeShaders.lut3DBaker;
            int           kernelIndex = 0;

            switch (base.settings.tonemapper.value)
            {
            case Tonemapper.None:
                kernelIndex = lut3DBaker.FindKernel("KGenLut3D_NoTonemap");
                break;

            case Tonemapper.Neutral:
                kernelIndex = lut3DBaker.FindKernel("KGenLut3D_NeutralTonemap");
                break;

            case Tonemapper.ACES:
                kernelIndex = lut3DBaker.FindKernel("KGenLut3D_AcesTonemap");
                break;

            case Tonemapper.Custom:
                kernelIndex = lut3DBaker.FindKernel("KGenLut3D_CustomTonemap");
                break;
            }
            CommandBuffer command = context.command;

            command.SetComputeTextureParam(lut3DBaker, kernelIndex, "_Output", m_InternalLogLut);
            command.SetComputeVectorParam(lut3DBaker, "_Size", new Vector4(33f, 0.03125f, 0f, 0f));
            Vector3 v = ColorUtilities.ComputeColorBalance(base.settings.temperature.value, base.settings.tint.value);

            command.SetComputeVectorParam(lut3DBaker, "_ColorBalance", v);
            command.SetComputeVectorParam(lut3DBaker, "_ColorFilter", base.settings.colorFilter.value);
            float x = base.settings.hueShift.value / 360f;
            float y = base.settings.saturation.value / 100f + 1f;
            float z = base.settings.contrast.value / 100f + 1f;

            command.SetComputeVectorParam(lut3DBaker, "_HueSatCon", new Vector4(x, y, z, 0f));
            Vector4 a  = new Vector4(base.settings.mixerRedOutRedIn, base.settings.mixerRedOutGreenIn, base.settings.mixerRedOutBlueIn, 0f);
            Vector4 a2 = new Vector4(base.settings.mixerGreenOutRedIn, base.settings.mixerGreenOutGreenIn, base.settings.mixerGreenOutBlueIn, 0f);
            Vector4 a3 = new Vector4(base.settings.mixerBlueOutRedIn, base.settings.mixerBlueOutGreenIn, base.settings.mixerBlueOutBlueIn, 0f);

            command.SetComputeVectorParam(lut3DBaker, "_ChannelMixerRed", a / 100f);
            command.SetComputeVectorParam(lut3DBaker, "_ChannelMixerGreen", a2 / 100f);
            command.SetComputeVectorParam(lut3DBaker, "_ChannelMixerBlue", a3 / 100f);
            Vector3 vector  = ColorUtilities.ColorToLift(base.settings.lift.value * 0.2f);
            Vector3 vector2 = ColorUtilities.ColorToGain(base.settings.gain.value * 0.8f);
            Vector3 vector3 = ColorUtilities.ColorToInverseGamma(base.settings.gamma.value * 0.8f);

            command.SetComputeVectorParam(lut3DBaker, "_Lift", new Vector4(vector.x, vector.y, vector.z, 0f));
            command.SetComputeVectorParam(lut3DBaker, "_InvGamma", new Vector4(vector3.x, vector3.y, vector3.z, 0f));
            command.SetComputeVectorParam(lut3DBaker, "_Gain", new Vector4(vector2.x, vector2.y, vector2.z, 0f));
            command.SetComputeTextureParam(lut3DBaker, kernelIndex, "_Curves", GetCurveTexture(hdr: true));
            if (base.settings.tonemapper.value == Tonemapper.Custom)
            {
                m_HableCurve.Init(base.settings.toneCurveToeStrength.value, base.settings.toneCurveToeLength.value, base.settings.toneCurveShoulderStrength.value, base.settings.toneCurveShoulderLength.value, base.settings.toneCurveShoulderAngle.value, base.settings.toneCurveGamma.value);
                command.SetComputeVectorParam(lut3DBaker, "_CustomToneCurve", m_HableCurve.uniforms.curve);
                command.SetComputeVectorParam(lut3DBaker, "_ToeSegmentA", m_HableCurve.uniforms.toeSegmentA);
                command.SetComputeVectorParam(lut3DBaker, "_ToeSegmentB", m_HableCurve.uniforms.toeSegmentB);
                command.SetComputeVectorParam(lut3DBaker, "_MidSegmentA", m_HableCurve.uniforms.midSegmentA);
                command.SetComputeVectorParam(lut3DBaker, "_MidSegmentB", m_HableCurve.uniforms.midSegmentB);
                command.SetComputeVectorParam(lut3DBaker, "_ShoSegmentA", m_HableCurve.uniforms.shoSegmentA);
                command.SetComputeVectorParam(lut3DBaker, "_ShoSegmentB", m_HableCurve.uniforms.shoSegmentB);
            }
            context.command.BeginSample("HdrColorGradingLut3D");
            int num = Mathf.CeilToInt(8.25f);

            command.DispatchCompute(lut3DBaker, kernelIndex, num, num, num);
            context.command.EndSample("HdrColorGradingLut3D");
            RenderTexture internalLogLut = m_InternalLogLut;
            PropertySheet uberSheet      = context.uberSheet;

            uberSheet.EnableKeyword("COLOR_GRADING_HDR_3D");
            uberSheet.properties.SetTexture(ShaderIDs.Lut3D, internalLogLut);
            uberSheet.properties.SetVector(ShaderIDs.Lut3D_Params, new Vector2(1f / (float)internalLogLut.width, (float)internalLogLut.width - 1f));
            uberSheet.properties.SetFloat(ShaderIDs.PostExposure, RuntimeUtilities.Exp2(base.settings.postExposure.value));
            context.logLut = internalLogLut;
        }
        public override void Render(PostProcessRenderContext context)
        {
            CommandBuffer command = context.command;

            command.BeginSample("AutoExposureLookup");
            CheckTexture(context.xrActiveEye, 0);
            CheckTexture(context.xrActiveEye, 1);
            float x = base.settings.filtering.value.x;
            float y = base.settings.filtering.value.y;

            y = Mathf.Clamp(y, 1.01f, 99f);
            x = Mathf.Clamp(x, 1f, y - 0.01f);
            float value  = base.settings.minLuminance.value;
            float value2 = base.settings.maxLuminance.value;

            base.settings.minLuminance.value = Mathf.Min(value, value2);
            base.settings.maxLuminance.value = Mathf.Max(value, value2);
            bool   flag = m_ResetHistory || !Application.isPlaying;
            string text = null;

            text = ((!flag && base.settings.eyeAdaptation.value != EyeAdaptation.Fixed) ? "KAutoExposureAvgLuminance_progressive" : "KAutoExposureAvgLuminance_fixed");
            ComputeShader autoExposure = context.resources.computeShaders.autoExposure;
            int           kernelIndex  = autoExposure.FindKernel(text);

            command.SetComputeBufferParam(autoExposure, kernelIndex, "_HistogramBuffer", context.logHistogram.data);
            command.SetComputeVectorParam(autoExposure, "_Params1", new Vector4(x * 0.01f, y * 0.01f, RuntimeUtilities.Exp2(base.settings.minLuminance.value), RuntimeUtilities.Exp2(base.settings.maxLuminance.value)));
            command.SetComputeVectorParam(autoExposure, "_Params2", new Vector4(base.settings.speedDown.value, base.settings.speedUp.value, base.settings.keyValue.value, Time.deltaTime));
            command.SetComputeVectorParam(autoExposure, "_ScaleOffsetRes", context.logHistogram.GetHistogramScaleOffsetRes(context));
            if (flag)
            {
                m_CurrentAutoExposure = m_AutoExposurePool[context.xrActiveEye][0];
                command.SetComputeTextureParam(autoExposure, kernelIndex, "_Destination", m_CurrentAutoExposure);
                command.DispatchCompute(autoExposure, kernelIndex, 1, 1, 1);
                RuntimeUtilities.CopyTexture(command, m_AutoExposurePool[context.xrActiveEye][0], m_AutoExposurePool[context.xrActiveEye][1]);
                m_ResetHistory = false;
            }
            else
            {
                int           num           = m_AutoExposurePingPong[context.xrActiveEye];
                RenderTexture tex           = m_AutoExposurePool[context.xrActiveEye][++num % 2];
                RenderTexture renderTexture = m_AutoExposurePool[context.xrActiveEye][++num % 2];
                command.SetComputeTextureParam(autoExposure, kernelIndex, "_Source", tex);
                command.SetComputeTextureParam(autoExposure, kernelIndex, "_Destination", renderTexture);
                command.DispatchCompute(autoExposure, kernelIndex, 1, 1, 1);
                m_AutoExposurePingPong[context.xrActiveEye] = ++num % 2;
                m_CurrentAutoExposure = renderTexture;
            }
            command.EndSample("AutoExposureLookup");
            context.autoExposureTexture = m_CurrentAutoExposure;
            context.autoExposure        = base.settings;
        }