In the last lesson, I showed you how to use the frame buffer to query a visual effect. The frame buffer can also be used to create many other visual effects. In this video, I'm going to show you how to create a mirror effect using the frame buffer. As mentioned in the last lecture, we can draw the OpenGL objects in a frame buffer. Instead of a screen the objects are actually drawn on the attached texture of the frame buffer. We can map this texture onto a 3D object and show it on the screen to create shiny and highly reflective objects in the scene. The same technique can be applied to create a mirror effect. Like this image, the virtual object appears to be placed on top of a mirror. The reflected image of the objects is actually generated by drawing the object in the frame buffer, and then the texture of the frame buffer is then drawn on the screen to show this mirror effect. To create a mirror effect, we need to flip the frame buffer texture image upside down. This is relatively easy to do. We can simply swap the y coordinates of the texture coordinates to flip the texture image upside down. The same shader source code created in the last frame buffer lesson can be used to create the mirror effect. In order to create a more realistic mirror effect, I would like to slightly dim the reflected image. To do that, I added a uniform parameter, ulighting which is passed to the vlighting variable in the fragment shader to scale the intensity of the color of the fragment. Basically, the intensity is set by multiplying the vlighting variable with the RGB value of the fragment color. To show the object and to reflect the image on the screen, I have to scale down the model first in order to leave some space on the screen to show the reflected image. In creating the mirror effect, we can use the same projection matrix to draw the object in the frame buffer. After drawing in the frame buffer, I then draw the texture of the frame buffer as a 2D plane on a screen to show the mirror reflected image. Before drawing the 2D plane, I first rotate the model about the x-axis for 65 degrees, and then translate by 0.05 units along the y-axis in order to position the mirror reflected image right underneath the object. Let's implement this in our example program. First, I added the uniform variable ulighting and the varying variable vlighting, and passed the ulighting value to the vlighting onto the fragment shader through the vlighting variable. Then I changed the gl_FragColor to use the vlighting to adjust the intensity of the fragment color. Then I add a variable called LightHandle to point to that uniform variable ulighting. And then in the texture coordinate, as I mentioned earlier, we need to swap the y-axis of the texture in order to flip the image upside down. Then I set the LightHandle to point to the uniform variable ulighting and also set the width of the frame buffer to be the same as the screen. Then I set the uniform variable value to 0.8, 0.8, 0.8 to dim the image. In the MyRenderer, I first need to scale the image down by 2.3 in order to have some space to draw the reflected image. As the mirror reflected image should appear the same as the original image, so we don't need to have a specific view matrix, and also, we can use the same projection matrix to draw the object in the frame buffer. As I want to create an effect as if mirrors is positioned right underneath the object, so I first rotated the 2D plane above the x-axis for 65 degrees, and then translated the object for 0.05 along the y-axis. So when I run the program, you can see that we create this mirror effect as if the object is positioned right on top of the mirror, and we can rotate the object and see the updates on the screen. You may have probably seen this kind of reflective effect in slideshow presentations and other image drawing software. Similar to the mirror effect I just showed you we can use the frame buffer in OpenGL to create this effect. Unlike the mirror effect, the reflected to image should fade away gradually. So starting from the top of the frame buffer, which should be closest to the original object, the intensity of the fragment should be decreased at a set rate. The y-position of the fragments can be found by using the variable gl_FragCoord.y which is the fragments y-coordinate. We can normalize it by dividing it with the height of the frame buffer, and I added a ufactor variable to adjust the dimming effect, reducing the impact of the displacement of the object. As the object is positioned in the middle of the frame buffer, there is a large empty area from the top. If you start dimming from the top edge of the frame buffer, by the time we reach the object, the dimming factor could already be quite large, and most fragments of the object could disappear from the screen. Hence, the ufactor basically translates the start of the dimming effect closer to the top of the object. In addition, to create this fading effect, I defined an exponential function to reduce the intensity of the fragment. The dim factor is basically the intensity of the fragment. When ypos is equal to 1, then the dimming factor will be equal to one, which means no dimming. On the other hand, if ypos is equal to 0, then the dimming factor will be equal to zero, which means disappearing from the screen. To go create this fading effect, we only need to modify the fragment shader. Hence, I first define two uniform variables, uheight and ufactor to set the frame buffer height and ufactor. Then I used a gl_FragCoord.y to find the y position on the fragment, and applied the exponential equation to calculate the dim factor. The dim factor is then multiplied with the fragment color to adjust the intensity of the fragment. To draw the object and the reflected object on the screen, I first bind the frame buffer, and then apply the same scale and rotation to the modal matrix as per the original object. Afterwards, I then draw the object in the frame buffer and release the frame buffer by unbinding it. I then draw the frame buffer texture on the 2D plane on screen. You may notice that I translated the 2D plane downward for one unit to position the reflected image at the bottom of the object. Let's implement this in our program. So to create this reflection effect, I create a new Java class called reflection effect. Basically, it's a copy of the frame buffer display object we created in the last lesson. I first added two uniform variables, uheights and ufactor, and then calculated the y position by using the gl_FragCoord.y variable, then using the exponential function to calculate the dim factor. Then I used the dim factor multiplied with the fragment color to adjust the intensity of the fragment. I then define the uheight handle and ufactor handle variables to point to those uniform variables. Then I set the uheight value to be the same as the height of the frame buffer, and also set the ufactor to a value of 0.3. Then in the MyRenderer, I first defined reflection effect variable mreflect to create this variable in onSurfaceChange functions. In the onDrawFrame function, I first bind the frame buffer of the mreflect object, set the Viewports, and then set the model matrix to be the same as per the one for drawing the original object. So basically, scale and rotate the object with the same values. Then I draw the object in the frame buffer, and then release the frame buffer by unbinding it. As the reflected image is only underneath the original object, we only need to translate a 2D plane by -1 along the y-axis, and then we can show this 2D plane to show the reflected image. So when you run the program, you see that there's a reflection underneath the object, and when you rotate the object, you see the reflected image update accordingly