140 lines
5.2 KiB
Plaintext
140 lines
5.2 KiB
Plaintext
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);
|
|
}
|