One way to create a reflective flat surface is to have another camera render the scene so that other camera will capture the actual reflection for the main camera. Think about our chopper scene, if we want to make the floor reflective, we would need to have another camera directly reflected below the floor and looking at the same point, where our main camera is looking. In that way the reflection camera will see exactly what would otherwise be reflected to the main camera.
Now, the reflection is not a perfect mirror of the color values. It is so for the diffuse part (if we assume, that diffuse light is of the same intensity no matter the viewer's position), but not for the specular highlights. The latter are dependent of the viewer. This means that the specular highlights seen in the reflection from the floor, will be different, because the light would bounce differently.
In order to achieve this effect, one way would be to construct the reflected camera's matrix directly. You can read more about that here:
http://khayyam.kaplinski.com/2011/09/reflective-water-with-glsl-part-i.html
Here we will implement a bit more simplified case and use different camera construction functions that we have (like the lookAt()). All that is needed for such a camera is just the correct position (reflection from the floor), same lookAt position and an opposite up-vector. For the position, if we assume that our main camera is located at $(0, 10, 0)$ and our floor is at the $y=0$ plane, then the reflected camera would have a position $(0, -10, 0)$. In a more general case you can think that if our floor is the plane $y = a$, then $y_{refl} = a - (y_{cam} - a)$, ie from the plane we subtract the vector from the plane to the camera.
It is quite common to do multiple rendering passes per frame, where only the last pass renders to the frame buffer. Other passes might render to a texture or to another buffer. Here we first need to render with the reflection camera and save what that camera sees. Then we render the scene normally, and when rendering the floor, we sample what the reflection camera saw in the first pass.
Task is to create a reflective floor, that has some amount of the reflection and some amount of the color of the floor. In reality we do not have perfectly reflective surfaces. The floor could just be a polished non-reflective surface and the polish on it adds some amount of reflection.
Also, make the arrow keys change the camera's viewing direction along the z axis. Make another key change between the normal and the reflection camera (so you can see, what the other camera actually sees).
Result can be something like:
The reflected camera should see something like this:
JavaScript
Feel free to see what parts of the previous solutions you can also use here. For example the Phong lighting model part you can just copy from the previous solutions.
Three.js provides a easy way to render to a texture, if we specify a certain object as the third parameter of the render() method.
Base code is located at:
https://cglearn.codelight.eu/files/course/10/ReflectedChopperJS.zip
Initially you should see something like this:
C++
Base code is at:
https://cglearn.codelight.eu/files/course/10/ReflectedChopperCPP.zip
See slides and comments for guidelines.