Until now, we have used the color buffer and depth buffer.
In this tutorial, we will use another buffer : the
Stencil Buffer.
Please read Lesson 05 for advanced
informations about buffers.
The reflection effect is a two pass effect.
In the first pass, you draw in the
stencil buffer
the area in which the reflection should be visible. This will create a mask for
drawing the reflection.
In the second pass, you draw the reflection in the color buffer only where the
mask is. The reflection is the symetry of the object (to reflect) in reference
to the reflection area (area that was used in first pas for creating the mask).
Then, draw the reflection area by blending it with the reflection. Finally, draw
the object reflected.
Reflection
The number of bit planes for stencil buffer is specified using a GLCapabilities object, before the creation of the GLCanvas :
Set stencil bit |
GLCapabilities glCapabilities = new GLCapabilities(); |
In the initialization, we specify the clearing value of the
stencil buffer. When this buffer will be cleared, it will be filled by 0 :
gl.glClearStencil(0)
To create the mask, we need to draw in the stencil
buffer the reflection area (here it is the ground).
To draw only in the stencil buffer, we disable writting in the color buffer (off
screen) and in depth buffer (draw all pixels).
Then, we activate and set up the stencil test. The stencil function to always
pass, value written will be 1(second parameter of
glStencilTest). The operation done, if stencil & depth test passes, is
writting in stencil buffer.
And we draw the reflected area (the ground).
This means, for each pixels of the ground, stencil test will mark '1' in stencil
buffer if depth test passes (third parameter of glStencilOp). We will have a
buffer in which where the ground is value is 1, elsewhere it is 0.
The stencil buffer for the above picture will look like (white='1', black='0'):
Stencil buffer
Finally, we activate writting in color and depth buffer for the
following.
First pass - Create the mask |
//Disable color and depth buffers |
Here we draw the reflection in the mask area, defined in the
stencil buffer.
We start with stencil test. The stencil function tests if value in the stencil
buffer is 1, to draw only where stencil buffer contains a '1'. When the test
succeed, we do nothing (keep current value).
Then, we draw the object to be reflected symmetrically to the drawing area. For
this, we mirror y and draw the object.
Finally, we disable stencil test.
Draw reflection |
gl.glStencilFunc(GL.GL_EQUAL,
1, 1);
//Draw only where stencil buffer is 1 |
Now, we draw the reflection area in color buffer.
We uses blending to mix the reflection with the ground (keep only 20% of the
reflection).
Draw reflection area |
gl.glEnable(GL.GL_TEXTURE_2D); |
To finish, we draw the reflected object.
Draw object reflected |
gl.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, lightPos); |
T/A/C : True/Average/Computed normals
True : true normal for at each vertex, using the
mathematical model of the geometry.
Average : average normal for each vertex, average calculated using
next and previous vertex.
Computed : normals is the normal calculated for each faces (bad result).
Average mode is equivalent to true mode for medium and high number of vertex,
but has low results for low number of vertex.
Remember to download the GraphicEngine-1.1.2 to run this tutorial !
Tutorial 23 src (137 ko) //Port to Jogl JSR-231 initially done by Magarrett Dias
If you've got any remarks on this tutorial, please let
me know to improve
it.
Thanks for your feedback.
Copyright © 2004-2012 Jérôme Jouvie - All rights reserved. | http://jerome.jouvie.free.fr/ |