Island Rendering
Bohdan Romashchenko, Joonas Praks, Mehis Taevere
Description
Our project aimed to create a realistic island scene with OpenGL and C++. We have implemented low-level algorithms for recreating effects that can be observed in nature. The rendered scene includes water with different effects, procedural island terrain generation, and the sky.
Demo
Water implementation
In order for water to look more or less realistic, several things need to be considered:
- Everything underneath the water must be seen on the water surface with a refraction effect.
- Everything above the water must be reflected on the water surface.
- Water surface reflectivity must depend on the viewing angle, which is called a Fresnel effect.
- Water surface must be "moving" based on the wind or other factors to simulate little waves.
Example from https://www.scratchapixel.com/lessons/3d-basic-rendering/introduction-to-shading/reflection-refraction-fresnel
Implementation wise these things look like this:
- Everything below the water is drawn to a refraction texture.
- Camera is moved underwater and inverted, then everything above the water is drawn to a reflection texture.
- Water is rendered taking into account some base color (e.g. blue), color values from refraction, and reflection textures, which are mixed based on the view angle. To simulate waves, a distortion coefficient is calculated based on several factors, it influences what UV coordinates to sample from textures.
Island implementation
Given a field of vertices, two types of heightmap generating algorithms are applied on top of one another:
- AddSphereHill takes a random origin and establishes x and y boundaries that mark the hill's random radius. Iterating through every point between the boundaries distance is calculated from the origin. If the distance is less than the radius then the difference between the squared radius and the squared distance is appended to the heightmap.
- AddGaussianHill starts of similarly but here we use the random radius as the standard deviation of the Gaussian distribution to apply Gaussian blur, namely {$ \frac{1}{2\pi*radius^2} * e^{-\frac{x^2+y^2}{2*radius^2}} $}. Also, if enabled by the 'isIsland' attribute, the generated landmasses can be concentrated in the center by setting the base origin to the map center and offsetting it from there by a random distance.
Those heightmaps are then blended together with a ratio of 1 (sphere hills) to 3 (gaussian hills). Sphere hills give the gaussians a nice bumpy texture.
Image courtesy of Raimond Tunnel.
Skybox implementation
To create the sky we have used a cube map with 6 images.
Example from https://learnopengl.com/Advanced-OpenGL/Cubemaps
GUI
To make our application more interesting and interactive, we have also added a GUI that allows users to change different parameters in the scene and offers help with controls. For that, the ImGui library was used.
Screenshots
The scene with default parameters
The scene with changed parameters