1  /*
2     NOTES: see CameraMotionBlur.shader
3  */

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


Gõ tìm kiếm nhanh...