1 Shader "Hidden/SSAO" {
2 Properties {
3     _MainTex (
"", 2D) = "" {}
4     _RandomTexture (
"", 2D) = "" {}
5     _SSAO (
"", 2D) = "" {}
6 }
7 Subshader {
8     ZTest Always Cull Off ZWrite Off
9
10 CGINCLUDE

11 // Common code used
by several SSAO passes below
12 #include
"UnityCG.cginc"
13 struct
v2f_ao {
14     float4 pos : SV_POSITION;
15     float2 uv : TEXCOORD0;
16     float2 uvr : TEXCOORD1;
17 };
18
19 uniform float2 _NoiseScale;
20 float4 _CameraDepthNormalsTexture_ST;
21
22 v2f_ao vert_ao (appdata_img v)
23 {
24     v2f_ao o;
25     o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
26     o.uv = TRANSFORM_TEX(v.texcoord, _CameraDepthNormalsTexture);
27     o.uvr = v.texcoord.xy * _NoiseScale;
28     
return o;
29 }
30
31 sampler2D _CameraDepthNormalsTexture;
32 sampler2D _RandomTexture;
33 float4 _Params;
// x=radius, y=minz, z=attenuation power, w=SSAO power
34
35 // HLSL and GLSL
do not support arbitrarily sized arrays as function parameters (eg. float bla[]), whereas Cg does.
36 #
if !defined(UNITY_COMPILER_CG)
37
38 # define INPUT_SAMPLE_COUNT
8
39 # include
"frag_ao.cginc"
40 # undef INPUT_SAMPLE_COUNT
41
42 # define INPUT_SAMPLE_COUNT
14
43 # include
"frag_ao.cginc"
44 # undef INPUT_SAMPLE_COUNT
45
46 # define INPUT_SAMPLE_COUNT
26
47 # include
"frag_ao.cginc"
48 # undef INPUT_SAMPLE_COUNT
49
50 # define INPUT_SAMPLE_COUNT
34
51 # include
"frag_ao.cginc"
52 # undef INPUT_SAMPLE_COUNT
53
54 #
else
55 # define INPUT_SAMPLE_COUNT
56 # include
"frag_ao.cginc"
57 #endif
58
59 ENDCG
60
61     
// ---- SSAO pass, 8 samples
62     Pass {
63         
64 CGPROGRAM
65 #pragma vertex vert_ao
66 #pragma fragment frag
67 #pragma target
3.0
68
69
70 half4 frag (v2f_ao i) : SV_Target
71 {
72     #define SAMPLE_COUNT
8
73     
const float3 RAND_SAMPLES[SAMPLE_COUNT] = {
74         float3(
0.01305719,0.5872321,-0.119337),
75         float3(
0.3230782,0.02207272,-0.4188725),
76         float3(-
0.310725,-0.191367,0.05613686),
77         float3(-
0.4796457,0.09398766,-0.5802653),
78         float3(
0.1399992,-0.3357702,0.5596789),
79         float3(-
0.2484578,0.2555322,0.3489439),
80         float3(
0.1871898,-0.702764,-0.2317479),
81         float3(
0.8849149,0.2842076,0.368524),
82     };
83     
return frag_ao (i, SAMPLE_COUNT, RAND_SAMPLES);
84 }
85 ENDCG
86
87     }

88
89 // ---- SSAO pass,
14 samples
90     Pass {
91         
92 CGPROGRAM
93 #pragma vertex vert_ao
94 #pragma fragment frag
95 #pragma target
3.0
96
97
98 half4 frag (v2f_ao i) : SV_Target
99 {
100     #define SAMPLE_COUNT
14
101     
const float3 RAND_SAMPLES[SAMPLE_COUNT] = {
102         float3(
0.4010039,0.8899381,-0.01751772),
103         float3(
0.1617837,0.1338552,-0.3530486),
104         float3(-
0.2305296,-0.1900085,0.5025396),
105         float3(-
0.6256684,0.1241661,0.1163932),
106         float3(
0.3820786,-0.3241398,0.4112825),
107         float3(-
0.08829653,0.1649759,0.1395879),
108         float3(
0.1891677,-0.1283755,-0.09873557),
109         float3(
0.1986142,0.1767239,0.4380491),
110         float3(-
0.3294966,0.02684341,-0.4021836),
111         float3(-
0.01956503,-0.3108062,-0.410663),
112         float3(-
0.3215499,0.6832048,-0.3433446),
113         float3(
0.7026125,0.1648249,0.02250625),
114         float3(
0.03704464,-0.939131,0.1358765),
115         float3(-
0.6984446,-0.6003422,-0.04016943),
116     };
117     
return frag_ao (i, SAMPLE_COUNT, RAND_SAMPLES);
118 }
119 ENDCG
120
121     }
122     

123 // ---- SSAO pass,
26 samples
124     Pass {
125         
126 CGPROGRAM
127 #pragma vertex vert_ao
128 #pragma fragment frag
129 #pragma target
3.0
130
131
132 half4 frag (v2f_ao i) : SV_Target
133 {
134     #define SAMPLE_COUNT
26
135     
const float3 RAND_SAMPLES[SAMPLE_COUNT] = {
136         float3(
0.2196607,0.9032637,0.2254677),
137         float3(
0.05916681,0.2201506,-0.1430302),
138         float3(-
0.4152246,0.1320857,0.7036734),
139         float3(-
0.3790807,0.1454145,0.100605),
140         float3(
0.3149606,-0.1294581,0.7044517),
141         float3(-
0.1108412,0.2162839,0.1336278),
142         float3(
0.658012,-0.4395972,-0.2919373),
143         float3(
0.5377914,0.3112189,0.426864),
144         float3(-
0.2752537,0.07625949,-0.1273409),
145         float3(-
0.1915639,-0.4973421,-0.3129629),
146         float3(-
0.2634767,0.5277923,-0.1107446),
147         float3(
0.8242752,0.02434147,0.06049098),
148         float3(
0.06262707,-0.2128643,-0.03671562),
149         float3(-
0.1795662,-0.3543862,0.07924347),
150         float3(
0.06039629,0.24629,0.4501176),
151         float3(-
0.7786345,-0.3814852,-0.2391262),
152         float3(
0.2792919,0.2487278,-0.05185341),
153         float3(
0.1841383,0.1696993,-0.8936281),
154         float3(-
0.3479781,0.4725766,-0.719685),
155         float3(-
0.1365018,-0.2513416,0.470937),
156         float3(
0.1280388,-0.563242,0.3419276),
157         float3(-
0.4800232,-0.1899473,0.2398808),
158         float3(
0.6389147,0.1191014,-0.5271206),
159         float3(
0.1932822,-0.3692099,-0.6060588),
160         float3(-
0.3465451,-0.1654651,-0.6746758),
161         float3(
0.2448421,-0.1610962,0.1289366),
162     };
163     
return frag_ao (i, SAMPLE_COUNT, RAND_SAMPLES);
164 }
165 ENDCG
166
167     }

168
169 // ---- Blur pass

170     Pass {
171 CGPROGRAM
172 #pragma vertex vert
173 #pragma fragment frag
174 #pragma target
3.0
175 #include
"UnityCG.cginc"
176
177 struct
v2f {
178     float4 pos : SV_POSITION;
179     float2 uv : TEXCOORD0;
180 };
181
182 float4 _MainTex_ST;
183
184 v2f vert (appdata_img v)
185 {
186     v2f o;
187     o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
188     o.uv = TRANSFORM_TEX (v.texcoord, _CameraDepthNormalsTexture);
189     
return o;
190 }
191
192 sampler2D _SSAO;
193 float3 _TexelOffsetScale;
194
195 inline half CheckSame (half4 n, half4 nn)
196 {
197     
// difference in normals
198     half2 diff = abs(n.xy - nn.xy);
199     half sn = (diff.x + diff.y) <
0.1;
200     
// difference in depth
201     
float z = DecodeFloatRG (n.zw);
202     
float zz = DecodeFloatRG (nn.zw);
203     
float zdiff = abs(z-zz) * _ProjectionParams.z;
204     half sz = zdiff <
0.2;
205     
return sn * sz;
206 }
207
208
209 half4 frag( v2f i ) : SV_Target
210 {
211     #define NUM_BLUR_SAMPLES
4
212     
213     float2 o = _TexelOffsetScale.xy;
214     
215     half sum = tex2D(_SSAO, i.uv).r * (NUM_BLUR_SAMPLES +
1);
216     half denom = NUM_BLUR_SAMPLES +
1;
217     
218     half4 geom = tex2D (_CameraDepthNormalsTexture, i.uv);
219     
220     
for (int s = 0; s < NUM_BLUR_SAMPLES; ++s)
221     {
222         float2 nuv = i.uv + o * (s+
1);
223         half4 ngeom = tex2D (_CameraDepthNormalsTexture, nuv.xy);
224         half coef = (NUM_BLUR_SAMPLES - s) * CheckSame (geom, ngeom);
225         sum += tex2D (_SSAO, nuv.xy).r * coef;
226         denom += coef;
227     }
228     
for (int s = 0; s < NUM_BLUR_SAMPLES; ++s)
229     {
230         float2 nuv = i.uv - o * (s+
1);
231         half4 ngeom = tex2D (_CameraDepthNormalsTexture, nuv.xy);
232         half coef = (NUM_BLUR_SAMPLES - s) * CheckSame (geom, ngeom);
233         sum += tex2D (_SSAO, nuv.xy).r * coef;
234         denom += coef;
235     }
236     
return sum / denom;
237 }
238 ENDCG
239     }
240     
241     
// ---- Composite pass
242     Pass {
243 CGPROGRAM
244 #pragma vertex vert
245 #pragma fragment frag
246 #include
"UnityCG.cginc"
247
248 struct
v2f {
249     float4 pos : SV_POSITION;
250     float2 uv[
2] : TEXCOORD0;
251 };
252
253 v2f vert (appdata_img v)
254 {
255     v2f o;
256     o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
257     o.uv[
0] = MultiplyUV (UNITY_MATRIX_TEXTURE0, v.texcoord);
258     o.uv[
1] = MultiplyUV (UNITY_MATRIX_TEXTURE1, v.texcoord);
259     
return o;
260 }
261
262 sampler2D _MainTex;
263 sampler2D _SSAO;
264
265 half4 frag( v2f i ) : SV_Target
266 {
267     half4 c = tex2D (_MainTex, i.uv[
0]);
268     half ao = tex2D (_SSAO, i.uv[
1]).r;
269     ao = pow (ao, _Params.w);
270     c.rgb *= ao;
271     
return c;
272 }
273 ENDCG
274     }
275
276 }
277
278 Fallback off
279 }


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