All pastes #901998 Raw Edit

Stuff

public text v1 · immutable
·published 2008-02-13 02:09 UTC
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();
    }
}