CameraMotionBlurDX11.shader 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
  2. /*
  3. NOTES: see CameraMotionBlur.shader
  4. */
  5. Shader "Hidden/CameraMotionBlurDX11" {
  6. Properties {
  7. _MainTex ("-", 2D) = "" {}
  8. _NoiseTex ("-", 2D) = "grey" {}
  9. _VelTex ("-", 2D) = "black" {}
  10. _NeighbourMaxTex ("-", 2D) = "black" {}
  11. }
  12. CGINCLUDE
  13. #include "UnityCG.cginc"
  14. // 'k' in paper
  15. float _MaxRadiusOrKInPaper;
  16. // 's' in paper
  17. #define NUM_SAMPLES (19)
  18. struct v2f {
  19. float4 pos : SV_POSITION;
  20. float2 uv : TEXCOORD0;
  21. };
  22. sampler2D _MainTex;
  23. sampler2D_float _CameraDepthTexture;
  24. sampler2D _VelTex;
  25. sampler2D _NeighbourMaxTex;
  26. sampler2D _NoiseTex;
  27. float4 _MainTex_TexelSize;
  28. float4 _CameraDepthTexture_TexelSize;
  29. float4 _VelTex_TexelSize;
  30. float4x4 _InvViewProj; // inverse view-projection matrix
  31. float4x4 _PrevViewProj; // previous view-projection matrix
  32. float4x4 _ToPrevViewProjCombined; // combined
  33. float _Jitter;
  34. float _VelocityScale;
  35. float _DisplayVelocityScale;
  36. float _MinVelocity;
  37. float _SoftZDistance;
  38. v2f vert(appdata_img v)
  39. {
  40. v2f o;
  41. o.pos = UnityObjectToClipPos (v.vertex);
  42. o.uv = v.texcoord.xy;
  43. return o;
  44. }
  45. // returns vector with largest magnitude
  46. float2 vmax(float2 a, float2 b)
  47. {
  48. float ma = dot(a, a);
  49. float mb = dot(b, b);
  50. return (ma > mb) ? a : b;
  51. }
  52. // find dominant velocity in each tile
  53. float4 TileMax(v2f i) : SV_Target
  54. {
  55. float2 tilemax = float2(0.0, 0.0);
  56. float2 srcPos = i.uv - _MainTex_TexelSize.xy * _MaxRadiusOrKInPaper * 0.5;
  57. for(int y=0; y<(int)_MaxRadiusOrKInPaper; y++) {
  58. for(int x=0; x<(int)_MaxRadiusOrKInPaper; x++) {
  59. float2 v = tex2D(_MainTex, srcPos + float2(x,y) * _MainTex_TexelSize.xy).xy;
  60. tilemax = vmax(tilemax, v);
  61. }
  62. }
  63. return float4(tilemax, 0, 1);
  64. }
  65. // find maximum velocity in any adjacent tile
  66. float4 NeighbourMax(v2f i) : SV_Target
  67. {
  68. float2 maxvel = float2(0.0, 0.0);
  69. for(int y=-1; y<=1; y++) {
  70. for(int x=-1; x<=1; x++) {
  71. float2 v = tex2D(_MainTex, i.uv + float2(x,y) * _MainTex_TexelSize.xy).xy;
  72. maxvel = vmax(maxvel, v);
  73. }
  74. }
  75. return float4(maxvel, 0, 1);
  76. }
  77. float cone(float2 px, float2 py, float2 v)
  78. {
  79. return clamp(1.0 - (length(px - py) / length(v)), 0.0, 1.0);
  80. }
  81. float cylinder(float2 x, float2 y, float2 v)
  82. {
  83. float lv = length(v);
  84. return 1.0 - smoothstep(0.95*lv, 1.05*lv, length(x - y));
  85. }
  86. float softDepthCompare(float za, float zb)
  87. {
  88. return clamp(1.0 - (za - zb) / _SoftZDistance, 0.0, 1.0);
  89. }
  90. float4 ReconstructFilterBlur(v2f i) : SV_Target
  91. {
  92. float2 x = i.uv;
  93. float2 xf = x;
  94. #if UNITY_UV_STARTS_AT_TOP
  95. if (_MainTex_TexelSize.y < 0)
  96. xf.y = 1-xf.y;
  97. #endif
  98. float2 x2 = xf;
  99. float2 vn = tex2D(_NeighbourMaxTex, x2).xy; // largest velocity in neighbourhood
  100. float4 cx = tex2D(_MainTex, x); // color at x
  101. float zx = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, x);
  102. zx = -Linear01Depth(zx); // depth at x
  103. float2 vx = tex2D(_VelTex, xf).xy; // vel at x
  104. // random offset [-0.5, 0.5]
  105. float j = (tex2D(_NoiseTex, i.uv * 11.0f ).r*2-1) * _Jitter;
  106. // sample current pixel
  107. float weight = 1.0;
  108. float4 sum = cx * weight;
  109. int centerSample = (int)(NUM_SAMPLES-1) / 2;
  110. // in DX11 county we take more samples and interleave with sampling along vx direction to break up "patternized" look
  111. for(int l=0; l<NUM_SAMPLES; l++)
  112. {
  113. if (l==centerSample) continue; // skip center sample
  114. // Choose evenly placed filter taps along +-vN,
  115. // but jitter the whole filter to prevent ghosting
  116. float t = lerp(-1.0, 1.0, (l + j) / (-1 + _Jitter + (float)NUM_SAMPLES));
  117. //float t = lerp(-1.0, 1.0, l / (float)(NUM_SAMPLES - 1));
  118. float2 velInterlaved = lerp(vn, min(vx, normalize(vx) * _MainTex_TexelSize.xy * _MaxRadiusOrKInPaper), l%2==0);
  119. float2 y = x + velInterlaved * t;
  120. float2 yf = y;
  121. #if UNITY_UV_STARTS_AT_TOP
  122. if (_MainTex_TexelSize.y < 0)
  123. yf.y = 1-yf.y;
  124. #endif
  125. // velocity at y
  126. float2 vy = tex2Dlod(_VelTex, float4(yf,0,0)).xy;
  127. float zy = SAMPLE_DEPTH_TEXTURE_LOD(_CameraDepthTexture, float4(y,0,0));
  128. zy = -Linear01Depth(zy);
  129. float f = softDepthCompare(zx, zy);
  130. float b = softDepthCompare(zy, zx);
  131. float alphay = f * cone(y, x, vy) + // blurry y in front of any x
  132. b * cone(x, y, vx) + // any y behing blurry x; estimate background
  133. cylinder(y, x, vy) * cylinder(x, y, vx) * 2.0; // simultaneous blurry x and y
  134. float4 cy = tex2Dlod(_MainTex, float4(y,0,0));
  135. sum += cy * alphay;
  136. weight += alphay;
  137. }
  138. sum /= weight;
  139. return sum;
  140. }
  141. ENDCG
  142. Subshader {
  143. // pass 0
  144. Pass {
  145. ZTest Always Cull Off ZWrite Off
  146. CGPROGRAM
  147. #pragma target 5.0
  148. #pragma vertex vert
  149. #pragma fragment TileMax
  150. ENDCG
  151. }
  152. // pass 1
  153. Pass {
  154. ZTest Always Cull Off ZWrite Off
  155. CGPROGRAM
  156. #pragma target 5.0
  157. #pragma vertex vert
  158. #pragma fragment NeighbourMax
  159. ENDCG
  160. }
  161. // pass 2
  162. Pass {
  163. ZTest Always Cull Off ZWrite Off
  164. CGPROGRAM
  165. #pragma target 5.0
  166. #pragma vertex vert
  167. #pragma fragment ReconstructFilterBlur
  168. ENDCG
  169. }
  170. }
  171. Fallback off
  172. }