float4 g_fResolution : register(c0); float3 g_vLightDir : register(c1); float3 g_vViewPos : register(c2); float3 g_fTime : register(c3); sampler2D waveSampler : register(s0); sampler2D reflectionSampler : register(s1); sampler2D refractionSampler : register(s2); sampler1D specSampler : register(s3); sampler2D shadowSampler : register(s4); sampler2D depthSampler : register(s5); static float g_fTileHardness = .6f; static float g_fTileDepth = 8.f; static float g_fBumpDepth = .75f; static float g_fTexScale = 0.1f; static float3 g_vTexSpeed = float3(0.04f, 0.0f, 0.04f); static float g_fSpecularPower = 0.5f; static float g_fSpecularHardness = 128.f; static float4 g_vWaveDirX = float4(0.07f, -0.035f, 0.03f, -0.05f); static float4 g_vWaveDirY = float4(0.07f, 0.005f, 0.11f, -0.09f); static float3 g_vWaveVec = float3(4.0f, 0.0f, 0.9f); static float3 g_vWaveVecOrtho = 0.2f * float3(-0.9f, 0.0f, 4.0f); static float4 g_fWaveScale = float4(0.2f, 0.1f, 0.3f, 0.7f); static float4 g_fWaveNoise = float4(1.0f, 2.0f, 3.0f, 4.0f); //static float4 g_fWaveDistortion = float4(0.025f, 0.15f, 0.1f, 0.05f); static float4 g_fWaveDistortion = float4(0.025f, 0.1f, 0.03f, 0.01f); static float4 g_fWaveVariation = float4(3.0f, 4.0f, 17.0f, 23.0f); static float4 g_fWaveHeightVariation = float4(9.0f, 4.0f, 1.0f, 0.5f); static float4 g_fLightFilterColor = float4(0.3f, 0.45f, 0.5f, 0.99f); static float4 g_fFogColor = float4(0.1f, 0.18f, 0.17f, 0.0f); struct psIn { float2 t : TEXCOORD0; float3 n : TEXCOORD1; float3 v : TEXCOORD2; float4 s : TEXCOORD3; float3 w : TEXCOORD4; }; float4 ps_main(psIn i) : COLOR0 { float st = g_fTime.z * 0.000035f; float wt = (0.75f + 0.25f * sin(st)) * 0.05f; float3 t = i.w * g_fTexScale; float3 dt = st * g_fTexScale * g_vTexSpeed; float3 bx = float3(2.0f, 1.0f, 0.0f); float4 fWave11 = tex2D(waveSampler, 0.13f * (t + 8 * dt).xz).xzyw * bx.xyxy - bx.yzyz; float4 fWave12 = tex2D(waveSampler, 0.13f * (t - 8 * dt).zx).xzyw * bx.xyxy - bx.yzyz; float4 fWave21 = tex2D(waveSampler, (t + 2 * dt).xz).xzyw * bx.xyxy - bx.yzyz; float4 fWave22 = tex2D(waveSampler, (t - 2 * dt).zx).xzyw * bx.xyxy - bx.yzyz; float4 fWave31 = tex2D(waveSampler, 11.0f * (t + 0.5f * dt).xz).xzyw * bx.xyxy - bx.yzyz; float4 fWave32 = tex2D(waveSampler, 11.0f * (t - 0.5f * dt).zx).xzyw * bx.xyxy - bx.yzyz; float3 fWaveWeights = 1.0f; // float3(1.0f, 0.5f, 0.25f); // Decode float4 fWave = (fWave11 * fWaveWeights.x + fWave21 * fWaveWeights.y + fWave31 * fWaveWeights.z + fWave12 * fWaveWeights.x + fWave22 * fWaveWeights.y + fWave32 * fWaveWeights.z) / dot(fWaveWeights, 2.0f); fWave.xyz += (reflect(fWave11.xyz, fWave12.xyz) * fWaveWeights.x + reflect(fWave21.xyz, fWave22.xyz) * fWaveWeights.y + reflect(fWave31.xyz, fWave32.xyz) * fWaveWeights.z) / dot(fWaveWeights, 1.0f); fWave.y *= sign(fWave.y) * 11.0f; float3 vNormal = normalize(fWave.xyz); float4 fBigWaveX = g_vWaveDirX * i.w.x; fBigWaveX += g_vWaveDirY * i.w.z; fBigWaveX += fWave.w * 3 + st * 0.2f; fBigWaveX -= round(fBigWaveX); float4 fBigWave = 8.1688f * sin(fBigWaveX) * 0.02f; float4 fBigWaveLength = 1.0f / sqrt(g_vWaveDirX * g_vWaveDirX + g_vWaveDirY * g_vWaveDirY); float fNormalDisplacement = 1.0f - saturate( dot(i.v, i.v) / 300000.0f + fwidth(dot(i.v, i.v)) / 5000.0f ); vNormal.x -= dot(fBigWave, g_vWaveDirX * fBigWaveLength) * fNormalDisplacement; vNormal.z -= dot(fBigWave, g_vWaveDirY * fBigWaveLength) * fNormalDisplacement; vNormal = normalize(vNormal); // Determine whether under water float4 fSubmerged = g_vViewPos.y - 5.0f; fSubmerged.y = sign(fSubmerged); fSubmerged.z = saturate(fSubmerged.y); fSubmerged.w = saturate(-fSubmerged.y); // Invert normal under water vNormal.y *= fSubmerged.y; // Evaluate fresnel term float3 vToEyeDir = normalize(i.v); float fFresnel = 1.0f - saturate( dot(vNormal, vToEyeDir) ); float fPlaneFresnel = 1.0f - abs( dot(i.n, vToEyeDir) ); fFresnel = lerp( fPlaneFresnel, max( fFresnel, fPlaneFresnel ), 0.5f ); fFresnel = saturate( pow(fFresnel, 5) ); // Compute refraction float2 vRefractionOffset = vNormal.xz * lerp( 0.02f, 0.005f, saturate(dot(i.v, i.v) / 1000.0f) ); float2 vRefractionCoord = i.s.xy / i.s.w; // Compute depths float fEyeDepth = tex2D(depthSampler, vRefractionCoord).x; float fEyeRefractionDepth = tex2D(depthSampler, vRefractionCoord + vRefractionOffset).x; // Compute fades float fWaterFade = saturate( 1.0f * abs(i.s.z - fEyeDepth) ); float fRefractionFade = 1.0f - saturate(10.0f * (i.s.z - fEyeRefractionDepth)); // Compute corrected refraction coords vRefractionCoord += vRefractionOffset * fRefractionFade * fWaterFade; // Fade water fFresnel *= fWaterFade; float fTransmissivity = saturate(2.0f - fFresnel - fWaterFade); // Colorize float3 fColor = lerp( g_fFogColor.xyz, float3(0.8f, 0.8f, 0.85f) * tex2D(reflectionSampler, vRefractionCoord).xyz, fSubmerged.z ) * fFresnel; fColor += tex2D(refractionSampler, vRefractionCoord).xyz * fTransmissivity; // Specular highlights float3 vHalf = normalize( vToEyeDir + -g_vLightDir ); float fSpecularity = saturate( dot(vNormal, vHalf) ); // * tex2Dproj(shadowSampler, i.s).x; fColor += g_fSpecularPower * pow(fSpecularity, g_fSpecularHardness) * fWaterFade; return float4(fColor, 1.0f); }