暫無描述
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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. Shader "Hidden/Universal Render Pipeline/Bloom"
  2. {
  3. HLSLINCLUDE
  4. #pragma multi_compile_local _ _USE_RGBM
  5. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
  6. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Filtering.hlsl"
  7. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
  8. #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
  9. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DynamicScalingClamping.hlsl"
  10. #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/UnityInput.hlsl"
  11. #include_with_pragmas "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRenderingKeywords.hlsl"
  12. #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/FoveatedRendering.hlsl"
  13. TEXTURE2D_X(_SourceTexLowMip);
  14. float4 _SourceTexLowMip_TexelSize;
  15. float4 _Params; // x: scatter, y: clamp, z: threshold (linear), w: threshold knee
  16. #define Scatter _Params.x
  17. #define ClampMax _Params.y
  18. #define Threshold _Params.z
  19. #define ThresholdKnee _Params.w
  20. half4 EncodeHDR(half3 color)
  21. {
  22. #if _USE_RGBM
  23. half4 outColor = EncodeRGBM(color);
  24. #else
  25. half4 outColor = half4(color, 1.0);
  26. #endif
  27. #if UNITY_COLORSPACE_GAMMA
  28. return half4(sqrt(outColor.xyz), outColor.w); // linear to γ
  29. #else
  30. return outColor;
  31. #endif
  32. }
  33. half3 DecodeHDR(half4 color)
  34. {
  35. #if UNITY_COLORSPACE_GAMMA
  36. color.xyz *= color.xyz; // γ to linear
  37. #endif
  38. #if _USE_RGBM
  39. return DecodeRGBM(color);
  40. #else
  41. return color.xyz;
  42. #endif
  43. }
  44. half3 SamplePrefilter(float2 uv, float2 offset)
  45. {
  46. float2 texelSize = _BlitTexture_TexelSize.xy;
  47. half4 color = SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv + texelSize * offset);
  48. #if _ENABLE_ALPHA_OUTPUT
  49. // When alpha is enabled, regions with zero alpha should not generate any bloom / glow. Therefore we pre-multipy the color with the alpha channel here and the rest
  50. // of the computations remain float3. Still, when bloom is applied to the final image, bloom will still be spread on regions with zero alpha (see UberPost.compute)
  51. color.xyz *= color.w;
  52. #endif
  53. return color.xyz;
  54. }
  55. half4 FragPrefilter(Varyings input) : SV_Target
  56. {
  57. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  58. float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
  59. #if defined(SUPPORTS_FOVEATED_RENDERING_NON_UNIFORM_RASTER)
  60. UNITY_BRANCH if (_FOVEATED_RENDERING_NON_UNIFORM_RASTER)
  61. {
  62. uv = RemapFoveatedRenderingLinearToNonUniform(uv);
  63. }
  64. #endif
  65. #if _BLOOM_HQ
  66. half3 A = SamplePrefilter(uv, float2(-1.0, -1.0));
  67. half3 B = SamplePrefilter(uv, float2( 0.0, -1.0));
  68. half3 C = SamplePrefilter(uv, float2( 1.0, -1.0));
  69. half3 D = SamplePrefilter(uv, float2(-0.5, -0.5));
  70. half3 E = SamplePrefilter(uv, float2( 0.5, -0.5));
  71. half3 F = SamplePrefilter(uv, float2(-1.0, 0.0));
  72. half3 G = SamplePrefilter(uv, float2( 0.0, 0.0));
  73. half3 H = SamplePrefilter(uv, float2( 1.0, 0.0));
  74. half3 I = SamplePrefilter(uv, float2(-0.5, 0.5));
  75. half3 J = SamplePrefilter(uv, float2( 0.5, 0.5));
  76. half3 K = SamplePrefilter(uv, float2(-1.0, 1.0));
  77. half3 L = SamplePrefilter(uv, float2( 0.0, 1.0));
  78. half3 M = SamplePrefilter(uv, float2( 1.0, 1.0));
  79. half2 div = (1.0 / 4.0) * half2(0.5, 0.125);
  80. half3 color = (D + E + I + J) * div.x;
  81. color += (A + B + G + F) * div.y;
  82. color += (B + C + H + G) * div.y;
  83. color += (F + G + L + K) * div.y;
  84. color += (G + H + M + L) * div.y;
  85. #else
  86. half3 color = SamplePrefilter(uv, float2(0,0));
  87. #endif
  88. // User controlled clamp to limit crazy high broken spec
  89. color = min(ClampMax, color);
  90. // Thresholding
  91. half brightness = Max3(color.r, color.g, color.b);
  92. half softness = clamp(brightness - Threshold + ThresholdKnee, 0.0, 2.0 * ThresholdKnee);
  93. softness = (softness * softness) / (4.0 * ThresholdKnee + 1e-4);
  94. half multiplier = max(brightness - Threshold, softness) / max(brightness, 1e-4);
  95. color *= multiplier;
  96. // Clamp colors to positive once in prefilter. Encode can have a sqrt, and sqrt(-x) == NaN. Up/Downsample passes would then spread the NaN.
  97. color = max(color, 0);
  98. return EncodeHDR(color);
  99. }
  100. half4 FragBlurH(Varyings input) : SV_Target
  101. {
  102. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  103. float2 texelSize = _BlitTexture_TexelSize.xy * 2.0;
  104. float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
  105. // 9-tap gaussian blur on the downsampled source
  106. half3 c0 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv - float2(texelSize.x * 4.0, 0.0), texelSize)));
  107. half3 c1 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv - float2(texelSize.x * 3.0, 0.0), texelSize)));
  108. half3 c2 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv - float2(texelSize.x * 2.0, 0.0), texelSize)));
  109. half3 c3 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv - float2(texelSize.x * 1.0, 0.0), texelSize)));
  110. half3 c4 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv , texelSize)));
  111. half3 c5 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv + float2(texelSize.x * 1.0, 0.0), texelSize)));
  112. half3 c6 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv + float2(texelSize.x * 2.0, 0.0), texelSize)));
  113. half3 c7 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv + float2(texelSize.x * 3.0, 0.0), texelSize)));
  114. half3 c8 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv + float2(texelSize.x * 4.0, 0.0), texelSize)));
  115. half3 color = c0 * 0.01621622 + c1 * 0.05405405 + c2 * 0.12162162 + c3 * 0.19459459
  116. + c4 * 0.22702703
  117. + c5 * 0.19459459 + c6 * 0.12162162 + c7 * 0.05405405 + c8 * 0.01621622;
  118. return EncodeHDR(color);
  119. }
  120. half4 FragBlurV(Varyings input) : SV_Target
  121. {
  122. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  123. float2 texelSize = _BlitTexture_TexelSize.xy;
  124. float2 uv = UnityStereoTransformScreenSpaceTex(input.texcoord);
  125. // Optimized bilinear 5-tap gaussian on the same-sized source (9-tap equivalent)
  126. half3 c0 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv - float2(0.0, texelSize.y * 3.23076923), texelSize)));
  127. half3 c1 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv - float2(0.0, texelSize.y * 1.38461538), texelSize)));
  128. half3 c2 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv , texelSize)));
  129. half3 c3 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv + float2(0.0, texelSize.y * 1.38461538), texelSize)));
  130. half3 c4 = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, ClampUVForBilinear(uv + float2(0.0, texelSize.y * 3.23076923), texelSize)));
  131. half3 color = c0 * 0.07027027 + c1 * 0.31621622
  132. + c2 * 0.22702703
  133. + c3 * 0.31621622 + c4 * 0.07027027;
  134. return EncodeHDR(color);
  135. }
  136. half3 Upsample(float2 uv)
  137. {
  138. half3 highMip = DecodeHDR(SAMPLE_TEXTURE2D_X(_BlitTexture, sampler_LinearClamp, uv));
  139. #if _BLOOM_HQ
  140. half3 lowMip = DecodeHDR(SampleTexture2DBicubic(TEXTURE2D_X_ARGS(_SourceTexLowMip, sampler_LinearClamp), uv, _SourceTexLowMip_TexelSize.zwxy, (1.0).xx, unity_StereoEyeIndex));
  141. #else
  142. half3 lowMip = DecodeHDR(SAMPLE_TEXTURE2D_X(_SourceTexLowMip, sampler_LinearClamp, uv));
  143. #endif
  144. return lerp(highMip, lowMip, Scatter);
  145. }
  146. half4 FragUpsample(Varyings input) : SV_Target
  147. {
  148. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
  149. half3 color = Upsample(UnityStereoTransformScreenSpaceTex(input.texcoord));
  150. return EncodeHDR(color);
  151. }
  152. ENDHLSL
  153. SubShader
  154. {
  155. Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline"}
  156. LOD 100
  157. ZTest Always ZWrite Off Cull Off
  158. Pass
  159. {
  160. Name "Bloom Prefilter"
  161. HLSLPROGRAM
  162. #pragma vertex Vert
  163. #pragma fragment FragPrefilter
  164. #pragma multi_compile_local_fragment _ _BLOOM_HQ
  165. #pragma multi_compile_fragment _ _ENABLE_ALPHA_OUTPUT
  166. ENDHLSL
  167. }
  168. Pass
  169. {
  170. Name "Bloom Blur Horizontal"
  171. HLSLPROGRAM
  172. #pragma vertex Vert
  173. #pragma fragment FragBlurH
  174. ENDHLSL
  175. }
  176. Pass
  177. {
  178. Name "Bloom Blur Vertical"
  179. HLSLPROGRAM
  180. #pragma vertex Vert
  181. #pragma fragment FragBlurV
  182. ENDHLSL
  183. }
  184. Pass
  185. {
  186. Name "Bloom Upsample"
  187. HLSLPROGRAM
  188. #pragma vertex Vert
  189. #pragma fragment FragUpsample
  190. #pragma multi_compile_local_fragment _ _BLOOM_HQ
  191. ENDHLSL
  192. }
  193. }
  194. }