Pond Water Effect Bug

Started by
6 comments, last by Quinnie 16 years, 3 months ago
Hey, I've been busy implementing water effects into a terrain engine. The effect is based on moon-lab's pond demo. This is a link to the paper describing the effect.The included screenshots show a bug near the edges of the water. I checked the moon-lab's pond demo executable and the same kind of effect exists there however it is much smaller and therefore less noticeable. If it is necessary I'm happy to post any sourcecode regarding the water effect. p.s. The demo includes two wavemaps, I was wondering how they are created and whether there are any tools for this. I would like to create my own wavemaps because the included wavemaps had a low resolution. Thanks in advance, Quinnie [Edited by - Quinnie on January 1, 2008 6:55:56 PM]
Advertisement
It looks to me like the mirrored camera position is being miscalculated; the clipping plane for rendering the reflection might also be mispositioned, from the look of it. Make sure you're not just reversing the up vector, but flipping it correctly across the mean water plane.

Edit - on further examination, the bit about the clipping plane also applies to the transparency rendering; make sure you've got that bit right as well.
RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.
It looks, like bad disorting is just from the camera, maybe I've got solution.

Are you moving in that scene? If yes, it may be caused by rendering refraction AFTER rendering whole scene - render refraction buffer before rendering of scene.

Or it may be caused by "bad FOV" in your projection matrix, while rendering water refraction/reflection. Maybe it's caused by bad width/height ratio, in projection matrix too. You need to have
ratio = sceneBufferX/sceneBufferY
not
ratio = renderBufferX/renderBufferY
even in water renderbuffer.

For example, you've got window of size 1024*768 and buffers for water of size 512*512. So width/height Ratio in window size is 1,33333...., water buffer needs to has the same! They might got 1,00000...., so you're getting bad offset just in everything in water, thats in Y direction of window (it looks like that, but I'm not 100% sure).

It hasn't nothing simiar with normalmaps or dudvmaps (or wavemaps).

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

Thanks a lot for your reply's,

My rendersurface for the refraction/reflection maps where set to 512x512 and my backbuffer was set to 1440x900. But I am not changing the aspect ratio while rendering the refraction/reflection maps. I did try changing the resolution of the refraction/reflection maps to 1440x900 but that didn't help.

I tried disabling the perturbation effect of the water, that seemed to fix the problem. Except that the water didn't look as good. So I'm guessing there is a problem with my perturbation calculations, I might be totally wrong though.

I'll post a snippit from my pixel shader:

// Sampler0 and Sampler1 are the reflection/refraction textures.// vNormal is the average normal of the two wave normals from the two wavemaps.float vPerturbationMagnitude = -pow(Input.vPositionCopy.y, 20.0f) + 1.0f;float2 vPerturbation = vNormal.xz * float2(0.04f, 0.03f);vPerturbation.y *= vPerturbationMagnitude;// Retreive The Refraction And Reflection Colorsfloat3 ReflectionColor = tex2D(Sampler0, Input.vPositionCopy.xy).rgb;float3 RefractionColor = tex2D(Sampler1, Input.vPositionCopy.xy + vPerturbation).rgb;


This is a screanshot with perturbation disabled. There are still some artifacts near the edge of the water but it is much less.


Thanks a lot for your help so far,

Quinnie
Well, i don't know, why are you using vPetrubationMagnitude parameter - i'm not using anything like this with rasterization water rendering. Try to change your code to something like this (it'd be better probably):

// I call this DUDV offset (but this is just small offset using normal maps)// True DUDV offset is using DUDV map, which is derived normal map.// Solution using DUDV mapping is maybe a little better, than normal map offset// Try using vNormal's red and green component, because blue component is always // at weight 1 in normal maps, it'd look nicerfloat2 vPerturbation = vNormal.xy * float2(0.04f, 0.03f);// Input.vPositionCopy.xy + vPerturbation - use this for both reflection and // refraction, solution will be much more nicer (you weren't "rippling" // reflection on water waves, but you were rippling refraction - this should look// a little strange for player/customer/tester)float3 ReflectionColor = tex2D(Sampler0, Input.vPositionCopy.xy + vPerturbation).rgb;float3 RefractionColor = tex2D(Sampler1, Input.vPositionCopy.xy + vPerturbation).rgb;


I changed commentaries a little. It should be working correctly now, i hope.

My current blog on programming, linux and stuff - http://gameprogrammerdiary.blogspot.com

First of all thanks a lot for your help,

I modified the shader using your proposed code. It has indeed improved the look of the water! However there are still some artifacts near the edge of the water. I'm guessing this is because the ripple offset moves the uv coordinates out of the texture, thus returning a black color. I tried clearing the render surfaces with a red color and the artifacts did indeed turn red.



Additionally the artifacts not only occur on the connection between the water and the terrain but also at the edges of the screen. This could also be explained because the uv coordinates exceed the reflection/refraction texture dimensions.

float vPerturbationMagnitude = -pow(Input.vPositionCopy.y, 20.0f) + 1.0f;

This magnitude parameter is used to fade out the ripple effect when the uv coordinates are near the bottom edge of the screen. I admit it was a bit hacky, instead I changed the texture mode from wrap to clamp. This solved the artifact problem near the edge of the screan. However the artifacts near the edge with the terrain remain.

Any additional advice would be greatly appreciated,

Quinnie
This is a common problem for water reflections. As you say, it is caused by perturbation of the texture coordinates past the geometry threshold on the reflected pre-render.

The simplest solution is to move the clipping plane some distance below the water's surface. Getting this offset correct is something of an art, though, as too little will leave some artifacts and too much will increase the likelihood of 'ghost' reflections of concave underwater geometry. If your animation formula betrays the largest possible perturbation in water height (as with Fourier-series or displacement-map methods, and - to a degree - Perlin noise) then you can just use that value and hope for the best.
Ring3 Circus - Diary of a programmer, journal of a hacker.
Thanks for clarifying that,

I changed the render target clear color to something blue/gray-ish and increased the clipplane height for the terrain. I did notice some ghost reflections but the edge artifacts where gone and the final look is a lot better now!

Thanks to all for your kind help!

Quinnie

This topic is closed to new replies.

Advertisement