Sign in to follow this  

Water refraction bug

This topic is 1448 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

Hi there,

 

I am trying to implement refraction for water surface, and i am struggling a bit with the implementation as this is the first time I am trying to do such a thing. The water surface is not flat, i use FFT on a small grid to make vertices move, and i use the normals of each vertices to calculate the refraction vector. Then i substract the view ray with the refract ray to know how much i need to offset my texture sampling when shading the water surface.

 

Here is the shader

 

VertexOut VS(VertexIn vin)
{
VertexOut vout; 

// Transform to world space.
vout.PosW    = mul(float4(vin.PosL, 1.0f), gWorld).xyz;

// Find transformed normals.
vout.NormalW = mul(vin.NormalL, (float3x3)gWorld);
vout.NormalV = mul(vin.NormalL, (float3x3)gWorldView);

// Transform to homogeneous clip space.
vout.PosH = mul(float4(vout.PosW, 1.0f), gViewProj);

vout.Tex = vin.Tex;

vout.PosV = mul(float4(vin.PosL, 1.0f), gWorldView).xyz;

return vout;
}

float4 PS(VertexOut pin) : SV_Target
{ 
float backBufferWidth = 1024.0f;
float backBufferHeight = 768.0f;
float zFar = 300.0f;
pin.NormalV = normalize(pin.NormalV);
float3 viewRay = normalize(pin.PosV);
float3 refractRay = refract(viewRay, pin.NormalV, 0.75f);
float2 InvTextureSize = float2(1.0f / backBufferWidth, 1.0f / backBufferHeight);
float2 texCoord = float2(pin.PosH.x, pin.PosH.y) * InvTextureSize;
float zw = gDepthMap.Sample(PointSampler, texCoord).x;

// Reconstruct linear depth.
    float depth2 = ProjectionB / (zw - ProjectionA);

// Calculate View position of ground fragment.
float3 groundPosV = viewRay * depth2; 

    // Calculate sampling offset caused by refraction.
float3 diff = normalize(normalize(viewRay) - normalize(refractRay));

texCoord = texCoord + diff.xz;

float3 sourceColor = gGroundMap.Sample(PointSampler, texCoord); 
return float4(sourceColor, 1.0f); 
}

And here is the result :

http://www.youtube.com/watch?v=mkoA7Ec1BjU&feature=youtu.be

 

 

I think the issue is around these lines :

// Calculate sampling offset caused by refraction.
float3 diff = normalize(normalize(viewRay) - normalize(refractRay));
texCoord = texCoord + diff.xz;

as i am not sure this will keep me in UV space.

 

Any idea ?!

 

Thanks :-)

Share this post


Link to post
Share on other sites

Hiya,

  For refraction I just use the x,z (or x,y depending on coordinate space) of the bump map multiplied by a value that scales based on distance. I can only see weird things happening if you use the view ray.

 

ie.

texCoord = texCoord + bump.xz * refractScale;

 

You might also want to put another scaling factor in that is based on the distance of the viewer from the surface.

 

n!

Share this post


Link to post
Share on other sites

Thanks for answering nfactorial.

I tried to scale the effect down by adding a 0.1f factor to it, and it does improve things. But i still have visual artefacts on the edges, I guess its the same artefacts i had before, but at a smaller scale.

 

rU2z8kZ.jpg

 

ktq99CN.jpg

 

New shader code :

float zw = gDepthMap.Sample(PointSampler, texCoord).x;

...

// Calculate sampling offset caused by refraction.
float3 diff = viewRay - refractRay;
diff = diff / zw;

texCoord = texCoord + (diff.xz * 0.1f);

Any thoughts ?

Share this post


Link to post
Share on other sites

You need to be careful around the edges, as the offset can bring the sample outside of the water. You generally check the depth of the refracted point and if it's closer than the water surface, you chose something else (I normally take the screen position of the original water surface).

 

n!

Share this post


Link to post
Share on other sites

This topic is 1448 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.

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