OpenGL Renderer

- Beta

OpenGL Renderer

3D Scene in OpenGL

About

This project was developed as part of the Computer Graphics coursework at SAE Institute Geneva. The goal was to create a modern-ish renderer in OpenGL version 300 es that supports a range of effects such as SSAO, HDR, Bloom, and such. This blogpost will go over a few techniques I implemented with more or less success.

Goals


Deferred Rendering Pipeline

OpenGL Scene

Description

Unlike Forward Rendering, where lighting calculations happen per object, Deferred Rendering stores object data in a G-Buffer (Geometry Buffer) and computes lighting in a separate pass, which allows for efficient lighting calculations with multiple light sources without redundant shading computations.

Rendering Steps

The different passes I decided to implement are as follows:

Complications


Cascaded Shadow Maps

Cascaded Shadow Maps

Description

To optimize the rendering of the shadows, we can reducec the quality of those that are further away from the view. To do as such, we can use Cascaded Shadow Maps (CSM). Meaning that instead of a single shadow map, CSM is used to split the view frustum into multiple layers and assign a separate shadow map to each, with reduced quality at a higher distance.

Learning Points and Complications


Geometry Pass

Geometry Pass

Description

The Geometry Pass is used for deferred rendering and consists in storing the position, normal, albedo, and material properties in a buffer called the G-Buffer that is then read by the following passes. Rather than rendering each object individually, like in a forward rendering pipeline, the effects are applied to the buffer and the buffer is rendered at once as a single texture on the screen.

Learning Points and Complications


Profiling

Begin

Begin Function

The start of the program is quite long (6,35 seconds) because it needs to load all models and textures from the disk. This is expected because I used more than a dozen of models. Initializing the future passes only takes a very short percentage of the total time.

CPU Update

Update on the CPU-side

On the CPU side, what takes most of the update time is the “Update Camera & Animation” function, because of the animation part. The second thing that takes the most time, as expected, is the Shadow Pass, since CSM requires to recalculate the layers based on the view position.

GPU Update

Update on the GPU-side

On the GPU side, most of the time is taken by “self time”, which is something that is outside of the nested zones, in this case it probably is the shaders execution.


Conclusion

Making one’s own renderer is an interesting challenge because it forces one to understand the importance of a solid order of operations to display things properly. As mentioned, some of what I implemented ended up missing from the final scene and I am therefore not fully happy with my result. Also, I did not have time to get into profiling and optimizing, which could provide interesting data on the cost of some better effects, for example.

[Github Project]
GitHub Repo