[1378] | 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 | } |
---|