root / Assets / Standard Assets / Water (Pro Only) / Water4 / Sources / Shaders / WaterInclude.cginc @ 175:f9f5640c2a3a
History | View | Annotate | Download (7.8 kB)
1 | // Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld' |
---|---|
2 | |
3 | // Upgrade NOTE: unity_Scale shader variable was removed; replaced 'unity_Scale.w' with '1.0' |
4 | |
5 | |
6 | #ifndef WATER_CG_INCLUDED |
7 | #define WATER_CG_INCLUDED |
8 | |
9 | #include "UnityCG.cginc" |
10 | |
11 | half _GerstnerIntensity; |
12 | |
13 | inline half3 PerPixelNormal(sampler2D bumpMap, half4 coords, half3 vertexNormal, half bumpStrength) |
14 | { |
15 | half4 bump = tex2D(bumpMap, coords.xy) + tex2D(bumpMap, coords.zw); |
16 | bump.xy = bump.wy - half2(1.0, 1.0); |
17 | half3 worldNormal = vertexNormal + bump.xxy * bumpStrength * half3(1,0,1); |
18 | return normalize(worldNormal); |
19 | } |
20 | |
21 | inline half3 PerPixelNormalUnpacked(sampler2D bumpMap, half4 coords, half bumpStrength) |
22 | { |
23 | half4 bump = tex2D(bumpMap, coords.xy) + tex2D(bumpMap, coords.zw); |
24 | bump = bump * 0.5; |
25 | half3 normal = UnpackNormal(bump); |
26 | normal.xy *= bumpStrength; |
27 | return normalize(normal); |
28 | } |
29 | |
30 | inline half3 GetNormal(half4 tf) { |
31 | #ifdef WATER_VERTEX_DISPLACEMENT_ON |
32 | return half3(2,1,2) * tf.rbg - half3(1,0,1); |
33 | #else |
34 | return half3(0,1,0); |
35 | #endif |
36 | } |
37 | |
38 | inline half GetDistanceFadeout(half screenW, half speed) { |
39 | return 1.0f / abs(0.5f + screenW * speed); |
40 | } |
41 | |
42 | half4 GetDisplacement3(half4 tileableUv, half4 tiling, half4 directionSpeed, sampler2D mapA, sampler2D mapB, sampler2D mapC) |
43 | { |
44 | half4 displacementUv = tileableUv * tiling + _Time.xxxx * directionSpeed; |
45 | #ifdef WATER_VERTEX_DISPLACEMENT_ON |
46 | half4 tf = tex2Dlod(mapA, half4(displacementUv.xy, 0.0,0.0)); |
47 | tf += tex2Dlod(mapB, half4(displacementUv.zw, 0.0,0.0)); |
48 | tf += tex2Dlod(mapC, half4(displacementUv.xw, 0.0,0.0)); |
49 | tf *= 0.333333; |
50 | #else |
51 | half4 tf = half4(0.5,0.5,0.5,0.0); |
52 | #endif |
53 | |
54 | return tf; |
55 | } |
56 | |
57 | half4 GetDisplacement2(half4 tileableUv, half4 tiling, half4 directionSpeed, sampler2D mapA, sampler2D mapB) |
58 | { |
59 | half4 displacementUv = tileableUv * tiling + _Time.xxxx * directionSpeed; |
60 | #ifdef WATER_VERTEX_DISPLACEMENT_ON |
61 | half4 tf = tex2Dlod(mapA, half4(displacementUv.xy, 0.0,0.0)); |
62 | tf += tex2Dlod(mapB, half4(displacementUv.zw, 0.0,0.0)); |
63 | tf *= 0.5; |
64 | #else |
65 | half4 tf = half4(0.5,0.5,0.5,0.0); |
66 | #endif |
67 | |
68 | return tf; |
69 | } |
70 | |
71 | inline void ComputeScreenAndGrabPassPos (float4 pos, out float4 screenPos, out float4 grabPassPos) |
72 | { |
73 | #if UNITY_UV_STARTS_AT_TOP |
74 | float scale = -1.0; |
75 | #else |
76 | float scale = 1.0f; |
77 | #endif |
78 | |
79 | screenPos = ComputeScreenPos(pos); |
80 | grabPassPos.xy = ( float2( pos.x, pos.y*scale ) + pos.w ) * 0.5; |
81 | grabPassPos.zw = pos.zw; |
82 | } |
83 | |
84 | |
85 | inline half3 PerPixelNormalUnpacked(sampler2D bumpMap, half4 coords, half bumpStrength, half2 perVertxOffset) |
86 | { |
87 | half4 bump = tex2D(bumpMap, coords.xy) + tex2D(bumpMap, coords.zw); |
88 | bump = bump * 0.5; |
89 | half3 normal = UnpackNormal(bump); |
90 | normal.xy *= bumpStrength; |
91 | normal.xy += perVertxOffset; |
92 | return normalize(normal); |
93 | } |
94 | |
95 | inline half3 PerPixelNormalLite(sampler2D bumpMap, half4 coords, half3 vertexNormal, half bumpStrength) |
96 | { |
97 | half4 bump = tex2D(bumpMap, coords.xy); |
98 | bump.xy = bump.wy - half2(0.5, 0.5); |
99 | half3 worldNormal = vertexNormal + bump.xxy * bumpStrength * half3(1,0,1); |
100 | return normalize(worldNormal); |
101 | } |
102 | |
103 | inline half4 Foam(sampler2D shoreTex, half4 coords, half amount) |
104 | { |
105 | half4 foam = ( tex2D(shoreTex, coords.xy) * tex2D(shoreTex,coords.zw) ) - 0.125; |
106 | foam.a = amount; |
107 | return foam; |
108 | } |
109 | |
110 | inline half4 Foam(sampler2D shoreTex, half4 coords) |
111 | { |
112 | half4 foam = (tex2D(shoreTex, coords.xy) * tex2D(shoreTex,coords.zw)) - 0.125; |
113 | return foam; |
114 | } |
115 | |
116 | inline half Fresnel(half3 viewVector, half3 worldNormal, half bias, half power) |
117 | { |
118 | half facing = clamp(1.0-max(dot(-viewVector, worldNormal), 0.0), 0.0,1.0); |
119 | half refl2Refr = saturate(bias+(1.0-bias) * pow(facing,power)); |
120 | return refl2Refr; |
121 | } |
122 | |
123 | inline half FresnelViaTexture(half3 viewVector, half3 worldNormal, sampler2D fresnel) |
124 | { |
125 | half facing = saturate(dot(-viewVector, worldNormal)); |
126 | half fresn = tex2D(fresnel, half2(facing, 0.5f)).b; |
127 | return fresn; |
128 | } |
129 | |
130 | inline half2 GetTileableUv(half4 vertex) |
131 | { |
132 | // @NOTE: use worldSpaceVertex.xz instead of ws to make it rotation independent |
133 | half2 ws = half2(unity_ObjectToWorld[0][3],unity_ObjectToWorld[2][3]); |
134 | half2 tileableUv = (ws + vertex.xz/1.0); |
135 | return tileableUv; |
136 | } |
137 | |
138 | inline void VertexDisplacementHQ( sampler2D mapA, sampler2D mapB, |
139 | sampler2D mapC, half4 uv, |
140 | half vertexStrength, half3 normal, |
141 | out half4 vertexOffset, out half2 normalOffset) |
142 | { |
143 | half4 tf = tex2Dlod(mapA, half4(uv.xy, 0.0,0.0)); |
144 | tf += tex2Dlod(mapB, half4(uv.zw, 0.0,0.0)); |
145 | tf += tex2Dlod(mapC, half4(uv.xw, 0.0,0.0)); |
146 | tf /= 3.0; |
147 | |
148 | tf.rga = tf.rga-half3(0.5,0.5,0.0); |
149 | |
150 | // height displacement in alpha channel, normals info in rgb |
151 | |
152 | vertexOffset = tf.a * half4(normal.xyz, 0.0) * vertexStrength; |
153 | normalOffset = tf.rg; |
154 | } |
155 | |
156 | inline void VertexDisplacementLQ( sampler2D mapA, sampler2D mapB, |
157 | sampler2D mapC, half4 uv, |
158 | half vertexStrength, half normalsStrength, |
159 | out half4 vertexOffset, out half2 normalOffset) |
160 | { |
161 | // @NOTE: for best performance, this should really be properly packed! |
162 | |
163 | half4 tf = tex2Dlod(mapA, half4(uv.xy, 0.0,0.0)); |
164 | tf += tex2Dlod(mapB, half4(uv.zw, 0.0,0.0)); |
165 | tf *= 0.5; |
166 | |
167 | tf.rga = tf.rga-half3(0.5,0.5,0.0); |
168 | |
169 | // height displacement in alpha channel, normals info in rgb |
170 | |
171 | vertexOffset = tf.a * half4(0,1,0,0) * vertexStrength; |
172 | normalOffset = tf.rg * normalsStrength; |
173 | } |
174 | |
175 | half4 ExtinctColor (half4 baseColor, half extinctionAmount) |
176 | { |
177 | // tweak the extinction coefficient for different coloring |
178 | return baseColor - extinctionAmount * half4(0.15, 0.03, 0.01, 0.0); |
179 | } |
180 | |
181 | half3 GerstnerOffsets (half2 xzVtx, half steepness, half amp, half freq, half speed, half2 dir) |
182 | { |
183 | half3 offsets; |
184 | |
185 | offsets.x = |
186 | steepness * amp * dir.x * |
187 | cos( freq * dot( dir, xzVtx ) + speed * _Time.x); |
188 | |
189 | offsets.z = |
190 | steepness * amp * dir.y * |
191 | cos( freq * dot( dir, xzVtx ) + speed * _Time.x); |
192 | |
193 | offsets.y = |
194 | amp * sin ( freq * dot( dir, xzVtx ) + speed * _Time.x); |
195 | |
196 | return offsets; |
197 | } |
198 | |
199 | half3 GerstnerOffset4 (half2 xzVtx, half4 steepness, half4 amp, half4 freq, half4 speed, half4 dirAB, half4 dirCD) |
200 | { |
201 | half3 offsets; |
202 | |
203 | half4 AB = steepness.xxyy * amp.xxyy * dirAB.xyzw; |
204 | half4 CD = steepness.zzww * amp.zzww * dirCD.xyzw; |
205 | |
206 | half4 dotABCD = freq.xyzw * half4(dot(dirAB.xy, xzVtx), dot(dirAB.zw, xzVtx), dot(dirCD.xy, xzVtx), dot(dirCD.zw, xzVtx)); |
207 | half4 TIME = _Time.yyyy * speed; |
208 | |
209 | half4 COS = cos (dotABCD + TIME); |
210 | half4 SIN = sin (dotABCD + TIME); |
211 | |
212 | offsets.x = dot(COS, half4(AB.xz, CD.xz)); |
213 | offsets.z = dot(COS, half4(AB.yw, CD.yw)); |
214 | offsets.y = dot(SIN, amp); |
215 | |
216 | return offsets; |
217 | } |
218 | |
219 | half3 GerstnerNormal (half2 xzVtx, half steepness, half amp, half freq, half speed, half2 dir) |
220 | { |
221 | half3 nrml = half3(0,0,0); |
222 | |
223 | nrml.x -= |
224 | dir.x * (amp * freq) * |
225 | cos(freq * dot( dir, xzVtx ) + speed * _Time.x); |
226 | |
227 | nrml.z -= |
228 | dir.y * (amp * freq) * |
229 | cos(freq * dot( dir, xzVtx ) + speed * _Time.x); |
230 | |
231 | return nrml; |
232 | } |
233 | |
234 | half3 GerstnerNormal4 (half2 xzVtx, half4 amp, half4 freq, half4 speed, half4 dirAB, half4 dirCD) |
235 | { |
236 | half3 nrml = half3(0,2.0,0); |
237 | |
238 | half4 AB = freq.xxyy * amp.xxyy * dirAB.xyzw; |
239 | half4 CD = freq.zzww * amp.zzww * dirCD.xyzw; |
240 | |
241 | half4 dotABCD = freq.xyzw * half4(dot(dirAB.xy, xzVtx), dot(dirAB.zw, xzVtx), dot(dirCD.xy, xzVtx), dot(dirCD.zw, xzVtx)); |
242 | half4 TIME = _Time.yyyy * speed; |
243 | |
244 | half4 COS = cos (dotABCD + TIME); |
245 | |
246 | nrml.x -= dot(COS, half4(AB.xz, CD.xz)); |
247 | nrml.z -= dot(COS, half4(AB.yw, CD.yw)); |
248 | |
249 | nrml.xz *= _GerstnerIntensity; |
250 | nrml = normalize (nrml); |
251 | |
252 | return nrml; |
253 | } |
254 | |
255 | void Gerstner ( out half3 offs, out half3 nrml, |
256 | half3 vtx, half3 tileableVtx, |
257 | half4 amplitude, half4 frequency, half4 steepness, |
258 | half4 speed, half4 directionAB, half4 directionCD ) |
259 | { |
260 | #ifdef WATER_VERTEX_DISPLACEMENT_ON |
261 | offs = GerstnerOffset4(tileableVtx.xz, steepness, amplitude, frequency, speed, directionAB, directionCD); |
262 | nrml = GerstnerNormal4(tileableVtx.xz + offs.xz, amplitude, frequency, speed, directionAB, directionCD); |
263 | #else |
264 | offs = half3(0,0,0); |
265 | nrml = half3(0,1,0); |
266 | #endif |
267 | } |
268 | |
269 | |
270 | #endif |