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 }
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)); }
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; }