Updated bubble shader.

MATERIAL mat_bubbles
{
flags = tangent;

effect
"
float4 vecFog;
float4 vecLightPos[8];
float4 vecLightColor[8];
float3 vecFalloff = float3(0.f, 0.f, 2.f);
float4 vecSunDir;
float4 vecSunDiffuse = float4(200.f/255.f, 200.f/255.f, 200.f/255.f, 1.f);

matrix matWorldViewProj;
matrix matWorld;
matrix matWorldView;

float4 DoSunLight(float3 N)
{
// modulate the sunlight by the surface angle
return vecSunDiffuse * dot(N,-vecSunDir);
}

float DoFog(float3 Pos)
{
// convert the vector position to view space to get it's depth (.z)
float3 P = mul(Pos,matWorldView);
// apply the linear fog formula
return saturate((vecFog.y-P.z) * vecFog.z);
}




float4 DoPointLight(float3 P, float3 N, int i)
{
// calculate the light ray pointing from the light to the surface
float3 D = (float3)vecLightPos-P;
// calculate the angle between surface and light ray
float NdotL = dot(N,normalize(D));
// modulate the light by the surface angle
float4 Color = vecLightColor * NdotL;

// calculate the light attenuation factor, DX uses a really strange formula here
float fac = 0.f;
if (NdotL >= 0.f && vecLightPos.w > 0.f)
{
// get the distance factor
float LD = length(D)/vecLightPos.w;
#ifdef DXLIGHTING
if (LD < 1.3f)
fac = 1.f/(vecFalloff.x + vecFalloff.y*LD + vecFalloff.z*LD*LD);
#else // linear Lighting
if (LD < 1.f)
fac = 1.f - LD;
#endif
}
return Color * fac;
}



texture entSkin1;
texture entSkin2;

vector vecSkill41;


struct VS_OUT // Output to the pixelshader fragment
{
float4 Pos : POSITION;
float4 Color: COLOR0;
float Fog: FOG;

};


VS_OUT Test_VS(

float4 inPos : POSITION,
float3 inNormal : NORMAL)
{
VS_OUT Out;

// transform the vector position to screen coordinates
Out.Pos = mul(inPos,matWorldViewProj);

// transform the normal and the position
float3 N = normalize(mul(inNormal,matWorld));
float3 P = mul(inPos,matWorld);
// Add ambient and sun light
Out.Color = vecSkill41.w + DoSunLight(N);
// Add 6 dynamic lights (maximum for vs 1.1)
for (int i=0; i<6; i++)
Out.Color += DoPointLight(P,N,i);
// Add fog
Out.Fog = DoFog(inPos);

// convert texture coordinates or do other stuff


return Out;
}

technique bubbles
{
pass p0
{
Texture[0] = <entSkin1>; //basemap
Texture[1] = <entSkin2>; //cubemap


VertexShaderConstant[0] = {0.0,0.5,1.0,2.0};
VertexShaderConstant[1] = {4.0f, 1.570909f,3.141818f, 6.283636f} ;
VertexShaderConstant[2] = {1.0f,-1.0f/6.0f, 1.0f/120.0f, -1.0f/5040.0f};
VertexShaderConstant[3] = {1.0f/2.0f, -1.0f/24.0f, 1.0f/720.0f, -1.0f/40320.0f};
VertexShaderConstant[4] = <matWorldViewProj>; //Composite World-View-Projection Matrix
VertexShaderConstant[8] = {0,0,100,1};
VertexShaderConstant[10] = {1.02, 0.04, 0, 0}; //fixup factor for Taylor series imprecision
VertexShaderConstant[11] = {0.5, 0.5, 0.25, 0.25}; //waveHeight0, waveHeight1, waveHeight2, waveHeight3
VertexShaderConstant[12] = {0.0, 0.0, 0.0, 0.0}; //waveOffset0, waveOffset1, waveOffset2, waveOffset3
VertexShaderConstant[13] = {0.6, 0.7, 1.2, 1.4}; //waveSpeed0, waveSpeed1, waveSpeed2, waveSpeed3
VertexShaderConstant[14] = {0.0, 2.0, 0.0, 4.0}; //waveDirX0, waveDirX1, waveDirX2, waveDirX3
VertexShaderConstant[15] = {2.0, 0.0, 4.0, 0.0}; //waveDirY0, waveDirY1, waveDirY2, waveDirY3
VertexShaderConstant[16] = <vecSkill41>;
VertexShaderConstant[17] = {-0.00015, 1.0, 0.0, 0.0}; //base texcoord distortion x0, y0, x1, y1
VertexShaderConstant[18] = <matWorld>;


PixelShaderConstant[0] = {0.0, 0.5, 1.0, -0.75};
PixelShaderConstant[1] = {0.6, 0.1, 0.0, 0.0}; // Alpha Scale and bias



VertexShader =

asm{

vs.1.1

dcl_position v0
dcl_normal v1
dcl_texcoord v2
dcl_tangent v3


mul r0, c14, v2.x // use tex coords as inputs to sinusoidal warp
mad r0, c15, v2.y, r0 // use tex coords as inputs to sinusoidal warp

mov r1, c16.x // time...
mad r0, r1, c13, r0 // add scaled time to move bumps according to frequency
add r0, r0, c12
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 // multiply by fixup factor (due to inaccuracy of taylor series)
sub r0, r0, c0.y // subtract .5
mul r0, r0, c1.w // mult 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!

dp4 r0, r4, c11 // multiply wave heights by waves

mul r0, r0, v1 // apply deformation in direction of normal

add r0.xyz, r0, v0 // add to position
mov r0.w, c0.z // homogenous component


m4x4 oPos, r0, c4 // OutPos = WorldSpacePos * Composite View-Projection Matrix
mov oT0, v2 // Pass along texture coordinates

//This is where the shader starts to diverge a bit from the Ocean shader. First the binormal is computed

mov r3, v1
mul r4, v3.yzxw, r3.zxyw
mad r4, v3.zxyw, -r3.yzxw, r4 // cross product to find binormal

//Then the normal is warped based on the tangent space basis vectors (tangent and binormal).

mul r1, r5, c11 // cos * waveheight
dp4 r9.x, -r1, c14 // amount of normal warping in direction of binormal
dp4 r9.y, -r1, c15 // amount of normal warping in direction of tangent
mul r1, r4, r9.x // normal warping in direction of binormal
mad r1, v3, r9.y, r1 // normal warping in direction of tangent
mad r5, r1, c10.y, v1 // warped normal move nx, ny: cos * wavedir * waveheight

//The normal is then renormalized.

mov r10, r5
m3x3 r5, r10, c18 // transform normal
dp3 r10.x, r5, r5
rsq r10.y, r10.x
mul r5, r5, r10.y // normalize warped normal

// Next the view vector is computed:
mov r10, r0
m4x4 r0, r10, c18 // transform vertex position

sub r2, c8, r0 // view vector
dp3 r10.x, r2, r2
rsq r10.y, r10.x
mul r2, r2, r10.y // normalized view vector

; Then the dot product of the view vector and the warped normal is computed:

dp3 r7, r5, r2 // N.V
mov oT2, r7 // Pass along N.V

// This is used to compute the reflection vector.

add r6, r7, r7 // 2N.V
mad r6, r6, r5, -r2 // 2N(N.V)-V
mov oT1, r6 // reflection vector


};

/////////////ps///////////////
// c0 - (0.0, 0.5, 1.0, -0.75)
// c1 - (0.6, 0.1, 0.0, 0.0) Alpha Scale and bias


pixelshader=
asm
{


ps.1.4

texld r0, t0
texld r1, t1
texcrd r2.rgb, t2


cmp r2.r, r2.r, r2.r, -r2.r // abs(V.N)
+mad_x4_sat r1.a, r1.a, r1.a, c0.a // 4 * (a^2 - .75), clamped


mul_x2_sat r2.rgb, r0, r1 // base * env (may change scale factor later)
+mad r2.a, 1-r2.r, c1.x, c1.y // alphascale * abs(V.N) + alphabias


lrp r0.rgb, r1.a, r1, r2 // Lerp between Env and Base*Env based on glow map
+add r0.a, r2.a, r1.a // Add glow map to Fresnel term for alpha

};
}
}


";
}


//------
var count;

ACTION bubbles
{
my.material = mat_bubbles;
while(1)
{
my.skill41=float(count);
my.skill42=float(0);
my.skill43=float(0);
my.skill44=float(0);
count += 0.07*time;
wait(1);
}
}