Sign in to follow this  
sipickles

Ragged edges to water reflection

Recommended Posts

Hello. To create active water reflection, which reflects in-game objects, I am using a technique like Yann Lonbard's article on GameDev. I never understood how he created the ripples, so instead I used a bumpMap. This works well, except I have ragged edges appearing around the edge of the screen: I think this is because I am wobbling the projected texture coords. Heres my effect file:


float4x4 WorldView : WORLDVIEW;	
float4x4 Projection : PROJECTION;	
float4x4 TexProj;

float bumpHeight = 10.0;
float2 textureScale = { 8.0, 4.0 };
float2 bumpSpeed = { -0.002, 0.000 };

float time = 0.0f;

texture reflectMap;
texture normalMap;

sampler2D reflectMapSampler = sampler_state
{
	Texture = <reflectMap>;
#if 0
	// this is a trick from Halo - use point sampling for sparkles
	MagFilter = Linear;	
	MinFilter = Point;
	MipFilter = None;
#else
	MagFilter = Linear;	
	MinFilter = Linear;
	MipFilter = Linear;
#endif
};

sampler2D normalMapSampler = sampler_state
{
	Texture = <normalMap>;
#if 0
	// this is a trick from Halo - use point sampling for sparkles
	MagFilter = Linear;	
	MinFilter = Point;
	MipFilter = None;
#else
	MagFilter = Linear;	
	MinFilter = Linear;
	MipFilter = Linear;
#endif
};
////////////////////////////////////////////////////////////////////////////

struct VS_INPUT {
	float3 Position : POSITION;   
	float3 Normal   : NORMAL;
    float2 Tex		: TEXCOORD0;
};

struct VS_OUTPUT {
	float4 Position		: POSITION;
    float4 TexProj		: TEXCOORD0;
    float2 Tex			: TEXCOORD1;
	float2 bumpCoord0	: TEXCOORD2;
	float2 bumpCoord1	: TEXCOORD3;
//	float2 bumpCoord2	: TEXCOORD4;
};
/////////////////////////////////////////////////////////////////////////////////
VS_OUTPUT reflectVS( VS_INPUT IN )
{
    VS_OUTPUT OUT = (VS_OUTPUT)0;
    
    float3 Pwv = mul(float4(IN.Position, 1), (float4x3)WorldView);	// position (view space)
//   float3 N = normalize(mul(IN.Normal, (float3x3)WorldView));		// normal (view space)

    float4 Pwvp	= mul(float4(Pwv, 1), Projection);            // position (projected)
	OUT.Position = Pwvp;
	OUT.TexProj = mul(TexProj, Pwvp);

   
   	// pass texture coordinates for fetching the normal map
	OUT.Tex.xy = IN.Tex*textureScale;

	time = fmod(time, 100.0);
	OUT.bumpCoord0.xy = IN.Tex*textureScale* + time*bumpSpeed;
	OUT.bumpCoord1.yx = IN.Tex*-textureScale*2.0 + time*bumpSpeed*4.0;
	//OUT.bumpCoord2.xy = IN.Tex*textureScale*4.0 + time*bumpSpeed*8.0;
   
   return OUT;
}

float4 reflectPS( VS_OUTPUT IN ) : COLOR
{
    float4 Color = (float4)0;
	
	half4 t0 = tex2D(normalMapSampler, IN.bumpCoord0.xy)*2.0-1.0;
    half4 t1 = tex2D(normalMapSampler, IN.bumpCoord1.xy)*2.0-1.0;
//	half4 t2 = tex2D(normalMapSampler, IN.bumpCoord2.xy)*2.0-1.0;	
    
    half4 N = t0 + t1;// + t2;		
    
    N = normalize(N) * bumpHeight;

   	// projectively sample the 2D reflection texture
	Color.rgb = tex2Dproj(reflectMapSampler, IN.TexProj + N ).rgb + 0.1;	

	Color.a = 1.0;
   
	return Color;
}


technique t0
{
	pass p0 
	{
		VertexShader = compile vs_2_0 reflectVS();
		
		Zenable = true;
		ZWriteEnable = true;

	//	AlphaBlendEnable = true;

		PixelShader = compile ps_2_0 reflectPS();

	}
}


Can anyone suggest an alternative way to do this? I am not calculating any waves with the vertex shader. Thank you. Simon

Share this post


Link to post
Share on other sites
Quote:
Original post by sipickles
Color.rgb = tex2Dproj(reflectMapSampler, IN.TexProj + N ).rgb + 0.1;


This is the source of the problem, as you probably already know. The + N term will potentially cause the texture coordinate to be outside the actual reflection map.

I don't have a resource handy, but the typical solution is to increase the field of view of your reflection map. This will cause more of the reflected scene to be rendered to the reflection map, namely the parts that you're currently trying to access but don't exist.

I'll post a link with a better explanation if I can find one.

Share this post


Link to post
Share on other sites
the error comes up because you are trying to fetch the texture outside its bounds, since the default clamp is clamp/repeat, so you will fetch a texture from the other side of the texture(see, you have the hill there on the error areas). There isn't really any way how to completely remove this side-effect, however you can partly compensate with setting the clamp to mirror, in most cases the error will be invisible.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this