You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
13 KiB

  1. using UnityEngine.Rendering;
  2. namespace UnityEngine.PostProcessing
  3. {
  4. using SSRResolution = ScreenSpaceReflectionModel.SSRResolution;
  5. using SSRReflectionBlendType = ScreenSpaceReflectionModel.SSRReflectionBlendType;
  6. public sealed class ScreenSpaceReflectionComponent : PostProcessingComponentCommandBuffer<ScreenSpaceReflectionModel>
  7. {
  8. static class Uniforms
  9. {
  10. internal static readonly int _RayStepSize = Shader.PropertyToID("_RayStepSize");
  11. internal static readonly int _AdditiveReflection = Shader.PropertyToID("_AdditiveReflection");
  12. internal static readonly int _BilateralUpsampling = Shader.PropertyToID("_BilateralUpsampling");
  13. internal static readonly int _TreatBackfaceHitAsMiss = Shader.PropertyToID("_TreatBackfaceHitAsMiss");
  14. internal static readonly int _AllowBackwardsRays = Shader.PropertyToID("_AllowBackwardsRays");
  15. internal static readonly int _TraceBehindObjects = Shader.PropertyToID("_TraceBehindObjects");
  16. internal static readonly int _MaxSteps = Shader.PropertyToID("_MaxSteps");
  17. internal static readonly int _FullResolutionFiltering = Shader.PropertyToID("_FullResolutionFiltering");
  18. internal static readonly int _HalfResolution = Shader.PropertyToID("_HalfResolution");
  19. internal static readonly int _HighlightSuppression = Shader.PropertyToID("_HighlightSuppression");
  20. internal static readonly int _PixelsPerMeterAtOneMeter = Shader.PropertyToID("_PixelsPerMeterAtOneMeter");
  21. internal static readonly int _ScreenEdgeFading = Shader.PropertyToID("_ScreenEdgeFading");
  22. internal static readonly int _ReflectionBlur = Shader.PropertyToID("_ReflectionBlur");
  23. internal static readonly int _MaxRayTraceDistance = Shader.PropertyToID("_MaxRayTraceDistance");
  24. internal static readonly int _FadeDistance = Shader.PropertyToID("_FadeDistance");
  25. internal static readonly int _LayerThickness = Shader.PropertyToID("_LayerThickness");
  26. internal static readonly int _SSRMultiplier = Shader.PropertyToID("_SSRMultiplier");
  27. internal static readonly int _FresnelFade = Shader.PropertyToID("_FresnelFade");
  28. internal static readonly int _FresnelFadePower = Shader.PropertyToID("_FresnelFadePower");
  29. internal static readonly int _ReflectionBufferSize = Shader.PropertyToID("_ReflectionBufferSize");
  30. internal static readonly int _ScreenSize = Shader.PropertyToID("_ScreenSize");
  31. internal static readonly int _InvScreenSize = Shader.PropertyToID("_InvScreenSize");
  32. internal static readonly int _ProjInfo = Shader.PropertyToID("_ProjInfo");
  33. internal static readonly int _CameraClipInfo = Shader.PropertyToID("_CameraClipInfo");
  34. internal static readonly int _ProjectToPixelMatrix = Shader.PropertyToID("_ProjectToPixelMatrix");
  35. internal static readonly int _WorldToCameraMatrix = Shader.PropertyToID("_WorldToCameraMatrix");
  36. internal static readonly int _CameraToWorldMatrix = Shader.PropertyToID("_CameraToWorldMatrix");
  37. internal static readonly int _Axis = Shader.PropertyToID("_Axis");
  38. internal static readonly int _CurrentMipLevel = Shader.PropertyToID("_CurrentMipLevel");
  39. internal static readonly int _NormalAndRoughnessTexture = Shader.PropertyToID("_NormalAndRoughnessTexture");
  40. internal static readonly int _HitPointTexture = Shader.PropertyToID("_HitPointTexture");
  41. internal static readonly int _BlurTexture = Shader.PropertyToID("_BlurTexture");
  42. internal static readonly int _FilteredReflections = Shader.PropertyToID("_FilteredReflections");
  43. internal static readonly int _FinalReflectionTexture = Shader.PropertyToID("_FinalReflectionTexture");
  44. internal static readonly int _TempTexture = Shader.PropertyToID("_TempTexture");
  45. }
  46. // Unexposed variables
  47. bool k_HighlightSuppression = false;
  48. bool k_TraceBehindObjects = true;
  49. bool k_TreatBackfaceHitAsMiss = false;
  50. bool k_BilateralUpsample = true;
  51. enum PassIndex
  52. {
  53. RayTraceStep = 0,
  54. CompositeFinal = 1,
  55. Blur = 2,
  56. CompositeSSR = 3,
  57. MinMipGeneration = 4,
  58. HitPointToReflections = 5,
  59. BilateralKeyPack = 6,
  60. BlitDepthAsCSZ = 7,
  61. PoissonBlur = 8,
  62. }
  63. readonly int[] m_ReflectionTextures = new int[5];
  64. // Not really needed as SSR only works in deferred right now
  65. public override DepthTextureMode GetCameraFlags()
  66. {
  67. return DepthTextureMode.Depth;
  68. }
  69. public override bool active
  70. {
  71. get
  72. {
  73. return model.enabled
  74. && context.isGBufferAvailable
  75. && !context.interrupted;
  76. }
  77. }
  78. public override void OnEnable()
  79. {
  80. m_ReflectionTextures[0] = Shader.PropertyToID("_ReflectionTexture0");
  81. m_ReflectionTextures[1] = Shader.PropertyToID("_ReflectionTexture1");
  82. m_ReflectionTextures[2] = Shader.PropertyToID("_ReflectionTexture2");
  83. m_ReflectionTextures[3] = Shader.PropertyToID("_ReflectionTexture3");
  84. m_ReflectionTextures[4] = Shader.PropertyToID("_ReflectionTexture4");
  85. }
  86. public override string GetName()
  87. {
  88. return "Screen Space Reflection";
  89. }
  90. public override CameraEvent GetCameraEvent()
  91. {
  92. return CameraEvent.AfterFinalPass;
  93. }
  94. public override void PopulateCommandBuffer(CommandBuffer cb)
  95. {
  96. var settings = model.settings;
  97. var camera = context.camera;
  98. // Material setup
  99. int downsampleAmount = (settings.reflection.reflectionQuality == SSRResolution.High) ? 1 : 2;
  100. var rtW = context.width / downsampleAmount;
  101. var rtH = context.height / downsampleAmount;
  102. float sWidth = context.width;
  103. float sHeight = context.height;
  104. float sx = sWidth / 2f;
  105. float sy = sHeight / 2f;
  106. var material = context.materialFactory.Get("Hidden/Post FX/Screen Space Reflection");
  107. material.SetInt(Uniforms._RayStepSize, settings.reflection.stepSize);
  108. material.SetInt(Uniforms._AdditiveReflection, settings.reflection.blendType == SSRReflectionBlendType.Additive ? 1 : 0);
  109. material.SetInt(Uniforms._BilateralUpsampling, k_BilateralUpsample ? 1 : 0);
  110. material.SetInt(Uniforms._TreatBackfaceHitAsMiss, k_TreatBackfaceHitAsMiss ? 1 : 0);
  111. material.SetInt(Uniforms._AllowBackwardsRays, settings.reflection.reflectBackfaces ? 1 : 0);
  112. material.SetInt(Uniforms._TraceBehindObjects, k_TraceBehindObjects ? 1 : 0);
  113. material.SetInt(Uniforms._MaxSteps, settings.reflection.iterationCount);
  114. material.SetInt(Uniforms._FullResolutionFiltering, 0);
  115. material.SetInt(Uniforms._HalfResolution, (settings.reflection.reflectionQuality != SSRResolution.High) ? 1 : 0);
  116. material.SetInt(Uniforms._HighlightSuppression, k_HighlightSuppression ? 1 : 0);
  117. // The height in pixels of a 1m object if viewed from 1m away.
  118. float pixelsPerMeterAtOneMeter = sWidth / (-2f * Mathf.Tan(camera.fieldOfView / 180f * Mathf.PI * 0.5f));
  119. material.SetFloat(Uniforms._PixelsPerMeterAtOneMeter, pixelsPerMeterAtOneMeter);
  120. material.SetFloat(Uniforms._ScreenEdgeFading, settings.screenEdgeMask.intensity);
  121. material.SetFloat(Uniforms._ReflectionBlur, settings.reflection.reflectionBlur);
  122. material.SetFloat(Uniforms._MaxRayTraceDistance, settings.reflection.maxDistance);
  123. material.SetFloat(Uniforms._FadeDistance, settings.intensity.fadeDistance);
  124. material.SetFloat(Uniforms._LayerThickness, settings.reflection.widthModifier);
  125. material.SetFloat(Uniforms._SSRMultiplier, settings.intensity.reflectionMultiplier);
  126. material.SetFloat(Uniforms._FresnelFade, settings.intensity.fresnelFade);
  127. material.SetFloat(Uniforms._FresnelFadePower, settings.intensity.fresnelFadePower);
  128. var P = camera.projectionMatrix;
  129. var projInfo = new Vector4(
  130. -2f / (sWidth * P[0]),
  131. -2f / (sHeight * P[5]),
  132. (1f - P[2]) / P[0],
  133. (1f + P[6]) / P[5]
  134. );
  135. var cameraClipInfo = float.IsPositiveInfinity(camera.farClipPlane) ?
  136. new Vector3(camera.nearClipPlane, -1f, 1f) :
  137. new Vector3(camera.nearClipPlane * camera.farClipPlane, camera.nearClipPlane - camera.farClipPlane, camera.farClipPlane);
  138. material.SetVector(Uniforms._ReflectionBufferSize, new Vector2(rtW, rtH));
  139. material.SetVector(Uniforms._ScreenSize, new Vector2(sWidth, sHeight));
  140. material.SetVector(Uniforms._InvScreenSize, new Vector2(1f / sWidth, 1f / sHeight));
  141. material.SetVector(Uniforms._ProjInfo, projInfo); // used for unprojection
  142. material.SetVector(Uniforms._CameraClipInfo, cameraClipInfo);
  143. var warpToScreenSpaceMatrix = new Matrix4x4();
  144. warpToScreenSpaceMatrix.SetRow(0, new Vector4(sx, 0f, 0f, sx));
  145. warpToScreenSpaceMatrix.SetRow(1, new Vector4(0f, sy, 0f, sy));
  146. warpToScreenSpaceMatrix.SetRow(2, new Vector4(0f, 0f, 1f, 0f));
  147. warpToScreenSpaceMatrix.SetRow(3, new Vector4(0f, 0f, 0f, 1f));
  148. var projectToPixelMatrix = warpToScreenSpaceMatrix * P;
  149. material.SetMatrix(Uniforms._ProjectToPixelMatrix, projectToPixelMatrix);
  150. material.SetMatrix(Uniforms._WorldToCameraMatrix, camera.worldToCameraMatrix);
  151. material.SetMatrix(Uniforms._CameraToWorldMatrix, camera.worldToCameraMatrix.inverse);
  152. // Command buffer setup
  153. var intermediateFormat = context.isHdr ? RenderTextureFormat.ARGBHalf : RenderTextureFormat.ARGB32;
  154. const int maxMip = 5;
  155. var kNormalAndRoughnessTexture = Uniforms._NormalAndRoughnessTexture;
  156. var kHitPointTexture = Uniforms._HitPointTexture;
  157. var kBlurTexture = Uniforms._BlurTexture;
  158. var kFilteredReflections = Uniforms._FilteredReflections;
  159. var kFinalReflectionTexture = Uniforms._FinalReflectionTexture;
  160. var kTempTexture = Uniforms._TempTexture;
  161. // RGB: Normals, A: Roughness.
  162. // Has the nice benefit of allowing us to control the filtering mode as well.
  163. cb.GetTemporaryRT(kNormalAndRoughnessTexture, -1, -1, 0, FilterMode.Point, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
  164. cb.GetTemporaryRT(kHitPointTexture, rtW, rtH, 0, FilterMode.Bilinear, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Linear);
  165. for (int i = 0; i < maxMip; ++i)
  166. {
  167. // We explicitly interpolate during bilateral upsampling.
  168. cb.GetTemporaryRT(m_ReflectionTextures[i], rtW >> i, rtH >> i, 0, FilterMode.Bilinear, intermediateFormat);
  169. }
  170. cb.GetTemporaryRT(kFilteredReflections, rtW, rtH, 0, k_BilateralUpsample ? FilterMode.Point : FilterMode.Bilinear, intermediateFormat);
  171. cb.GetTemporaryRT(kFinalReflectionTexture, rtW, rtH, 0, FilterMode.Point, intermediateFormat);
  172. cb.Blit(BuiltinRenderTextureType.CameraTarget, kNormalAndRoughnessTexture, material, (int)PassIndex.BilateralKeyPack);
  173. cb.Blit(BuiltinRenderTextureType.CameraTarget, kHitPointTexture, material, (int)PassIndex.RayTraceStep);
  174. cb.Blit(BuiltinRenderTextureType.CameraTarget, kFilteredReflections, material, (int)PassIndex.HitPointToReflections);
  175. cb.Blit(kFilteredReflections, m_ReflectionTextures[0], material, (int)PassIndex.PoissonBlur);
  176. for (int i = 1; i < maxMip; ++i)
  177. {
  178. int inputTex = m_ReflectionTextures[i - 1];
  179. int lowMip = i;
  180. cb.GetTemporaryRT(kBlurTexture, rtW >> lowMip, rtH >> lowMip, 0, FilterMode.Bilinear, intermediateFormat);
  181. cb.SetGlobalVector(Uniforms._Axis, new Vector4(1.0f, 0.0f, 0.0f, 0.0f));
  182. cb.SetGlobalFloat(Uniforms._CurrentMipLevel, i - 1.0f);
  183. cb.Blit(inputTex, kBlurTexture, material, (int)PassIndex.Blur);
  184. cb.SetGlobalVector(Uniforms._Axis, new Vector4(0.0f, 1.0f, 0.0f, 0.0f));
  185. inputTex = m_ReflectionTextures[i];
  186. cb.Blit(kBlurTexture, inputTex, material, (int)PassIndex.Blur);
  187. cb.ReleaseTemporaryRT(kBlurTexture);
  188. }
  189. cb.Blit(m_ReflectionTextures[0], kFinalReflectionTexture, material, (int)PassIndex.CompositeSSR);
  190. cb.GetTemporaryRT(kTempTexture, camera.pixelWidth, camera.pixelHeight, 0, FilterMode.Bilinear, intermediateFormat);
  191. cb.Blit(BuiltinRenderTextureType.CameraTarget, kTempTexture, material, (int)PassIndex.CompositeFinal);
  192. cb.Blit(kTempTexture, BuiltinRenderTextureType.CameraTarget);
  193. cb.ReleaseTemporaryRT(kTempTexture);
  194. }
  195. }
  196. }