1 | // this is a slighty modified version of the nvidia ocean.fx shader
|
---|
2 |
|
---|
3 | float4x4 worldMatrix : World; // World or Model matrix
|
---|
4 | float4x4 wvpMatrix : WorldViewProjection; // Model*View*Projection
|
---|
5 | float4x4 worldViewMatrix : WorldView;
|
---|
6 | float4x4 viewInverseMatrix : ViewInverse;
|
---|
7 |
|
---|
8 | float time : Time;
|
---|
9 | bool forRaytracer = false;
|
---|
10 |
|
---|
11 | float3 fSceneDimensions;
|
---|
12 |
|
---|
13 | texture normalMap : Normal;
|
---|
14 |
|
---|
15 | texture cubeMap : Environment;
|
---|
16 |
|
---|
17 | texture terrainTex;
|
---|
18 |
|
---|
19 | float FarPlaneMinusNearPlane; // Distance of the far plane minus distance of the near plane.
|
---|
20 |
|
---|
21 | sampler2D normalMapSampler = sampler_state
|
---|
22 | {
|
---|
23 | Texture = <normalMap>;
|
---|
24 | MagFilter = Linear;
|
---|
25 | MinFilter = Linear;
|
---|
26 | MipFilter = Linear;
|
---|
27 | };
|
---|
28 |
|
---|
29 | samplerCUBE envMapSampler = sampler_state
|
---|
30 | {
|
---|
31 | Texture = <cubeMap>;
|
---|
32 | MinFilter = Linear;
|
---|
33 | MagFilter = Linear;
|
---|
34 | MipFilter = Linear;
|
---|
35 | AddressU = Clamp;
|
---|
36 | AddressV = Clamp;
|
---|
37 | };
|
---|
38 |
|
---|
39 |
|
---|
40 | sampler2D terrainSampler = sampler_state
|
---|
41 | {
|
---|
42 | Texture = <terrainTex>;
|
---|
43 | minfilter = Linear;
|
---|
44 | mipfilter = Linear;
|
---|
45 | magfilter = Linear;
|
---|
46 | addressu = BORDER;
|
---|
47 | addressv = BORDER;
|
---|
48 | addressw = BORDER;
|
---|
49 | };
|
---|
50 |
|
---|
51 | float bumpHeight = 0.5;
|
---|
52 | float2 textureScale = {25.60, 12.80 };
|
---|
53 | float2 bumpSpeed = { -0.1, 0.1 };
|
---|
54 | float fresnelBias = 0.5;
|
---|
55 | //float fresnelPower = 4.0;
|
---|
56 | float fresnelPower = 12.0;
|
---|
57 | float hdrMultiplier = 3.0;
|
---|
58 | //float4 deepColor : Diffuse = {0.0f, 0.0f, 0.1f, 1.0f};
|
---|
59 | //float4 shallowColor : Diffuse = {0.0f, 0.5f, 0.5f, 1.0f};
|
---|
60 | float4 deepColor : Diffuse;
|
---|
61 | float4 shallowColor : Diffuse;
|
---|
62 | float4 reflectionColor : Specular = {0.5f, 0.5f, 0.5f, 1.0f};
|
---|
63 | float reflectionAmount = 1.0f;
|
---|
64 | float waterAmount = 1.0f;
|
---|
65 | float waveAmp = 0.0;
|
---|
66 | float waveFreq = 0.1;
|
---|
67 |
|
---|
68 | struct a2v {
|
---|
69 | float4 Position : POSITION; // in object space
|
---|
70 | float2 TexCoord : TEXCOORD0;
|
---|
71 | float2 terrainCoord : TEXCOORD1;
|
---|
72 | float3 Tangent : TEXCOORD2;
|
---|
73 | float3 Binormal : TEXCOORD3;
|
---|
74 | float3 Normal : NORMAL;
|
---|
75 |
|
---|
76 | };
|
---|
77 |
|
---|
78 | struct v2f {
|
---|
79 | float4 Position : POSITION; // in clip space
|
---|
80 | float2 TexCoord : TEXCOORD0;
|
---|
81 | float3 TexCoord1 : TEXCOORD1; // first row of the 3x3 transform from tangent to cube space
|
---|
82 | float3 TexCoord2 : TEXCOORD2; // second row of the 3x3 transform from tangent to cube space
|
---|
83 | float3 TexCoord3 : TEXCOORD3; // third row of the 3x3 transform from tangent to cube space
|
---|
84 |
|
---|
85 | float2 bumpCoord0 : TEXCOORD4;
|
---|
86 | float2 bumpCoord1 : TEXCOORD5;
|
---|
87 | float2 bumpCoord2 : TEXCOORD6;
|
---|
88 |
|
---|
89 | float3 eyeVector : TEXCOORD7;
|
---|
90 |
|
---|
91 | float4 pos2 : COLOR0;
|
---|
92 | float4 terrainCoord : COLOR1;
|
---|
93 | };
|
---|
94 |
|
---|
95 | struct v2fdepth {
|
---|
96 | float4 HPosition : POSITION;
|
---|
97 | float4 texCoord : TEXCOORD0;
|
---|
98 | };
|
---|
99 |
|
---|
100 | struct PS_OUTPUT
|
---|
101 | {
|
---|
102 | float4 diffuse : COLOR0;
|
---|
103 | };
|
---|
104 |
|
---|
105 | struct pixelOutput
|
---|
106 | {
|
---|
107 | float4 color : COLOR;
|
---|
108 | };
|
---|
109 |
|
---|
110 |
|
---|
111 | struct depthVertexInput {
|
---|
112 | float4 position : POSITION;
|
---|
113 | float4 texCoord : TEXCOORD0;
|
---|
114 | };
|
---|
115 |
|
---|
116 | struct depthVertexOutput {
|
---|
117 | float4 HPosition : POSITION;
|
---|
118 | float4 texCoord : TEXCOORD0;
|
---|
119 | };
|
---|
120 |
|
---|
121 | // wave functions
|
---|
122 |
|
---|
123 | struct Wave {
|
---|
124 | float freq; // 2*PI / wavelength
|
---|
125 | float amp; // amplitude
|
---|
126 | float phase; // speed * 2*PI / wavelength
|
---|
127 | float2 dir;
|
---|
128 | };
|
---|
129 |
|
---|
130 | #define NWAVES 2
|
---|
131 | Wave wave[NWAVES] = {
|
---|
132 | { 1.0, 1.0, 0.5, float2(-1, 0) },
|
---|
133 | { 2.0, 0.5, 1.3, float2(-0.7, 0.7) }
|
---|
134 | };
|
---|
135 |
|
---|
136 | float evaluateWave(Wave w, float2 pos, float t)
|
---|
137 | {
|
---|
138 | return w.amp * sin( dot(w.dir, pos)*w.freq + t*w.phase);
|
---|
139 | }
|
---|
140 |
|
---|
141 | // derivative of wave function
|
---|
142 | float evaluateWaveDeriv(Wave w, float2 pos, float t)
|
---|
143 | {
|
---|
144 | return w.freq*w.amp * cos( dot(w.dir, pos)*w.freq + t*w.phase);
|
---|
145 | }
|
---|
146 |
|
---|
147 | v2f BumpReflectWaveVS(a2v IN,
|
---|
148 | uniform float4x4 WorldViewProj,
|
---|
149 | uniform float4x4 World,
|
---|
150 | uniform float4x4 ViewIT,
|
---|
151 | uniform float BumpScale,
|
---|
152 | uniform float2 textureScale,
|
---|
153 | uniform float2 bumpSpeed,
|
---|
154 | uniform float time,
|
---|
155 | uniform float waveFreq,
|
---|
156 | uniform float waveAmp
|
---|
157 | )
|
---|
158 | {
|
---|
159 | v2f OUT;
|
---|
160 |
|
---|
161 | wave[0].freq = waveFreq;
|
---|
162 | wave[0].amp = waveAmp;
|
---|
163 |
|
---|
164 | wave[1].freq = waveFreq*2.0;
|
---|
165 | wave[1].amp = waveAmp*0.5;
|
---|
166 |
|
---|
167 | float4 P = IN.Position;
|
---|
168 |
|
---|
169 | // sum waves
|
---|
170 |
|
---|
171 | float ddx = 0.0, ddy = 0.0;
|
---|
172 | for(int i=0; i<NWAVES; i++) {
|
---|
173 | //P.y += evaluateWave(wave[i], P.xz, time);
|
---|
174 | float deriv = evaluateWaveDeriv(wave[i], P.xz, time);
|
---|
175 | ddx += deriv * wave[i].dir.x;
|
---|
176 | ddy += deriv * wave[i].dir.y;
|
---|
177 | }
|
---|
178 |
|
---|
179 | P.y = 0.5f;
|
---|
180 |
|
---|
181 | // compute tangent basis
|
---|
182 | float3 B = float3(1, ddx, 0);
|
---|
183 | float3 T = float3(0, ddy, 1);
|
---|
184 | float3 N = float3(-ddx, 1, -ddy);
|
---|
185 |
|
---|
186 | OUT.Position = mul(P, WorldViewProj);
|
---|
187 |
|
---|
188 | // pass texture coordinates for fetching the normal map
|
---|
189 | OUT.TexCoord.xy = IN.TexCoord*textureScale;
|
---|
190 |
|
---|
191 | time = fmod(time, 100.0);
|
---|
192 | OUT.bumpCoord0.xy = IN.TexCoord*textureScale + time*bumpSpeed;
|
---|
193 | OUT.bumpCoord1.xy = IN.TexCoord*textureScale*2.0 + time*bumpSpeed*4.0;
|
---|
194 | OUT.bumpCoord2.xy = IN.TexCoord*textureScale*4.0 + time*bumpSpeed*8.0;
|
---|
195 |
|
---|
196 | // compute the 3x3 tranform from tangent space to object space
|
---|
197 | float3x3 objToTangentSpace;
|
---|
198 | // first rows are the tangent and binormal scaled by the bump scale
|
---|
199 | objToTangentSpace[0] = BumpScale * normalize(T);
|
---|
200 | objToTangentSpace[1] = BumpScale * normalize(B);
|
---|
201 | objToTangentSpace[2] = normalize(N);
|
---|
202 |
|
---|
203 | OUT.TexCoord1.xyz = mul(objToTangentSpace, World[0].xyz);
|
---|
204 | OUT.TexCoord2.xyz = mul(objToTangentSpace, World[1].xyz);
|
---|
205 | OUT.TexCoord3.xyz = mul(objToTangentSpace, World[2].xyz);
|
---|
206 |
|
---|
207 | //for raytracer:
|
---|
208 | if(forRaytracer) {
|
---|
209 | OUT.pos2 = mul(IN.Position, worldViewMatrix );
|
---|
210 | } else {
|
---|
211 | OUT.pos2.xyzw = 0;
|
---|
212 | }
|
---|
213 |
|
---|
214 |
|
---|
215 | // compute the eye vector (going from shaded point to eye) in cube space
|
---|
216 | float4 worldPos = mul(P, World);
|
---|
217 | OUT.eyeVector = ViewIT[3] - worldPos; // view inv. transpose contains eye position in world space in last row
|
---|
218 | OUT.terrainCoord.xy = IN.TexCoord;
|
---|
219 | OUT.terrainCoord.zw = 0;
|
---|
220 | return OUT;
|
---|
221 | }
|
---|
222 |
|
---|
223 | // Pixel Shaders
|
---|
224 |
|
---|
225 | float4 OceanPS20(v2f IN,
|
---|
226 | uniform sampler2D NormalMap,
|
---|
227 | uniform samplerCUBE EnvironmentMap,
|
---|
228 | uniform sampler2D terrainSamp,
|
---|
229 | uniform half4 deepColor,
|
---|
230 | uniform half4 shallowColor,
|
---|
231 | uniform half4 reflectionColor,
|
---|
232 | uniform half4 reflectionAmount,
|
---|
233 | uniform half4 waterAmount,
|
---|
234 | uniform half fresnelPower,
|
---|
235 | uniform half fresnelBias,
|
---|
236 | uniform half hdrMultiplier
|
---|
237 | ) : COLOR
|
---|
238 | {
|
---|
239 | // sum normal maps
|
---|
240 | half4 t0 = tex2D(NormalMap, IN.bumpCoord0.xy)*2.0-1.0;
|
---|
241 | half4 t1 = tex2D(NormalMap, IN.bumpCoord1.xy)*2.0-1.0;
|
---|
242 | half4 t2 = tex2D(NormalMap, IN.bumpCoord2.xy)*2.0-1.0;
|
---|
243 | half3 N = t0.xyz + t1.xyz + t2.xyz;
|
---|
244 |
|
---|
245 | half3x3 m; // tangent to world matrix
|
---|
246 | m[0] = IN.TexCoord1;
|
---|
247 | m[1] = IN.TexCoord2;
|
---|
248 | m[2] = IN.TexCoord3;
|
---|
249 | half3 Nw = mul(m, N.xyz);
|
---|
250 | Nw = normalize(Nw);
|
---|
251 |
|
---|
252 | // reflection
|
---|
253 | float3 E = normalize(IN.eyeVector);
|
---|
254 | half3 R = reflect(-E, Nw);
|
---|
255 |
|
---|
256 | half4 reflection = texCUBE(EnvironmentMap, R);
|
---|
257 | // hdr effect (multiplier in alpha channel)
|
---|
258 | reflection.rgb *= (1.0 + reflection.a*hdrMultiplier);
|
---|
259 |
|
---|
260 | // fresnel - could use 1D tex lookup for this
|
---|
261 | half facing = 1.0 - max(dot(E, Nw), 0);
|
---|
262 | half fresnel = fresnelBias + (1.0-fresnelBias)*pow(facing, fresnelPower);
|
---|
263 |
|
---|
264 | half4 waterColor = lerp(deepColor, shallowColor, facing);
|
---|
265 |
|
---|
266 | float4 result = waterColor*waterAmount + reflection*reflectionColor*reflectionAmount*fresnel;
|
---|
267 |
|
---|
268 | if (forRaytracer) {
|
---|
269 | result.a = (float) ( length( IN.pos2.xyz ) );
|
---|
270 | } else {
|
---|
271 | float3 terr = tex2D(terrainSampler, IN.terrainCoord.xy);
|
---|
272 | result.a = (float)(1.0f - (float)terr.x);
|
---|
273 | }
|
---|
274 |
|
---|
275 | return result;
|
---|
276 | }
|
---|
277 |
|
---|
278 | /*PS_OUTPUT depthPS(v2fdepth IN)
|
---|
279 | {
|
---|
280 | PS_OUTPUT OUT;
|
---|
281 | float depth = IN.texCoord.a;
|
---|
282 | OUT.diffuse = float4(depth, depth, depth, depth);
|
---|
283 | return OUT;
|
---|
284 | }*/
|
---|
285 |
|
---|
286 | depthVertexOutput DepthPassVS(depthVertexInput IN)
|
---|
287 | {
|
---|
288 | depthVertexOutput OUT;
|
---|
289 | float4 P = IN.position;
|
---|
290 |
|
---|
291 | P.y = 0.5f;
|
---|
292 |
|
---|
293 | // sum waves
|
---|
294 |
|
---|
295 | /*float ddx = 0.0, ddy = 0.0;
|
---|
296 | for(int i=0; i<NWAVES; i++) {
|
---|
297 | P.y += evaluateWave(wave[i], P.xz, time);
|
---|
298 | }*/
|
---|
299 |
|
---|
300 | //float4 vertexpos = float4(IN.position.xyz, 1.0);
|
---|
301 | float4 vertexpos = P;
|
---|
302 | float4 eyespace = mul(vertexpos, wvpMatrix);
|
---|
303 | OUT.HPosition = eyespace;
|
---|
304 | float tempDepth = saturate(eyespace.z/FarPlaneMinusNearPlane);
|
---|
305 | IN.texCoord.a = tempDepth;
|
---|
306 | OUT.texCoord = IN.texCoord;
|
---|
307 | return OUT;
|
---|
308 | }
|
---|
309 |
|
---|
310 | pixelOutput DepthPassPS(depthVertexOutput IN)
|
---|
311 | {
|
---|
312 | pixelOutput OUT;
|
---|
313 | float depth = IN.texCoord.a;
|
---|
314 | OUT.color = float4(depth, depth, depth, depth);
|
---|
315 | return OUT;
|
---|
316 | }
|
---|
317 |
|
---|
318 | technique PS20
|
---|
319 | {
|
---|
320 | pass p0
|
---|
321 | {
|
---|
322 | VertexShader = compile vs_3_0 BumpReflectWaveVS(wvpMatrix, worldMatrix, viewInverseMatrix,
|
---|
323 | bumpHeight, textureScale, bumpSpeed, time,
|
---|
324 | waveFreq, waveAmp);
|
---|
325 |
|
---|
326 | PixelShader = compile ps_3_0 OceanPS20(normalMapSampler, envMapSampler, terrainSampler,
|
---|
327 | deepColor, shallowColor, reflectionColor, reflectionAmount, waterAmount,
|
---|
328 | fresnelPower, fresnelBias, hdrMultiplier);
|
---|
329 | }
|
---|
330 | }
|
---|
331 |
|
---|
332 | technique PS20_Depth
|
---|
333 | {
|
---|
334 | pass p0
|
---|
335 | {
|
---|
336 | VertexShader = compile vs_3_0 DepthPassVS();
|
---|
337 |
|
---|
338 | PixelShader = compile ps_3_0 DepthPassPS();
|
---|
339 | }
|
---|
340 | } |
---|