123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- using UnityEngine.Rendering;
- namespace UnityEngine.PostProcessing
- {
- using SSRResolution = ScreenSpaceReflectionModel.SSRResolution;
- using SSRReflectionBlendType = ScreenSpaceReflectionModel.SSRReflectionBlendType;
- public sealed class ScreenSpaceReflectionComponent : PostProcessingComponentCommandBuffer<ScreenSpaceReflectionModel>
- {
- static class Uniforms
- {
- internal static readonly int _RayStepSize = Shader.PropertyToID("_RayStepSize");
- internal static readonly int _AdditiveReflection = Shader.PropertyToID("_AdditiveReflection");
- internal static readonly int _BilateralUpsampling = Shader.PropertyToID("_BilateralUpsampling");
- internal static readonly int _TreatBackfaceHitAsMiss = Shader.PropertyToID("_TreatBackfaceHitAsMiss");
- internal static readonly int _AllowBackwardsRays = Shader.PropertyToID("_AllowBackwardsRays");
- internal static readonly int _TraceBehindObjects = Shader.PropertyToID("_TraceBehindObjects");
- internal static readonly int _MaxSteps = Shader.PropertyToID("_MaxSteps");
- internal static readonly int _FullResolutionFiltering = Shader.PropertyToID("_FullResolutionFiltering");
- internal static readonly int _HalfResolution = Shader.PropertyToID("_HalfResolution");
- internal static readonly int _HighlightSuppression = Shader.PropertyToID("_HighlightSuppression");
- internal static readonly int _PixelsPerMeterAtOneMeter = Shader.PropertyToID("_PixelsPerMeterAtOneMeter");
- internal static readonly int _ScreenEdgeFading = Shader.PropertyToID("_ScreenEdgeFading");
- internal static readonly int _ReflectionBlur = Shader.PropertyToID("_ReflectionBlur");
- internal static readonly int _MaxRayTraceDistance = Shader.PropertyToID("_MaxRayTraceDistance");
- internal static readonly int _FadeDistance = Shader.PropertyToID("_FadeDistance");
- internal static readonly int _LayerThickness = Shader.PropertyToID("_LayerThickness");
- internal static readonly int _SSRMultiplier = Shader.PropertyToID("_SSRMultiplier");
- internal static readonly int _FresnelFade = Shader.PropertyToID("_FresnelFade");
- internal static readonly int _FresnelFadePower = Shader.PropertyToID("_FresnelFadePower");
- internal static readonly int _ReflectionBufferSize = Shader.PropertyToID("_ReflectionBufferSize");
- internal static readonly int _ScreenSize = Shader.PropertyToID("_ScreenSize");
- internal static readonly int _InvScreenSize = Shader.PropertyToID("_InvScreenSize");
- internal static readonly int _ProjInfo = Shader.PropertyToID("_ProjInfo");
- internal static readonly int _CameraClipInfo = Shader.PropertyToID("_CameraClipInfo");
- internal static readonly int _ProjectToPixelMatrix = Shader.PropertyToID("_ProjectToPixelMatrix");
- internal static readonly int _WorldToCameraMatrix = Shader.PropertyToID("_WorldToCameraMatrix");
- internal static readonly int _CameraToWorldMatrix = Shader.PropertyToID("_CameraToWorldMatrix");
- internal static readonly int _Axis = Shader.PropertyToID("_Axis");
- internal static readonly int _CurrentMipLevel = Shader.PropertyToID("_CurrentMipLevel");
- internal static readonly int _NormalAndRoughnessTexture = Shader.PropertyToID("_NormalAndRoughnessTexture");
- internal static readonly int _HitPointTexture = Shader.PropertyToID("_HitPointTexture");
- internal static readonly int _BlurTexture = Shader.PropertyToID("_BlurTexture");
- internal static readonly int _FilteredReflections = Shader.PropertyToID("_FilteredReflections");
- internal static readonly int _FinalReflectionTexture = Shader.PropertyToID("_FinalReflectionTexture");
- internal static readonly int _TempTexture = Shader.PropertyToID("_TempTexture");
- }
- // Unexposed variables
- bool k_HighlightSuppression = false;
- bool k_TraceBehindObjects = true;
- bool k_TreatBackfaceHitAsMiss = false;
- bool k_BilateralUpsample = true;
- enum PassIndex
- {
- RayTraceStep = 0,
- CompositeFinal = 1,
- Blur = 2,
- CompositeSSR = 3,
- MinMipGeneration = 4,
- HitPointToReflections = 5,
- BilateralKeyPack = 6,
- BlitDepthAsCSZ = 7,
- PoissonBlur = 8,
- }
- readonly int[] m_ReflectionTextures = new int[5];
- // Not really needed as SSR only works in deferred right now
- public override DepthTextureMode GetCameraFlags()
- {
- return DepthTextureMode.Depth;
- }
- public override bool active
- {
- get
- {
- return model.enabled
- && context.isGBufferAvailable
- && !context.interrupted;
- }
- }
- public override void OnEnable()
- {
- m_ReflectionTextures[0] = Shader.PropertyToID("_ReflectionTexture0");
- m_ReflectionTextures[1] = Shader.PropertyToID("_ReflectionTexture1");
- m_ReflectionTextures[2] = Shader.PropertyToID("_ReflectionTexture2");
- m_ReflectionTextures[3] = Shader.PropertyToID("_ReflectionTexture3");
- m_ReflectionTextures[4] = Shader.PropertyToID("_ReflectionTexture4");
- }
- public override string GetName()
- {
- return "Screen Space Reflection";
- }
- public override CameraEvent GetCameraEvent()
- {
- return CameraEvent.AfterFinalPass;
- }
- public override void PopulateCommandBuffer(CommandBuffer cb)
- {
- var settings = model.settings;
- var camera = context.camera;
- // Material setup
- int downsampleAmount = (settings.reflection.reflectionQuality == SSRResolution.High) ? 1 : 2;
- var rtW = context.width / downsampleAmount;
- var rtH = context.height / downsampleAmount;
- float sWidth = context.width;
- float sHeight = context.height;
- float sx = sWidth / 2f;
- float sy = sHeight / 2f;
- var material = context.materialFactory.Get("Hidden/Post FX/Screen Space Reflection");
- material.SetInt(Uniforms._RayStepSize, settings.reflection.stepSize);
- material.SetInt(Uniforms._AdditiveReflection, settings.reflection.blendType == SSRReflectionBlendType.Additive ? 1 : 0);
- material.SetInt(Uniforms._BilateralUpsampling, k_BilateralUpsample ? 1 : 0);
- material.SetInt(Uniforms._TreatBackfaceHitAsMiss, k_TreatBackfaceHitAsMiss ? 1 : 0);
- material.SetInt(Uniforms._AllowBackwardsRays, settings.reflection.reflectBackfaces ? 1 : 0);
- material.SetInt(Uniforms._TraceBehindObjects, k_TraceBehindObjects ? 1 : 0);
- material.SetInt(Uniforms._MaxSteps, settings.reflection.iterationCount);
- material.SetInt(Uniforms._FullResolutionFiltering, 0);
- material.SetInt(Uniforms._HalfResolution, (settings.reflection.reflectionQuality != SSRResolution.High) ? 1 : 0);
- material.SetInt(Uniforms._HighlightSuppression, k_HighlightSuppression ? 1 : 0);
- // The height in pixels of a 1m object if viewed from 1m away.
- float pixelsPerMeterAtOneMeter = sWidth / (-2f * Mathf.Tan(camera.fieldOfView / 180f * Mathf.PI * 0.5f));
- material.SetFloat(Uniforms._PixelsPerMeterAtOneMeter, pixelsPerMeterAtOneMeter);
- material.SetFloat(Uniforms._ScreenEdgeFading, settings.screenEdgeMask.intensity);
- material.SetFloat(Uniforms._ReflectionBlur, settings.reflection.reflectionBlur);
- material.SetFloat(Uniforms._MaxRayTraceDistance, settings.reflection.maxDistance);
- material.SetFloat(Uniforms._FadeDistance, settings.intensity.fadeDistance);
- material.SetFloat(Uniforms._LayerThickness, settings.reflection.widthModifier);
- material.SetFloat(Uniforms._SSRMultiplier, settings.intensity.reflectionMultiplier);
- material.SetFloat(Uniforms._FresnelFade, settings.intensity.fresnelFade);
- material.SetFloat(Uniforms._FresnelFadePower, settings.intensity.fresnelFadePower);
- var P = camera.projectionMatrix;
- var projInfo = new Vector4(
- -2f / (sWidth * P[0]),
- -2f / (sHeight * P[5]),
- (1f - P[2]) / P[0],
- (1f + P[6]) / P[5]
- );
- var cameraClipInfo = float.IsPositiveInfinity(camera.farClipPlane) ?
- new Vector3(camera.nearClipPlane, -1f, 1f) :
- new Vector3(camera.nearClipPlane * camera.farClipPlane, camera.nearClipPlane - camera.farClipPlane, camera.farClipPlane);
- material.SetVector(Uniforms._ReflectionBufferSize, new Vector2(rtW, rtH));
- material.SetVector(Uniforms._ScreenSize, new Vector2(sWidth, sHeight));
- material.SetVector(Uniforms._InvScreenSize, new Vector2(1f / sWidth, 1f / sHeight));
- material.SetVector(Uniforms._ProjInfo, projInfo); // used for unprojection
- material.SetVector(Uniforms._CameraClipInfo, cameraClipInfo);
- var warpToScreenSpaceMatrix = new Matrix4x4();
- warpToScreenSpaceMatrix.SetRow(0, new Vector4(sx, 0f, 0f, sx));
- warpToScreenSpaceMatrix.SetRow(1, new Vector4(0f, sy, 0f, sy));
- warpToScreenSpaceMatrix.SetRow(2, new Vector4(0f, 0f, 1f, 0f));
- warpToScreenSpaceMatrix.SetRow(3, new Vector4(0f, 0f, 0f, 1f));
- var projectToPixelMatrix = warpToScreenSpaceMatrix * P;
- material.SetMatrix(Uniforms._ProjectToPixelMatrix, projectToPixelMatrix);
- material.SetMatrix(Uniforms._WorldToCameraMatrix, camera.worldToCameraMatrix);
- material.SetMatrix(Uniforms._CameraToWorldMatrix, camera.worldToCameraMatrix.inverse);
- // Command buffer setup
- var intermediateFormat = context.isHdr ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32;
- const int maxMip = 5;
- var kNormalAndRoughnessTexture = Uniforms._NormalAndRoughnessTexture;
- var kHitPointTexture = Uniforms._HitPointTexture;
- var kBlurTexture = Uniforms._BlurTexture;
- var kFilteredReflections = Uniforms._FilteredReflections;
- var kFinalReflectionTexture = Uniforms._FinalReflectionTexture;
- var kTempTexture = Uniforms._TempTexture;
- // RGB: Normals, A: Roughness.
- // Has the nice benefit of allowing us to control the filtering mode as well.
- cb.GetTemporaryRT(kNormalAndRoughnessTexture, -1, -1, 0, FilterMode.Point, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
- cb.GetTemporaryRT(kHitPointTexture, rtW, rtH, 0, FilterMode.Bilinear, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
- for (int i = 0; i < maxMip; ++i)
- {
- // We explicitly interpolate during bilateral upsampling.
- cb.GetTemporaryRT(m_ReflectionTextures[i], rtW >> i, rtH >> i, 0, FilterMode.Bilinear, intermediateFormat);
- }
- cb.GetTemporaryRT(kFilteredReflections, rtW, rtH, 0, k_BilateralUpsample ? FilterMode.Point : FilterMode.Bilinear, intermediateFormat);
- cb.GetTemporaryRT(kFinalReflectionTexture, rtW, rtH, 0, FilterMode.Point, intermediateFormat);
- cb.Blit(BuiltinRenderTextureType.CameraTarget, kNormalAndRoughnessTexture, material, (int)PassIndex.BilateralKeyPack);
- cb.Blit(BuiltinRenderTextureType.CameraTarget, kHitPointTexture, material, (int)PassIndex.RayTraceStep);
- cb.Blit(BuiltinRenderTextureType.CameraTarget, kFilteredReflections, material, (int)PassIndex.HitPointToReflections);
- cb.Blit(kFilteredReflections, m_ReflectionTextures[0], material, (int)PassIndex.PoissonBlur);
- for (int i = 1; i < maxMip; ++i)
- {
- int inputTex = m_ReflectionTextures[i - 1];
- int lowMip = i;
- cb.GetTemporaryRT(kBlurTexture, rtW >> lowMip, rtH >> lowMip, 0, FilterMode.Bilinear, intermediateFormat);
- cb.SetGlobalVector(Uniforms._Axis, new Vector4(1.0f, 0.0f, 0.0f, 0.0f));
- cb.SetGlobalFloat(Uniforms._CurrentMipLevel, i - 1.0f);
- cb.Blit(inputTex, kBlurTexture, material, (int)PassIndex.Blur);
- cb.SetGlobalVector(Uniforms._Axis, new Vector4(0.0f, 1.0f, 0.0f, 0.0f));
- inputTex = m_ReflectionTextures[i];
- cb.Blit(kBlurTexture, inputTex, material, (int)PassIndex.Blur);
- cb.ReleaseTemporaryRT(kBlurTexture);
- }
- cb.Blit(m_ReflectionTextures[0], kFinalReflectionTexture, material, (int)PassIndex.CompositeSSR);
- cb.GetTemporaryRT(kTempTexture, camera.pixelWidth, camera.pixelHeight, 0, FilterMode.Bilinear, intermediateFormat);
- cb.Blit(BuiltinRenderTextureType.CameraTarget, kTempTexture, material, (int)PassIndex.CompositeFinal);
- cb.Blit(kTempTexture, BuiltinRenderTextureType.CameraTarget);
- cb.ReleaseTemporaryRT(kTempTexture);
- }
- }
- }
|