1
2 /*
3     DX11 Depth Of Field
4     pretty much just does bokeh texture splatting
5
6     basic algorithm:
7
8     * find bright spots
9     * verify high frequency (otherwise dont care)
10     *
if possitive, replace with black pixel and add to append buffer
11     * box blur buffer (thus smearing black pixels)
12     * blend bokeh texture sprites via append buffer
on top of box blurred buffer
13     * composite with frame buffer
14 */

15
16 Shader
"Hidden/Dof/DX11Dof"
17 {
18     Properties
19     {
20         _MainTex (
"", 2D) = "white" {}
21         _BlurredColor (
"", 2D) = "white" {}
22         _FgCocMask (
"", 2D) = "white" {}
23     }
24
25     CGINCLUDE
26
27     #define BOKEH_ZERO_VEC (float4(
0,0,0,0))
28     #define BOKEH_ONE_VEC (float4(
1,1,1,1))
29
30     float4 _BokehParams;
// legend: dx11BokehScale, dx11BokehIntensity,dx11BokehThreshhold, internalBlurWidth
31     float4 _MainTex_TexelSize;
32     float3 _Screen;
33     
float _SpawnHeuristic;
34
35     sampler2D_float _CameraDepthTexture;
36     sampler2D _BlurredColor;
37     sampler2D _MainTex;
38     sampler2D _FgCocMask;
39
40     
struct appendStruct {
41         float3 pos;
42         float4 color;
43     };
44
45     
struct gs_out {
46         float4 pos : SV_POSITION;
47         float3 uv : TEXCOORD0;
48         float4 color : TEXCOORD1;
49         float4 misc : TEXCOORD2;
50     };
51
52     
// TODO: activate border clamp tex sampler state instead?
53     inline float4 clampBorderColor(float2 uv)
54     {
55 #
if 1
56         
if(uv.x<=0) return BOKEH_ZERO_VEC; if(uv.x>=1) return BOKEH_ZERO_VEC;
57         
if(uv.y<=0) return BOKEH_ZERO_VEC; if(uv.y>=1) return BOKEH_ZERO_VEC;
58 #endif
59         
return BOKEH_ONE_VEC;
60     }
61
62     
struct vs_out {
63         float4 pos : SV_POSITION;
64         float2 uv : TEXCOORD0;
65         float4 color : TEXCOORD1;
66         
float cocOverlap : TEXCOORD2;
67     };
68
69     StructuredBuffer<appendStruct> pointBuffer;
70
71     vs_out vertApply (
uint id : SV_VertexID)
72     {
73         vs_out o;
74         float2 pos = pointBuffer[id].pos.xy ;
75         o.pos = float4(pos *
2.0 - 1.0, 0, 1);
76         o.color = pointBuffer[id].color;
77         #
if UNITY_UV_STARTS_AT_TOP
78             o.pos.y *= -
1;
79         #endif
80         o.cocOverlap = pointBuffer[id].pos.z;
81
82         
return o;
83     }
84
85     
[maxvertexcount(4)]
86     
void geom (point vs_out input[1], inout TriangleStream<gs_out> outStream)
87     {
88         
// NEW ENERGY CONSERVATION:
89
90         float2 scale2 = _BokehParams.ww * input[
0].color.aa * _BokehParams.xx;
91         float4 offs =
0;
92         offs.xy = float2(
3.0, 3.0) + 2.0f * floor(scale2 + float2(0.5,0.5));
93
94         float2 rs = ((float2(
1.0, 1.0) + 2.0f * (scale2 + float2(0.5,0.5))));;
95         float2 f2 = offs.xy / rs;
96
97         
float energyAdjustment = (_BokehParams.y) / (rs.x*rs.y);
98         offs.xy *= _Screen.xy;
99
100         gs_out output;
101
102         output.pos = input[
0].pos + offs*float4(-1,1,0,0);
103         output.misc = float4(f2,
0,0);
104         output.uv = float3(
0, 1, input[0].cocOverlap);
105         output.color = input[
0].color * energyAdjustment;
106         outStream.Append (output);
107
108         output.pos = input[
0].pos + offs*float4(1,1,0,0);
109         output.misc = float4(f2,
0,0);
110         output.uv = float3(
1, 1, input[0].cocOverlap);
111         output.color = input[
0].color * energyAdjustment;
112         outStream.Append (output);
113
114         output.pos = input[
0].pos + offs*float4(-1,-1,0,0);
115         output.misc = float4(f2,
0,0);
116         output.uv = float3(
0, 0, input[0].cocOverlap);
117         output.color = input[
0].color * energyAdjustment;
118         outStream.Append (output);
119
120         output.pos = input[
0].pos + offs*float4(1,-1,0,0);
121         output.misc = float4(f2,
0,0);
122         output.uv = float3(
1, 0, input[0].cocOverlap);
123         output.color = input[
0].color * energyAdjustment;
124         outStream.Append (output);
125
126         outStream.RestartStrip();
127     }
128
129 ENDCG
130
131 SubShader
132 {

133
134 // pass
0: append buffer "collect"
135
136 Pass
137 {
138     ZWrite Off ZTest Always Cull Off
139
140     CGPROGRAM
141
142     #pragma vertex vert
143     #pragma fragment frag
144     #pragma target
5.0
145
146     #include
"UnityCG.cginc"
147
148     
struct appdata {
149         float4 vertex : POSITION;
150         float2 texcoord : TEXCOORD0;
151     };
152
153     
struct v2f {
154         float4 pos : SV_POSITION;
155         float2 uv_flip : TEXCOORD0;
156         float2 uv : TEXCOORD1;
157     };
158
159     v2f vert (appdata v)
160     {
161         v2f o;
162         o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
163         o.uv = v.texcoord;
164         o.uv_flip = v.texcoord;
165         #
if UNITY_UV_STARTS_AT_TOP
166         
if(_MainTex_TexelSize.y<0)
167             o.uv_flip.y =
1.0-o.uv_flip.y;
168         
if(_MainTex_TexelSize.y<0)
169             o.pos.y *= -
1.0;
170         #endif
171         
return o;
172     }
173
174     AppendStructuredBuffer<appendStruct> pointBufferOutput : register(u1);
175
176     float4 frag (v2f i) : SV_Target
177     {
178         float4 c = tex2D (_MainTex, i.uv_flip);
179         
float lumc = Luminance (c.rgb);
180
181         float4 cblurred = tex2D (_BlurredColor, i.uv);
182         
float lumblurred = Luminance (cblurred.rgb);
183
184         
float fgCoc = tex2D(_FgCocMask, i.uv).a;
185
186         
[branch]
187         
if (c.a * _BokehParams.w > 1 && cblurred.a > 0.1 && lumc > _BokehParams.z && abs(lumc-lumblurred) > _SpawnHeuristic)
188         {
189             appendStruct append;
190             append.pos = float3(i.uv, fgCoc);
191             append.color.rgba = float4(c.rgb * saturate(c.a*
4), c.a);
192             pointBufferOutput.Append (append);
193             
return float4(c.rgb * saturate(1-c.a*4), c.a);
194         }
195
196         
return c;
197     }
198     ENDCG
199 }

200
201 // pass
1: bokeh splatting (low resolution)
202
203 Pass {
204
205     ZWrite Off ZTest Always Cull Off
206     Blend One One, One One
207     ColorMask RGBA
208
209     CGPROGRAM
210
211     #pragma target
5.0
212     #pragma vertex vertApply
213     #pragma geometry geom
214     #pragma fragment frag
215
216     #include
"UnityCG.cginc"
217
218     fixed4 frag (gs_out i) : SV_Target
219     {
220         float2 uv = (i.uv.xy) * i.misc.xy + (float2(
1,1)-i.misc.xy) * 0.5; // smooth uv scale
221         
return float4(i.color.rgb, 1) * float4(tex2D(_MainTex, uv.xy).rgb, i.uv.z) * clampBorderColor (uv);
222     }
223
224     ENDCG
225 }

226
227 // pass
2: bokeh splatting (high resolution)
228
229 Pass {
230
231     ZWrite Off ZTest Always Cull Off
232     BlendOp Add, Add
233     Blend DstAlpha One, Zero One
234     ColorMask RGBA
235
236     CGPROGRAM
237
238     #pragma target
5.0
239     #pragma vertex vertApply
240     #pragma geometry geom
241     #pragma fragment frag
242
243     #include
"UnityCG.cginc"
244
245     fixed4 frag (gs_out i) : SV_Target
246     {
247         float2 uv = (i.uv.xy) * i.misc.xy + (float2(
1,1)-i.misc.xy) * 0.5; // smooth uv scale
248         
return float4(i.color.rgb, 1) * float4(tex2D(_MainTex, uv.xy).rgb, i.uv.z) * clampBorderColor (uv);
249     }
250
251     ENDCG
252 }
253
254 }
255
256 Fallback Off
257 }


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