Jump to content


Water with distortion


5 replies to this topic

#1 Guest_graphicboy_*

  • Guests

Posted 21 October 2004 - 11:04 AM

Posted Image

Description
The screenshot shows water with distortion effects.

Implementation details:

1. Render water using 2 passes;
2. In first pass, I render the scene into reflective-texture with mirror transform matrix;
3. In second pass, I render the water with reflective-texture;
4. In order to add distortion to water, I grab the normal from the normal-map in Water-Pixel Shader code (provided below) and add this normal to the texture coordinates for grabing the reflective-texture.

Advantages of this method:

1. Rendering water whose area is large just needs two triangle;
2. Normal-map is repeated, which means the normal-map can be low-resolution;

I think this method is suitable for rendering huge water with low triagles and low memory foot-print;

Here's the pixel shader program:

struct VS_OUTPUT
{
    float4 Pos     : POSITION;
    float4 Tex0    : TEXCOORD0;
    float2 Tex1    : TEXCOORD1;
};

VS_OUTPUT VS(float4 Pos  : POSITION,
    	     float2 Tex  : TEXCOORD0)
{
    VS_OUTPUT Out;

 	Out.Pos  = mul(Pos, modelViewProj);
 	Out.Tex0 = mul(Pos, texTransform);
	Out.Tex1 = Tex;	

	return Out;
}

sampler sReflect = sampler_state
{
    Texture   = (tReflect);
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
	ADDRESSU  = CLAMP;
	ADDRESSV  = CLAMP;
};

sampler sAlpha = sampler_state
{
    Texture   = (tDepth);
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
	ADDRESSU  = CLAMP;
	ADDRESSV  = CLAMP;
};

sampler sNormal = sampler_state
{
    Texture   = (tNormal);
    MipFilter = LINEAR;
    MinFilter = LINEAR;
    MagFilter = LINEAR;
	ADDRESSU  = WRAP;
	ADDRESSV  = WRAP;
};

float4 PS(VS_OUTPUT In) : COLOR
{	
	float4 Out;	
	
	// grab value from depth map as alpha
	Out.w = tex2D(sAlpha, In.Tex1).w;
	
	// scale tex coordinate for repeat normal map
	float2 rUv;
	
	rUv.x = In.Tex1.x*uNormalRep;
	rUv.y = In.Tex1.y*vNormalRep;

	// grab value from normal map
	float3 nor = tex2D(sNormal, rUv).xyz;
	
	// scale and offset from [0,1] into [-1,1]
	nor.x = nor.x * 2.0f - 1.0f;
	nor.y = nor.y * 2.0f - 1.0f;
	nor.z = nor.z * 2.0f - 1.0f;

	// normal scale
	float eff = fNormalScale*In.Tex0.w;
	
	// offset tex coordinate for reflective texture with normal 
	float4 Uv = In.Tex0;
	
	Uv.x += nor.x*eff;
	Uv.y += nor.y*eff;
	Uv.z += nor.z*eff;
	
	// grab value from reflective map
	Out.xyz = tex2Dproj(sReflect, Uv).xyz;

	// lerp value between water constant value and reflective value
	// Out = lerp(crlWater, Out, Out.w);
	return Out;
}


#2 NomadRock

    Senior Member

  • Members
  • PipPipPipPip
  • 785 posts

Posted 21 October 2004 - 11:49 PM

Looks good, but the water blends too well into the land, there are areas where I can't tell where the land stops and the water starts.
Jesse Coyle

#3 bladder

    DevMaster Staff

  • Members
  • PipPipPipPip
  • 1057 posts

Posted 22 October 2004 - 12:16 AM

Yeah, it looks great except for where the land and water blend in. If you could make some (I forget the name of the white noise on top of water waves) surf (??) as the water hits the edges, it would look sweet!! But I suppose doing that you'll need to calculate the intersection of the water with the land - and that will add quite a bit more complexity...

#4 Dia

    DevMaster Staff

  • Administrators
  • 1120 posts

Posted 22 October 2004 - 01:58 AM

I like the fact that you have provided implementation details and some code. This is what developers benefit from the most besides seeing some eye candy.
Nice job!

#5 SnprBoB86

    Valued Member

  • Members
  • PipPipPip
  • 112 posts

Posted 22 October 2004 - 10:38 PM

Good work!
Brandon Bloom
http://brandonbloom.name

#6 SYS49152

    Member

  • Members
  • PipPip
  • 57 posts

Posted 28 October 2004 - 10:11 AM

the water looks great. cool that you share the shader-file. :)
you should add some detail texturing.

nice job !

- Andy





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users