Skip to main content
GameDev.net gamedev.net
🔒 Locked

Reflective surfaces (e.g. water)

Started by VanKurt Aug 19, 2003 at 12:30 PM 46 replies 21.1k views
Original Post
VanKurt
VanKurt
I''m trying to create a reflective surface just like mirror or water. I''ve read a lot of posts on this topic and I think I''ve got the theory by now: 1) You flip the geometry around the water plane 2) You set the water plane as a clipping plane (so that things under water aren''t drawn) 3) You render the scene to a texture But as easy as that sounds I''ve still some questions: - What''s the easyest way to flip my whole geometry (that are a LOT of objects) about the water plane? Is there some easy trick like moving the camera/changing it''s up vector?? - How do I define my own clipping planes? - How do I apply that texture to my plane? What texture coords should I use and where do I get them???? Lots of questions...but hopefully lots of answers, too.... Thanks a lot, FunKurt
circuit
circuit
>- What''s the easyest way to flip my whole geometry (that are a
>LOT of objects) about the water plane? Is there some easy trick
>like moving the camera/changing it''s up vector??

Use glScale-functions.
glScalef(1, -1, 1); // Flips y

>>How do I define my own clipping planes?
Use glClipPlane(GL_CLIP_PLANE0, plane_equation) to define the plane.
Then use glEnable(GL_CLIP_PLANE0) to enable it.
EvilProgrammer
EvilProgrammer
I''m looking into this, too, and I was wondering if you should define a sort of viewing box coming out from the water so you only draw reflected objects that have reflections you can see from your current position. Is this right?
VanKurt
VanKurt
Thanks circuit!

But what about the texturing? How does that work?
I think it would be difficult to map a texture on a quad which has been rendered that way...
VanKurt
VanKurt
I''ve tryed google in order to find some tuts/samples, but it''s all about stencil reflection, which not what I need...

Maybe smeone has got a good link???
Thanks!!!
theZapper
theZapper
I think there is another way using the stencil buffer.
It goes somthing like:
draw your reflective surface into the stencil buffer,
flip your geometry and redraw it to the colour buffer only where the stencil buffer is set.

---
When I''m in command, every mission''s a suicide mission!
---When I'm in command, every mission's a suicide mission!
VanKurt
VanKurt
Is this method suitable for large planes? (I mean REALLY big, so that the player sees only a very small part of it at a time)
Sander
Sander
Yes. The stencil buffer is just as big as the color buffer (your screen). The only limit that you have is that ou have to render your terrain twice. Once flipped over Y and once normal, so it takes longer.

I hope you have a good frustum culling / occlusion culling method!

Sander Maréchal
[Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]


GSACP: GameDev Society Against Crap Posting
To join: Put these lines in your signature and don''t post crap!
VanKurt
VanKurt
Allright then! Thanks for your support.. I''ll try that as soon as possible :-)
Rasmadrak
Rasmadrak
Hi there!

The glScalef(1,1,-1) works great... except for one thing.

The models get all funky normals... if I flip a box, it´s like you press down the top of it and through to the other side... thus, leaving the box inside out. <- not nice! =)

Is there a function for flipping the normals? thanx!



P.S would it be better to have several small quads of water(textures), or just one quad/trianglepair with one texture wrapped all over it? I recon the one quad solution is pretty fillrate punishing..?

"Game Maker For Life, probably never professional thou." =)
"Game Maker For Life, probably never professional thou." =)
Rickwi22
Rickwi22
Seems like glRotate wouldnt have that prob. Im not sure tho
VanKurt
VanKurt
Sorry, but it''s me again ];-}

I''ve got a problem with this stencil-thing:
The reflection is created through a second render pass, but this way you cannot use any pixel shaders, right? Is there a way to use stencil reflections to generate a texture, which is then applied to my water quads?
Sander
Sander
Why wouldn''t you be able to use pixel shaders? Are you sure you understand how to do stencil reflections?

1) turn off all pixel shaders, textures, light etcetera
2) render waterplane to stencil buffer
3) enable stuff from (1)
4) flip geometry over the water plane
5) enable clipplane over the waterplane
6) render geometry with testcil test (only render where stencil buffer is set to 1 in step (2))
7) undo (4) and (5)
8) render waterplane (blended)
9) render geometry again

Sander Maréchal
[Lone Wolves Game Development][RoboBlast][Articles][GD Emporium][Webdesign][E-mail]


GSACP: GameDev Society Against Crap Posting
To join: Put these lines in your signature and don''t post crap!
memon
memon
Dont use the scale -1 because it makes the normals crazy as you described, the rotate is not right either, since you need mirroring, not rotation (the scale is right in theory)

I think the best way is to tweak the camera. Can''t remember the details, but I once made a rippling reflective water for a small game. You can download hte sources here:

http://moppi.inside.org/eskimo/

The stuff you are interested of is in the SceneC.cpp
VanKurt
VanKurt
Excuse my stupidity.. ;-)

In step 8, do you use the texture you generated in step 6?
theZapper
theZapper
No, you don''t generate or render any textures. You are simply drawing, and redrawing parts of you scene and blending them all together for the final effect.

Read Sander''s instructions again, they do make sense. But here is another description.

Say you have a pond, you want to render a reflection but don''t want the reflection to appear on the ground next to the pond. You disable colour and depth buffers, and enable the stencil buffer.
Now, you draw *ONLY* your pond surface. This will set an area in the stencil buffer, like a little cutout.
Now if you render into the colour buffer, you will only see objects that appear where the stencil buffer is set, so, you flip your objects about the reflective plane, and draw them. Now you should have objects in that little cutout area and they will be flipped over and look like a perfect reflection.
Now all you need to do is draw your pond surface again, with blending and it should now look like water with a reflection on it.
You don''t need to use any textures you have generated from prvious steps.

---
When I''m in command, every mission''s a suicide mission!
---When I'm in command, every mission's a suicide mission!
FReY
FReY
Hey there. The reason why your objects will be inverted is that the scale(1,-1,1) reverses the winding order of your vertices.

In OpenGL you can correct this by doing something like the following

// render the actual object
glFrontFace(GL_CCW);
RenderObject();

// render the reflection.
glScale(1,-1,1);
glFrontFace(GL_CW);
RenderObject();


As a side note, you can perform frustum culling by perform the exact same transformation (in this case glScale(1,-1,1)) on your bounding box/sphere/volume, and then testing it against your frustum.


do unto others... and then run like hell.
VanKurt
VanKurt
Allright, I got that! Thanks!

The big BUT:
I would like to apply a UV-distortion pixelshader to the water-texture to make it look better. (Using a normal map to do bumpmapping and to perturb the UVs of the reflection texture)

But for that I''d need a texture. So stenceling is not suitable here...(or at least I think so), right?


Thanks for your support!!!
OleKaiwalker
OleKaiwalker
I see, what your problem is :D

You are simply trying to copy the reflection down to pixel, so you can disort it with the pixel shader / fragment program ?

There are different ways to get that work (I think)...

You can create a new viewport. Render the water texture in it, and render what you have in the stencil to it afterwards. And last copy the viewport to a texture and then disort it. I don't recommend it because this way can be extremly slow if you arn't good at optimizing.

Otherwise you can render the thing from the above (water and stencil) to the texture directly with the pbuffer extension (it is an ARB extension). Read about it. It's much faster but a bit more complicated than the above solution...

Hope you can use some of it :D





[edited by - olekaiwalker on August 23, 2003 11:17:26 AM]
VanKurt
VanKurt
@ OleKaiwalker:
Just in case you are bored... could you explain that a little more in detail? For example: If youe render a texture that way, how can that be mapped onto the water plane?

"Otherwise you can render the thing from the above (water and stencil) to the texture directly with the pbuffer extension (it is an ARB extension). Read about it. It''s much faster but a bit more complicated than the above solution...
"


THAAANKS!!!

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.