Creating waves on a water surface (HLSL)

Started by
28 comments, last by kobingo 17 years, 11 months ago
Crap, that didn't do any difference :-(
Advertisement
Imagine your water surface has normals pointing upward from every pixel. Normals can be
calculated by the following formula

N = -dz/dx(i) - dz/dy(j) + k

Later normalize it.

However, most of the times this is precalculated in the normal map or can be easily calculated in the vertex-shader and interpolate along the whole tri. For that however, u need more tesellation, only two tris will look ugly.

For the moment you can using simple stuffs, as follows, as your wave model

z = A * sin(k*x) * cos(l*y);

Where A, k and l are constants.

Now imagine that whatever reflection texture you want to put on the water surface, is
lifted JUST A LIL ABOVE the surface. Note the phrase "JUST A LIL." Now for a texture coordinate s,t, make it 3d, (s,t,0). Now with the normal N , just project (s,t,0) to
that lifted surface along N.. i am using R ( or Z ) to be upward here. Which means

(s',t',r') = (s,t,0) + lambda * N;

Now use (s',t') to index into your texture. "lambda" is a very small number, u can't afford to make it large because when u took the snapshot of the reflected world (by RTT), u already lost one dimension, and hence u can't make lambda large...it will only make things look ugly.

Since we are only worried about s' and r' so the above equation actually boils down to

s' = s + lambda * N.x
r' = r + lambda * N.y

After doing all these.. u will still run into problems with texture sortof "waving" on the edges of the screen, depending on the orientation of your water with respect to camera. This is something which is VERY difficult to avoid to be honest. There are some hacks to get around this... which i will tell u once u get the basic thing right.

Btw, by just looking at one of ur screenshot.... DID YOU USE the same aspect-ratio when u did the RTT as when doing normal rendering to screen. IF you didn't then DO IT. You must use the SAME aspect-ratio when doing RTT. Usually beginners think that they should use an aspect ratio of 1 when using a RTT on a square texture (say, 256x256) but that is not correct.

Regards
Z
Z
Thanks, but I'm sorry I don't really understand what you are trying to explain, I think I already got the basics to work (reflection and distortion of water). The only problem right now is that there is a small gap between my terrain and the reflection in the water. Here is a new screenshot that shows what I mean

This is the pixelshader code I'm using:
float4 reflect = tex2D(TextureSampler, projcoord);	float3 combinedNormal;combinedNormal = tex2D(NormalSampler, IN.texCoordDiffuse.xy);float distScaledDistortion = IN.project.z;distScaledDistortion = clamp(3 / (distScaledDistortion + 2), .3, 1);float3 scaledNormal = normalize(combinedNormal * float3(reflectDistortion * distScaledDistortion, reflectDistortion * distScaledDistortion, 1));IN.project.xy = IN.project.xy / IN.project.z - scaledNormal.xy;float4 reflectiveColor = tex2D(TextureSampler, IN.project);reflectiveColor = reflectiveColor * IN.color;    return reflectiveColor;


Also, I'm already using the same aspect-ratio in my RTT... I have tried to get this to work for a week now, starting to get really frustated :-/
*One last shot* Anyone?
All the math looks right and with no distortion the reflection is right, so it seems like the problem lies in the format of your normal map. Make sure that it's an 8 bit or more per channel rgb format, no color-based compression, and the color value (127, 127, 255) is a unit vector straight up. Maybe you could post a shot of it.
Aha, it could be my normal map?...

This is just a screenshot of my normal map:



This is the actual dds texture I'm using: Actual texture

Maybe some nice person could send me his/her water normal map so I could test it, I tried to search the web but couldn't find any... :-)
With a little brightness and contrast tweaking, and of course a channel swap to match my shader, I get this:

water reflection

here's the normal map used.

So those results aren't too bad. There's nothing inherently wrong with the normal map, except maybe for that big flat spot, I think you just need to tweak the parameters more. When I first plugged in the original you gave me it caused the reflection to be lifted up, just like in your screenshots. But turning the brightness down solved that.
That's a beautiful screenshot :-) Thanks, all try it as soon as I get home...

When you say turning the brightness down (you are talking about the normal map image right?), do you mean like just change the brightness in photoshop?
Hi Kobingo,

Just wanted to say that the error in the last shot looks very much like it was caused by an incorrect clip plane. I don't know quite how you're clipping the world when you render to your reflection texture, but make sure that your clip plane is set to the same level as your water surface. Good luck.
Finaaaaally :-)

I changed some of my values, and now it works like a charm! Thank you very much all of you!



Next up, texture splatting :-)

This topic is closed to new replies.

Advertisement