Rippling the Stencil Buffer

Does anyone know how to manipulate the data in the stencil buffer directly? I am using it to do reflections (surprise surprise), and I’d like to be able to ripple it, to simulate water. Does anyone know how to do this?

That just hit me like a brick! Is the stencil buffer used to draw only the section in the mirror and not the pre-rendered scene?

Ever sence I learned how matrices work, all 3D ideas have been coming clear to me…even collision detection. I read a tutorial on bsp trees, and even they seemed to make more sence to me, even though I still don’t know how to do them yet.

tsuraan: What you are describing is best done with environment mapped bump maps (EMBM). These do not use stencil buffers. Also only the latest hardware is really suitable for implementing them.

Whoa, hold on a second. Where’d you learn how martices work? How… ehrm… when… why what where??? aaaahhhhhh! If they help that much show me!! PLEEAAASEE ?

LOL! What they did was show me what was going on.

I’ll try to explain a bit.

A matrix used by OpenGL is a 4x4 array of numbers(Modelview Matrix to be exact). When you want the vertices from your model moved to a place in space you multiply each xyz vertex in your model against the matrix.

Here’s something I didn’t understand for the longest time. When an xyz value is multiplied by the identity matrix, the point doesn’t move. The identity matrix is just a name used to describe the initial state of a matrix. You always start with the identity matrix before you perform any new multiplication. Now say you want to move a point 10 units on the x direction, all you have to do is create another matrix called the transformation matrix using the number 10 and placing it in its proper location in the matrix. Now multiply the identity matrix with the tranformation matrix. Now whenever you multiply a vertex, it’ll move over 10 units in the x direction.

Now the cool part. All you have to do to move your vertices around is start multiplying matrices with matrices. There’s the Rotation Matrix, Scale Matrix, and Transformation Matrix.

You may be familiar with using matrices, but I’ll continue anyway.

Lets say we want to move a vertex 10 units in the x direction, and rotate the vertex 45 degrees on the x axis.

seudo code:

matrix m;
vertex v=0,0,0

m=mRotationMatrix(45, 1, 0, 0)
TransformationMatrix(10, 0, 0)


v is now in the loaction you wanted it with only one pass through m. With thousands of vertices it saves tons of multiplications and uses of sin & cos.

The last thing that happens to the v in OpenGL under perspective mode is that it’s multiplied by the Perspective Matrix.

Once you’ve gotten a handle on matrices, then you can do cool things. Have you ever wondered how they get text to be right above a players head, yet never scale with the rest of the game? All they do is multiply the point above the players head with their own matrices to get the xy position on the screen, after all, that’s what OpenGL is doing to draw your scene right? You have to be in orthogonal mode when you draw the text though.

Alot of 3D for the longest time was very native to me, but I knew enough to use the matrices, but not enough to use the matrices to my advantage.

Hope this helps some of you understand matrices a little better, if you didn’t know already of course .

end rambling

[This message has been edited by WhatEver (edited 04-02-2001).]

hmmm. Does anyone know how I could get a pointer to the base address of the stencil buffer? I have a program that will draw ripples (like water) on an arbitrary texture, so if I could just grab the address of the stencil buffer I could play with it from there…

Also, yes, stencil buffers are generally used for reflections, or I’m pretty sure you could use one for a portal too, but I haven’t tried it. It basically renders your scene to a position in memory instead of the screen, so that you can draw the scene from different angles in the same area, making reflections and stuff (I think that’s how it works. I’m a bit new at this).

I know there’s someone who can help you, it’ll just take at least a day.

Sorry for knocking the thread off track.

Actually, a stencil buffer acts more like a mask that you can draw into the scene and use later to block out areas of the frame buffer. What you are talking about are either auxiliary buffers or p-buffers.

For what you want, probably the best thing would be rendering the reflection, copying it to a texture, and then distorting the reflection texture. But it will be really slow on almost anything.

There’s a title in development called X-Isle that does this sort of trick on a GeForce3 using a pixel shader on the reflection texture. It looks pretty impressive in action.


Originally posted by j:
For what you want, probably the best thing would be rendering the reflection, copying it to a texture, and then distorting the reflection texture. But it will be really slow on almost anything.

Right, but you don’t need to warp the texture itself. You can achieve the same effect by warping the texture coordinates instead. However, this requires that you use a pretty detailed mesh to represent your water surface.

X-isle looks like it does per-pixel bumpmapping of the water surface. They could use a pixel shader that uses a bump map texture as input to determine how to warp the texture coordinates for the reflection texture. The effect is essentially the same, but it’s done per pixel and doesn’t require a fine tesselation of the water surface. NVidia has plenty of documentation about this on their site…

  • Tom

ok, how would I go about copying the reflection into a texture? Is there a command for that, or would I have to do something nasty like running through the stencil buffer sampling pixels and putting them onto a texture (I’m sure that would be the worst possible way).

What you would do is set the viewport to be something like 512x512, and render the reflection image normally. Then use glTexCopyImage2D(…) or glTexCopySubImage2D(…). I forget the exact syntax for them. Then just use the reflection texture on your reflective surface with the appropriate texture coordinates.


alright, I’ll give that a shot. thanks.