Jump to content
  • Advertisement
Sign in to follow this  
yuppies

Simple Water rendering in DX

This topic is 4887 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

how can i render a simple water like for example a lake or something for my map? im planning to use a big Mesh for my map and implement an OCTREE for it? do i need to model the water along the mesh or it will be a separate object?

Share this post


Link to post
Share on other sites
Advertisement
Hi there yuppies,
How are you doing?

Well I would say the easiest way to render nice water would be to introduce yourself to shaders. Water rendering would also introduce you to other elements of graphics programming namely bump mapping.

To get you started I will link you to a demo of mine that I did that includes normal mapping (bump mapping) and water and a normal mapping shader. I load them as effects in DX. So you will need to read through the DX Docs or a tutorial to get you started on loading effects/shaders.

The Normal Mapping & Bump mapping demo (You need a pixel shader 2.0 compatible graphics card)

[source lang = cpp]
//Bumpmap.fx
float4x4 ModelViewProj : WORLDVIEWPROJ; //our world view projection matrix
float4x4 ModelViewIT : WORLDVIEWIT; //our inverse transpose matrix
float4x4 ModelWorld : WORLD; //our world matrix
float4 lightPos; //our light position

texture texture0;
texture texture1;

sampler2D texSampler0 : TEXUNIT0 = sampler_state
{
Texture = (texture0);
MIPFILTER = LINEAR;
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
};
sampler2D texSampler1 : TEXUNIT1 = sampler_state
{
Texture = (texture1);
MIPFILTER = LINEAR;
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
};

//application to vertex structure
struct a2v
{
float4 position : POSITION0;
float3 normal : NORMAL;
float2 tex0 : TEXCOORD0;
float3 tangent : TANGENT;
float3 binormal : BINORMAL;
};

//vertex to pixel shader structure
struct v2p
{
float4 position : POSITION0;
float2 tex0 : TEXCOORD0;
float2 tex1 : TEXCOORD1;
float3 lightVec : TEXCOORD2;
float att : TEXCOORD3;
};

//pixel shader to screen
struct p2f
{
float4 color : COLOR0;
};

//VERTEX SHADER
void vs( in a2v IN, out v2p OUT )
{
//getting to position to object space
OUT.position = mul(IN.position, ModelViewProj);

//getting the position of the vertex in the world
float4 posWorld = mul(IN.position, ModelWorld); //IN.position;

//getting vertex -> light vector
float3 light = normalize(lightPos - posWorld);

//calculating the binormal and setting the Tangent Binormal and Normal matrix
float3x3 TBNMatrix = float3x3(IN.tangent, IN.binormal , IN.normal);

//setting the lightVector
OUT.lightVec = mul(TBNMatrix, light);

//calculate the attenuation
OUT.att = 1/( 1 + ( 0.005 * distance(lightPos.xyz, posWorld) ) );

OUT.tex0 = IN.tex0;
OUT.tex1 = IN.tex0;
}

//PIXEL SHADER
void ps( in v2p IN, out p2f OUT )
{
//calculate the color and the normal
float4 color = tex2D(texSampler0, IN.tex0);

/*this is apparently how you uncompress a normal map*/
float3 normal = 2.0f * tex2D(texSampler1, IN.tex1).rgb - 1.0f;

//normalize the light
float3 light = normalize(IN.lightVec);

//set the output color
float diffuse = saturate(dot(normal, light));

//multiply the attenuation with the color
OUT.color = IN.att * color * diffuse;
}

technique test
{
pass p0
{
vertexshader = compile vs_1_1 vs();
pixelshader = compile ps_2_0 ps();
}
}




[source lang = cpp]
//Water.fx
float4x4 ModelViewProj : WORLDVIEWPROJ; //our world view projection matrix
float4x4 ModelWorld;
float4 eyePos;
float4 lightPos;
float time;

texture texture0;
texture texture1;

sampler2D texSampler : TEXUNIT0 = sampler_state
{
Texture = (texture0);
MIPFILTER = LINEAR;
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
};

samplerCUBE cubeSampler : TEXUNIT1 = sampler_state
{
Texture = (texture1);
MIPFILTER = LINEAR;
MAGFILTER = LINEAR;
MINFILTER = LINEAR;
};

//application to vertex structure
struct a2v
{
float4 position : POSITION;
float3 normal : NORMAL;
float2 tex0 : TEXCOORD0;
float3 tangent : TANGENT;
float3 binormal : BINORMAL;
};

//vertex to pixel shader structure
struct v2p
{
float4 position : POSITION;
float2 tex0 : TEXCOORD0;
float2 tex1 : TEXCOORD1;
float3 eyeVec : TEXCOORD2;
float3 lightVec : TEXCOORD3;
float att : TEXCOORD4;
};

//pixel shader to screen
struct p2f
{
float4 color : COLOR0;
};

//VERTEX SHADER
void vs( in a2v IN, out v2p OUT )
{
//getting to position to object space
OUT.position = mul(IN.position, ModelViewProj);

//getting the position of the vertex in the world
float4 posWorld = mul(IN.position, ModelWorld); //IN.position;

//getting vertex -> light vector
float3 eye = eyePos.xyz - posWorld.xyz;
float3 light = lightPos.xyz - posWorld.xyz;

//calculating the binormal and setting the Tangent Binormal and Normal matrix
float3x3 TBNMatrix = float3x3(IN.tangent, IN.binormal , IN.normal);

//setting the lightVector
OUT.eyeVec = normalize(mul(TBNMatrix, eye));
OUT.lightVec = normalize(mul(TBNMatrix, light));

OUT.att = 1/( 1 + ( 0.005 * distance(lightPos.xyz, posWorld) ) );

OUT.tex0 = IN.tex0;
OUT.tex1 = IN.tex0;
}

//PIXEL SHADER
void ps( in v2p IN, out p2f OUT )
{
float3 normal = 2.0f * tex2D(texSampler, (0.5 * IN.tex0) + (time * 0.5)).rgb - 1.0f; //the normal map
float3 normal1 = 2.0f * tex2D(texSampler, (1 * IN.tex0) + (time * 2)).rgb - 1.0f; //the normal2nd map
float3 normal2 = 2.0f * tex2D(texSampler, (2 * IN.tex0) + (time * 4)).rgb - 1.0f; //the normal3rd map

float3 eye = normalize(IN.eyeVec); //our eye vector normalized

float3 finalNormal = normalize(normal + normal1 * 2 + normal2 * 4);

float3 reflectVector = reflect(eye, finalNormal); //getting the reflection vector and a surface to eye vector

float4 color = texCUBE(cubeSampler, reflectVector); //our cube sampler

float3 light = normalize(IN.lightVec);

float diffuse = saturate(dot(finalNormal, light));

//multiply the attenuation with the color
OUT.color = 2.0 * IN.att * color * diffuse;

}

technique test
{
pass p0
{
vertexshader = compile vs_1_1 vs();
pixelshader = compile ps_2_0 ps();
}
}




If you have any problems on the details I left out, do not hesitate to ask :)
I hope you got some information out of me :)

PS: With my water, I made it a seperate mesh and ontop of the mesh I placed a texture. What then happens is that the shader creates 3 planes if you will and scrolls each one of them at a different speed. It's the same shader as the bump map but it just scrolls the texture across a mesh.

Share this post


Link to post
Share on other sites
Quote:
how can i render a simple water like for example a lake or something for my map?
im planning to use a big Mesh for my map and implement an OCTREE for it? do i need to model the water along the mesh or it will be a separate object?
What kind of "simple" water do you mean? For instance a flat quad textured with a tiled water image might work. If you want the water animated then you could either manipulate the texture coordinates or move the quad slowly and then occasionally reset it to its original position to create the illusion of continuous movement. That's simple water to me. For waves and reflection you might want to look into a shader implementation.

You could also check out this page for more info on water rendering.

Share this post


Link to post
Share on other sites
Quote:
Original post by noaktree
What kind of "simple" water do you mean? For instance a flat quad textured with a tiled water image might work. If you want the water animated then you could either manipulate the texture coordinates or move the quad slowly and then occasionally reset it to its original position to create the illusion of continuous movement. That's simple water to me. For waves and reflection you might want to look into a shader implementation.


Wow, complex. Simple water to me means a big blue flat polygon [grin]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!