I have converted the Ocean Water Shader from ATI's Rendermonkey into 3DGS. It works very fine. But it was very hard to find a texture which looks very good in this shader.



1.) Here is the Material:
Code:
MATERIAL mat_oceanwater
{
flags = tangent;

effect
"
matrix matWorldViewProj;
matrix matWorld;
matrix matWorldView;

texture entSkin1; //first skin is a water texture
texture entSkin2; //second skin is a normalmap
texture entSkin3; //third skin is a texture with blue colors

vector vecSkill41;

technique oceanwater
{
pass p0
{
Texture[0] = <entSkin2>;
Texture[1] = <entSkin2>;
Texture[2] = <entSkin1>;
Texture[3] = <entSkin3>;

VertexShaderConstant[0]={0f,0.5f,1f,2f};
VertexShaderConstant[1]={0.85f,1.7f,3.14f,6.28f};
VertexShaderConstant[2]={0f,0f,0f,0f};
VertexShaderConstant[3]={0.5f,-0.04167f,0.00139f,-0.00002f};
VertexShaderConstant[4]=<matWorldViewProj>;
VertexShaderConstant[8]={0f,0f,0f,1f};
VertexShaderConstant[9]={0f,0f,0f,1f};
VertexShaderConstant[10]={0.98f,0.003f,0f,0f};
VertexShaderConstant[11]={0f,0f,0f,0f};
VertexShaderConstant[12]={0f,0.2f,0f,0f};
VertexShaderConstant[13]={0.45f,0.1f,0.221f,0.04f};
VertexShaderConstant[14]={6.22f,-2.2f,0.55f,2.12f};
VertexShaderConstant[15]={4f,-2.33f,2.5f,0f};
VertexShaderConstant[16]=<vecSkill41>;
VertexShaderConstant[18]={0.1f,0.1f,0.1f,0.1f};
VertexShaderConstant[19]={0.05f,0.055f,0f,1f};
VertexShaderConstant[90]={1f,0f,0f,0f}; //damit oFog gefüllt ist

PixelShaderConstant[1]={0.129f,0.415f,0.864f,0.839f};

VertexShader =
decl
{
stream 0;
float v0[3]; //Position
float v3[3]; //Normal
float v7[3]; //Textur Koordinaten 0
float v8[3]; //Textur Koordinaten 0
}
asm
{
vs.1.1

mul r0, c14, v7.x
mad r0, c15, v7.y, r0

mov r1, c16.x // time...
mad r0, r1, c13, r0 // add scaled time to move bumps according to freq
add r0, r0, c12 // starting time offset
frc r0.xy, r0 // take frac of all 4 components
frc r1.xy, r0.zwzw //
mov r0.zw, r1.xyxy //

mul r0, r0, c10.x // mul by fixup (due to inaccuracy)
sub r0, r0, c0.y // subtract 0.5
mul r0, r0, c1.w // mul tex coords by 2pi (coords range from -pi to pi)

mul r5, r0, r0 // (wave vec)^2
mul r1, r5, r0 // (wave vec)^3
mul r6, r1, r0 // (wave vec)^4
mul r2, r6, r0 // (wave vec)^5
mul r7, r2, r0 // (wave vec)^6
mul r3, r7, r0 // (wave vec)^7
mul r8, r3, r0 // (wave vec)^8

mad r4, r1, c2.y, r0 // (wave vec) ((wave vec)^3)/3!
mad r4, r2, c2.z, r4 // + ((wave vec)^5)/5!
mad r4, r3, c2.w, r4 // ((wave vec)^7/7!

mov r0, c0.z // 1
mad r5, r5, c3.x, r0 // -(wave vec)^2/2!
mad r5, r6, c3.y, r5 // +(wave vec)^4/4!
mad r5, r7, c3.z, r5 // -(wave vec)^6/6!
mad r5, r8, c3.w, r5 // +(wave vec)^8/8!

sub r0, c0.z, c0.x //... 1-wave scale
mul r4, r4, r0 // scale sin
mul r5, r5, r0 // scale cos

dp4 r0, r4, c11 // mul by wave heights

mul r0.xyz, v3, r0 // mul wave mag at this vertex by normal
add r0.xyz, r0, v0 // add to position
mov r0.w, c0.z // homogenous component

m4x4 oPos, r0, c4 // Outpos = ObjSpace * World-view-proj matrix

mul r1, r5, c11 // cos * wave height
dp4 r9.x, -r1, c14 // normal x offset
dp4 r9.yzw, -r1, c15 // normal y offset and tangent offset
mov r5, v3 // starting normal
mad r5.xy, r9, c10.y, r5 //warped normal move nx, ny according to
// cos*wavedir*waveheight
mov r4, v8 // tangent
mad r4.z, -r9.x, c10.y, r4.z // warped tangent vector

dp3 r10.x, r5, r5 // normalize the normal
rsq r10.y, r10.x
mul r5, r5, r10.y

dp3 r10.x, r4, r4 // normalize the tangent
rsq r10.y, r10.x
mul r4, r4, r10.y

mul r3, r4.yzxw, r5.zxyw // xprod to find binormal
mad r3, r4.zxyw, -r5.yzxw, r3


mov r6, c8 // get eye pos into object space
m4x4 r2, r6, c20

sub r2, r2, r0 // find view vector

dp3 r10.x, r2, r2 // normalize view vector
rsq r10.y, r10.x
mul r2, r2, r10.y

mov r0, c16.x
mul r0, r0, c18.xyxy
frc r0.xy, r0 // frac of incoming time
add r0, v7, r0 // add time to tex coords
mov oT0, r0 // output tex coords

mov r0, c16.x
mul r0, r0, c18.zwzw
frc r0.xy, r0 // frac of incoming time
add r0, v7, r0 // add time to tex coords
mov oT1, r0.yxzw // output distorted tex coord1

mov oT2, r2 // pass in view vector (world space)
mov oT3, r3 // tangent
mov oT4, r4 // binormal
mov oT5, r5 // normal
mov oFog,c90
};
pixelshader=
asm
{
ps.1.4

def c0, 0.5, 0.5, 0.5, 1.0;

texld r0, t0 // bump map 0
texld r1, t1 // bump map 1
texcrd r2.rgb, t2 // view vec
texcrd r3.rgb, t3 // tangent
texcrd r4.rgb, t4 // binormal
texcrd r5.rgb, t5 // normal

add_d4 r0.xy, r0_bx2, r1_bx2 // scaled avg of 2 bumpmap xy offsets

mul r1.rgb, r0.x, r3 // put bump maps into world space
mad r1.rgb, r0.y, r4, r1
mad r1.rgb, r0.z, r5, r1

dp3 r0.rgb, r1, r2 // V.N
mad r2.rgb, r1, r0_x2, -r2 // R = 2N(V.N)-V

mov_sat r0.rgb, r0_x2 // 2 * V.N (sample over range of 1D map)

phase

texld r2, r2 // env map
texld r3, r0 // index frenel map using 2*N.V

mul r2.rgb, r2, r2 // square env map
+mul r2.a, r2.g, r2.g // use green of env as specular
mul r2.rgb, r2, 1-r0.r // fresnel term
+mul r2.a, r2.a, r2.a // specular ^4

add_d4_sat r2.rgb, r2, r3_x2 // += water color
+mul r2.a, r2.a, r2.a // specular ^8

mad_sat r0, r2.a, c1, r2
};
}
}

technique fallback
{
pass p0
{
TEXTURE[0] = <entSkin1>;
COLOROP[0] = modulate;
}
}
";
}



2.) Here is the Action for the water entity:
Code:

var count;

ACTION water_fx
{
my.material = mat_oceanwater;
while(1)
{
my.skill41=float(count);
my.skill42=float(0);
my.skill43=float(0);
my.skill44=float(0);
count += 0.005*time; //U Texcoord
wait(1);
}
}



3.) Here is my water model with the 3 textures you need:
water.mdl

The shader needs Vertexshader 1.1 and Pixelshader 1.4.