rendered paste body//------- Constants --------
#define NWAVES 2
float4x4 View : VIEW;
float4x4 Projection : PROJECTION;
float4x4 World : WORLD;
float4x4 WorldViewProj : WORLDVIEWPROJECTION;
float4x4 ReflectionView;
float4x4 WindDirection = {-0.00000004371139, 1.0, 0.0, 0.0, -1.0, -0.00000004371139, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0};
float Time : TIME;
float WaveLength = 0.09f;
float WaveHeight = 0.1f;
float WindForce = 0.11f;
float2 WaterVelocity = {0, 5};
float4 DullColor = float4(0.0f, 0.05f, 0.1f, 1.0f);
float DullBlendFactor = 0.5f;
float WaterHeight = 10;
float WaveAmp = 0.9;
float WaveFreq = 0.05;
float ReflectionStrength = 0.35f;
Texture ReflectionMap;
Texture RefractionMap;
Texture WaterBumpMap;
struct Wave {
float freq; // 2*PI / wavelength
float amp; // amplitude
float phase; // speed * 2 * PI / wavelength
float2 dir;
};
Wave wave[NWAVES] = {
{ 0.1, 0.1, 0.5, float2(0.1, 1.2) },
{ 0.2, 0.05, 1.3, float2(0.3, 0.8) }
};
float evaluateWave(Wave w, float2 pos, float t)
{
return w.amp * sin(dot(w.dir, pos) * w.freq + t * w.phase);
}
// derivative of wave function
float evaluateWaveDeriv(Wave w, float2 pos, float t)
{
return w.freq * w.amp * cos(dot(w.dir, pos) * w.freq + t * w.phase);
}
// sharp wave functions
float evaluateWaveSharp(Wave w, float2 pos, float t, float k)
{
return w.amp * pow(sin(dot(w.dir, pos) * w.freq + t * w.phase) * 0.5 + 0.5 , k);
}
float evaluateWaveDerivSharp(Wave w, float2 pos, float t, float k)
{
return k * w.freq * w.amp * pow(sin(dot(w.dir, pos) * w.freq + t * w.phase) * 0.5 + 0.5 , k - 1) * cos( dot(w.dir, pos) * w.freq + t * w.phase);
}
sampler ReflectionSampler = sampler_state
{
Texture = <ReflectionMap>;
Magfilter = LINEAR;
Minfilter = LINEAR;
Mipfilter = LINEAR;
AddressU = mirror;
AddressV = mirror;
};
sampler RefractionSampler = sampler_state
{
Texture = <RefractionMap>;
Magfilter = LINEAR;
Minfilter = LINEAR;
Mipfilter = LINEAR;
AddressU = mirror;
AddressV = mirror;
};
sampler WaterBumpMapSampler = sampler_state
{
Texture = <WaterBumpMap>;
Magfilter = LINEAR;
Minfilter = LINEAR;
Mipfilter = LINEAR;
AddressU = mirror;
AddressV = mirror;
};
struct VS_INPUT
{
float4 Position : Position0;
float3 Normal : NORMAL0;
float2 TexCoord : TexCoord0;
float4 TexWeight : TexCoord1;
};
struct VS_OUTPUT
{
float4 Position : POSITION;
float2 TexCoord : TEXCOORD0;
float4 ReflectionMapSamplingPos : TEXCOORD1;
float2 BumpMapSamplingPos : TEXCOORD2;
float4 RefractionMapSamplingPos : TEXCOORD3;
float4 Position3D : TEXCOORD4;
};
VS_OUTPUT VertexShader(VS_INPUT input)
{
VS_OUTPUT Output = (VS_OUTPUT)0;
wave[0].freq = WaveFreq;
wave[0].amp = WaveAmp;
wave[1].freq = WaveFreq*2.0;
wave[1].amp = WaveAmp*0.5;
float4 Po = float4(input.Position.xyz,1.0);
// sum waves
Po.y = 0.0;
float ddx = 0.0, ddy = 0.0;
for(int i=0; i<NWAVES; i++) {
Po.y += evaluateWaveSharp(wave[i], Po.xz, Time, 2);
float deriv = evaluateWaveDerivSharp(wave[i], Po.xz, Time, 2);
ddx += deriv * wave[i].dir.x;
ddy += deriv * wave[i].dir.y;
}
Output.TexCoord = input.TexCoord;
float4x4 reflProj = mul (ReflectionView, Projection);
float4x4 preViewProjection = mul (View, Projection);
float4x4 preWorldViewProjection = mul (World, preViewProjection);
float4x4 preReflectionViewProjection = mul (ReflectionView, Projection);
float4x4 preWorldReflectionViewProjection = mul (World, preReflectionViewProjection);
Output.Position = mul(Po, preWorldViewProjection);
Output.Position3D = input.Position;
Output.ReflectionMapSamplingPos = mul(input.Position, preReflectionViewProjection);
Output.RefractionMapSamplingPos = mul(input.Position, preWorldViewProjection);
float4 absoluteTexCoords = float4(input.TexCoord, 0, 1);
float4 rotatedTexCoords = mul(absoluteTexCoords, WindDirection);
float2 moveVector = float2(0, 1);
Output.BumpMapSamplingPos = rotatedTexCoords.xy / WaveLength + Time * WindForce * moveVector.xy;
return Output;
}
float4 PixelShader(VS_OUTPUT input) : COLOR0
{
float2 ProjectedTexCoords;
float2 ProjectedRefrTexCoords;
ProjectedTexCoords.x = input.ReflectionMapSamplingPos.x / input.ReflectionMapSamplingPos.w / 2.0f + 0.5f;
ProjectedTexCoords.y = -input.ReflectionMapSamplingPos.y / input.ReflectionMapSamplingPos.w / 2.0f + 0.5f;
ProjectedRefrTexCoords.x = input.RefractionMapSamplingPos.x / input.RefractionMapSamplingPos.w / 2.0f + 0.5f;
ProjectedRefrTexCoords.y = -input.RefractionMapSamplingPos.y / input.RefractionMapSamplingPos.w / 2.0f + 0.5f;
float4 bumpColor = tex2D(WaterBumpMapSampler, input.BumpMapSamplingPos);
float2 perturbation = WaveHeight * (bumpColor.rg - 0.5f);
float2 perturbatedTexCoords = ProjectedTexCoords + perturbation;
float2 perturbatedRefrTexCoords = ProjectedRefrTexCoords + perturbation;
float4 reflectiveColor = tex2D(ReflectionSampler, perturbatedTexCoords);
float4 refractiveColor = tex2D(RefractionSampler, perturbatedRefrTexCoords);
float4 combinedColor = refractiveColor + reflectiveColor * ReflectionStrength;
float4 Color = DullBlendFactor * DullColor + (1 - DullBlendFactor) * combinedColor;
Color.a = 1.0f;
return Color;
}
technique Water
{
pass Pass0
{
VertexShader = compile vs_1_1 VertexShader();
PixelShader = compile ps_2_0 PixelShader();
}
}