Blur.hlsl 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. #ifndef VOLUMETRIC_FOG_2_BLUR
  2. #define VOLUMETRIC_FOG_2_BLUR
  3. #include "CommonsURP.hlsl"
  4. TEXTURE2D_X(_MainTex);
  5. TEXTURE2D_X(_LightBuffer);
  6. TEXTURE2D_X(_DownsampledDepth);
  7. TEXTURE2D(_BlueNoise);
  8. float4 _BlueNoise_TexelSize;
  9. float4 _MainTex_TexelSize;
  10. float4 _MainTex_ST;
  11. float4 _DownsampledDepth_TexelSize;
  12. float4 _MiscData;
  13. float _BlurScale;
  14. half4 _ScatteringData;
  15. half3 _ScatteringTint;
  16. #define DITHER_STRENGTH _MiscData.x
  17. #define BRIGHTNESS _MiscData.y
  18. #define BLUR_EDGE_THRESHOLD _MiscData.z
  19. #define DOWNSCALING_EDGE_THRESHOLD _MiscData.w
  20. #define BLUR_SCALE _BlurScale
  21. #define SCATTERING _ScatteringData.w
  22. #define SCATTERING_THRESHOLD _ScatteringData.x
  23. #define SCATTERING_INTENSITY _ScatteringData.y
  24. #define SCATTERING_ABSORPTION _ScatteringData.z
  25. TEXTURE2D_X(_BlurredTex);
  26. // Optimization for SSPR
  27. #define uvN uv1
  28. #define uvE uv2
  29. #define uvW uv3
  30. #define uvS uv4
  31. #if defined(UNITY_STEREO_INSTANCING_ENABLED) || defined(UNITY_STEREO_MULTIVIEW_ENABLED) || defined(SINGLE_PASS_STEREO)
  32. #define VERTEX_CROSS_UV_DATA
  33. #define VERTEX_OUTPUT_CROSS_UV(o)
  34. #define FRAG_SETUP_CROSS_UV(i) float3 uvInc = float3(_MainTex_TexelSize.x, _MainTex_TexelSize.y, 0); uvInc.xy *= BLUR_SCALE; float2 uvN = i.uv + uvInc.zy; float2 uvE = i.uv + uvInc.xz; float2 uvW = i.uv - uvInc.xz; float2 uvS = i.uv - uvInc.zy;
  35. #define VERTEX_OUTPUT_GAUSSIAN_UV(o)
  36. #if defined(BLUR_HORIZ)
  37. #define FRAG_SETUP_GAUSSIAN_UV(i) float2 inc = float2(_MainTex_TexelSize.x * 1.3846153846 * BLUR_SCALE, 0); float2 uv1 = i.uv - inc; float2 uv2 = i.uv + inc; float2 inc2 = float2(_MainTex_TexelSize.x * 3.2307692308 * BLUR_SCALE, 0); float2 uv3 = i.uv - inc2; float2 uv4 = i.uv + inc2;
  38. #else
  39. #define FRAG_SETUP_GAUSSIAN_UV(i) float2 inc = float2(0, _MainTex_TexelSize.y * 1.3846153846 * BLUR_SCALE); float2 uv1 = i.uv - inc; float2 uv2 = i.uv + inc; float2 inc2 = float2(0, _MainTex_TexelSize.y * 3.2307692308 * BLUR_SCALE); float2 uv3 = i.uv - inc2; float2 uv4 = i.uv + inc2;
  40. #endif
  41. #else
  42. #define VERTEX_CROSS_UV_DATA float2 uvN : TEXCOORD1; float2 uvW: TEXCOORD2; float2 uvE: TEXCOORD3; float2 uvS: TEXCOORD4;
  43. #define VERTEX_OUTPUT_CROSS_UV(o) float3 uvInc = float3(_MainTex_TexelSize.x, _MainTex_TexelSize.y, 0); uvInc.xy *= BLUR_SCALE; o.uvN = o.uv + uvInc.zy; o.uvE = o.uv + uvInc.xz; o.uvW = o.uv - uvInc.xz; o.uvS = o.uv - uvInc.zy;
  44. #define FRAG_SETUP_CROSS_UV(i) float2 uv1 = i.uv1; float2 uv2 = i.uv2; float2 uv3 = i.uv3; float2 uv4 = i.uv4;
  45. #if defined(BLUR_HORIZ)
  46. #define VERTEX_OUTPUT_GAUSSIAN_UV(o) float2 inc = float2(_MainTex_TexelSize.x * 1.3846153846 * BLUR_SCALE, 0); o.uv1 = o.uv - inc; o.uv2 = o.uv + inc; float2 inc2 = float2(_MainTex_TexelSize.x * 3.2307692308 * BLUR_SCALE, 0); o.uv3 = o.uv - inc2; o.uv4 = o.uv + inc2;
  47. #else
  48. #define VERTEX_OUTPUT_GAUSSIAN_UV(o) float2 inc = float2(0, _MainTex_TexelSize.y * 1.3846153846 * BLUR_SCALE); o.uv1 = o.uv - inc; o.uv2 = o.uv + inc; float2 inc2 = float2(0, _MainTex_TexelSize.y * 3.2307692308 * BLUR_SCALE); o.uv3 = o.uv - inc2; o.uv4 = o.uv + inc2;
  49. #endif
  50. #define FRAG_SETUP_GAUSSIAN_UV(i) float2 uv1 = i.uv1; float2 uv2 = i.uv2; float2 uv3 = i.uv3; float2 uv4 = i.uv4;
  51. #endif
  52. struct AttributesSimple
  53. {
  54. float4 positionOS : POSITION;
  55. float2 uv : TEXCOORD0;
  56. UNITY_VERTEX_INPUT_INSTANCE_ID
  57. };
  58. struct VaryingsCross {
  59. float4 positionCS : SV_POSITION;
  60. float2 uv: TEXCOORD0;
  61. UNITY_VERTEX_INPUT_INSTANCE_ID
  62. VERTEX_CROSS_UV_DATA
  63. UNITY_VERTEX_OUTPUT_STEREO
  64. };
  65. VaryingsCross VertBlur(AttributesSimple v) {
  66. VaryingsCross o;
  67. UNITY_SETUP_INSTANCE_ID(v);
  68. UNITY_TRANSFER_INSTANCE_ID(v, o);
  69. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  70. o.positionCS = v.positionOS;
  71. o.positionCS.y *= _ProjectionParams.x;
  72. o.uv = v.uv;
  73. VERTEX_OUTPUT_GAUSSIAN_UV(o)
  74. return o;
  75. }
  76. inline void ApplyDither(inout half4 pixel, float2 uv) {
  77. // screen space dithering
  78. //const float3 magic = float3( 0.06711056, 0.00583715, 52.9829189 );
  79. //float jitter = frac( magic.z * frac( dot( uv * _MainTex_TexelSize.zw, magic.xy ) ) );
  80. //pixel = max(0, pixel - jitter * DITHER_STRENGTH);
  81. // blue noise based dithering
  82. float2 noiseUV = uv * _MainTex_TexelSize.zw * _BlueNoise_TexelSize.xy;
  83. half jitter = SAMPLE_TEXTURE2D(_BlueNoise, sampler_PointRepeat, noiseUV).r;
  84. pixel = max(0, pixel - jitter * DITHER_STRENGTH);
  85. }
  86. #if EDGE_PRESERVE_UPSCALING
  87. inline float GetDownsampledLinearEyeDepth(float2 uv) {
  88. float rawDepth = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_LinearClamp, uv).r;
  89. float sceneLinearDepth = LinearEyeDepth(rawDepth, _ZBufferParams);
  90. #if defined(ORTHO_SUPPORT)
  91. #if UNITY_REVERSED_Z
  92. rawDepth = 1.0 - rawDepth;
  93. #endif
  94. float orthoDepth = lerp(_ProjectionParams.y, _ProjectionParams.z, rawDepth);
  95. sceneLinearDepth = lerp(sceneLinearDepth, orthoDepth, unity_OrthoParams.w);
  96. #endif
  97. return sceneLinearDepth;
  98. }
  99. #else
  100. #define GetDownsampledLinearEyeDepth(uv) GetLinearEyeDepth(uv)
  101. #endif
  102. half4 FragBlur (VaryingsCross i): SV_Target {
  103. UNITY_SETUP_INSTANCE_ID(i);
  104. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
  105. i.uv = UnityStereoTransformScreenSpaceTex(i.uv);
  106. FRAG_SETUP_GAUSSIAN_UV(i)
  107. half4 pixel0 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, i.uv);
  108. half4 pixel1 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv1);
  109. half4 pixel2 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv2);
  110. half4 pixel3 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv3);
  111. half4 pixel4 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv4);
  112. float w0 = 0.2270270270;
  113. half4 wn = half4(0.3162162162.xx, 0.0702702703.xx);
  114. #if EDGE_PRESERVE_UPSCALING || EDGE_PRESERVE
  115. float depthFull = GetDownsampledLinearEyeDepth(i.uv);
  116. float4 depths;
  117. depths.x = GetDownsampledLinearEyeDepth(uv1);
  118. depths.y = GetDownsampledLinearEyeDepth(uv2);
  119. depths.z = GetDownsampledLinearEyeDepth(uv3);
  120. depths.w = GetDownsampledLinearEyeDepth(uv4);
  121. half4 depthDiffs = 1.0 + abs(depths - depthFull) * BLUR_EDGE_THRESHOLD;
  122. wn *= saturate(1.0 / depthDiffs);
  123. half w = w0 + dot(wn, 1.0);
  124. half4 pixel = pixel0 * w0 + pixel1 * wn.x + pixel2 * wn.y + pixel3 * wn.z + pixel4 * wn.w;
  125. pixel /= w;
  126. #else
  127. half4 pixel = pixel0 * w0 + pixel1 * wn.x + pixel2 * wn.y + pixel3 * wn.z + pixel4 * wn.w;
  128. #endif
  129. #if DITHER
  130. ApplyDither(pixel, i.uv);
  131. #endif
  132. return pixel;
  133. }
  134. struct VaryingsSimple {
  135. float4 positionCS : SV_POSITION;
  136. float2 uv: TEXCOORD0;
  137. UNITY_VERTEX_INPUT_INSTANCE_ID
  138. UNITY_VERTEX_OUTPUT_STEREO
  139. };
  140. VaryingsSimple VertSimple(AttributesSimple v) {
  141. VaryingsSimple o;
  142. UNITY_SETUP_INSTANCE_ID(v);
  143. UNITY_TRANSFER_INSTANCE_ID(v, o);
  144. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  145. o.positionCS = v.positionOS;
  146. o.positionCS.y *= _ProjectionParams.x;
  147. o.uv = v.uv;
  148. return o;
  149. }
  150. half4 FragUpscalingBlend (VaryingsSimple i): SV_Target {
  151. UNITY_SETUP_INSTANCE_ID(i);
  152. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
  153. float depthFull = GetRawDepth(i.uv);
  154. const float t = 0.5;
  155. float2 uv00 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(-t, -t));
  156. float2 uv10 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(t, -t));
  157. float2 uv01 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(-t, t));
  158. float2 uv11 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(t, t));
  159. float4 depths;
  160. depths.x = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_LinearClamp, uv00).r;
  161. depths.y = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_LinearClamp, uv10).r;
  162. depths.z = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_LinearClamp, uv01).r;
  163. depths.w = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_LinearClamp, uv11).r;
  164. float4 diffs = abs(depthFull.xxxx - depths);
  165. float2 minUV = UnityStereoTransformScreenSpaceTex(i.uv);
  166. if (any(diffs > DOWNSCALING_EDGE_THRESHOLD)) {
  167. // Check 10 vs 00
  168. float minDiff = lerp(diffs.x, diffs.y, diffs.y < diffs.x);
  169. minUV = lerp(uv00, uv10, diffs.y < diffs.x);
  170. // Check against 01
  171. minUV = lerp(minUV, uv01, diffs.z < minDiff);
  172. minDiff = lerp(minDiff, diffs.z, diffs.z < minDiff);
  173. // Check against 11
  174. minUV = lerp(minUV, uv11, diffs.w < minDiff);
  175. }
  176. half4 pixel = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, minUV);
  177. #if DITHER
  178. ApplyDither(pixel, i.uv);
  179. #endif
  180. return pixel;
  181. }
  182. float4 FragOnlyDepth (VaryingsSimple i): SV_Target {
  183. UNITY_SETUP_INSTANCE_ID(i);
  184. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
  185. return GetRawDepth(i.uv);
  186. }
  187. VaryingsCross VertCross(AttributesSimple v) {
  188. VaryingsCross o;
  189. UNITY_SETUP_INSTANCE_ID(v);
  190. UNITY_TRANSFER_INSTANCE_ID(v, o);
  191. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  192. o.positionCS = v.positionOS;
  193. o.positionCS.y *= _ProjectionParams.x;
  194. o.uv = v.uv;
  195. VERTEX_OUTPUT_CROSS_UV(o)
  196. return o;
  197. }
  198. half Brightness(half3 c) {
  199. return max(c.r, max(c.g, c.b));
  200. }
  201. half4 FragScatteringPrefilter(VaryingsSimple i) : SV_Target {
  202. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
  203. i.uv = UnityStereoTransformScreenSpaceTex(i.uv);
  204. half4 color = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, i.uv);
  205. #if UNITY_COLORSPACE_GAMMA
  206. color.rgb = FastSRGBToLinear(color.rgb);
  207. #endif
  208. half3 extraLight = max(0, color.rgb - SCATTERING_THRESHOLD);
  209. color.rgb += extraLight * SCATTERING_INTENSITY;
  210. color.a = Brightness(color.rgb);
  211. return color;
  212. }
  213. half4 FragResample(VaryingsCross i) : SV_Target {
  214. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
  215. i.uv = UnityStereoTransformScreenSpaceTex(i.uv);
  216. FRAG_SETUP_CROSS_UV(i)
  217. half4 c1 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv1);
  218. half4 c2 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv2);
  219. half4 c3 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv3);
  220. half4 c4 = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, uv4);
  221. half w1 = 1.0 / (c1.a + 1.0);
  222. half w2 = 1.0 / (c2.a + 1.0);
  223. half w3 = 1.0 / (c3.a + 1.0);
  224. half w4 = 1.0 / (c4.a + 1.0);
  225. half dd = 1.0 / (w1 + w2 + w3 + w4);
  226. half4 v = (c1 * w1 + c2 * w2 + c3 * w3 + c4 * w4) * dd;
  227. #if defined(COMBINE_SCATTERING)
  228. half4 o = SAMPLE_TEXTURE2D_X(_BlurredTex, sampler_LinearClamp, i.uv);
  229. v = (o + v * (1.0 + SCATTERING)) / (1.0 + SCATTERING * 0.6735);
  230. v *= SCATTERING_ABSORPTION;
  231. #endif
  232. return v;
  233. }
  234. half4 FragScatteringBlend(VaryingsSimple i) : SV_Target {
  235. UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
  236. i.uv = UnityStereoTransformScreenSpaceTex(i.uv);
  237. half4 color = SAMPLE_TEXTURE2D_X(_MainTex, sampler_LinearClamp, i.uv);
  238. #if UNITY_COLORSPACE_GAMMA
  239. color.rgb = FastLinearToSRGB(color.rgb);
  240. #endif
  241. float2 minUV = i.uv;
  242. #if SCATTERING_HQ
  243. float depthFull = GetRawDepth(i.uv);
  244. const float t = 0.5;
  245. float2 uv00 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(-t, -t));
  246. float2 uv10 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(t, -t));
  247. float2 uv01 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(-t, t));
  248. float2 uv11 = UnityStereoTransformScreenSpaceTex(i.uv + _DownsampledDepth_TexelSize.xy * float2(t, t));
  249. float4 depths;
  250. depths.x = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_LinearClamp, uv00).r;
  251. depths.y = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_LinearClamp, uv10).r;
  252. depths.z = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_LinearClamp, uv01).r;
  253. depths.w = SAMPLE_TEXTURE2D_X(_DownsampledDepth, sampler_LinearClamp, uv11).r;
  254. float4 diffs = abs(depthFull.xxxx - depths);
  255. if (any(diffs > DOWNSCALING_EDGE_THRESHOLD)) {
  256. // Check 10 vs 00
  257. float minDiff = lerp(diffs.x, diffs.y, diffs.y < diffs.x);
  258. minUV = lerp(uv00, uv10, diffs.y < diffs.x);
  259. // Check against 01
  260. minUV = lerp(minUV, uv01, diffs.z < minDiff);
  261. minDiff = lerp(minDiff, diffs.z, diffs.z < minDiff);
  262. // Check against 11
  263. minUV = lerp(minUV, uv11, diffs.w < minDiff);
  264. }
  265. #endif
  266. half4 fog = SAMPLE_TEXTURE2D_X(_LightBuffer, sampler_LinearClamp, minUV);
  267. color.rgb *= _ScatteringTint;
  268. color.a = saturate( fog.a * fog.a * SCATTERING * 4.0);
  269. return color;
  270. }
  271. #endif // VOLUMETRIC_FOG_2_BLUR