A model of an old-fashioned gun is set against a backdrop of a lake.

Real-time Physically-based Renderer

Implements a microfacet surface model using Cook-Torrance BRDF. Performs importance sampling from environment maps for image-based lighting.

Tech stack

C++, GLSL, OpenGL

For the second half of our Offline & Real-time Rendering class, we implemented the industry-standard real-time shading model as presented by Epic Games for Unreal Engine 4.

In particular, we used the following approximation formulas for the many components of the Torrance-Sparrow microfacet model:

All the lighting calculations are performed in the fragment shader. Depending on whether the model provides its own textures, we either sample a texture for the material attribute or rely on a GUI slider for adjustments.

For IBL, we precompute the Lambertian/diffuse and glossy irradiance from the environment map, store them in a samplerCube, and sample via a vector (surface normal for diffuse, reflection about normal from camera for glossy).

Some screenshots

The following are screenshots and a video of different models interacting with the light coming from different environment maps.

PBR shader

Here is the PBR shader with the albedo set to purple. The left/top image has metallicness turned to zero while the right/bottom has it set to full. Both have a roughness of ~0.25.

Zero metallicness, a little roughness
Full metallicness, more roughness

Model with albedo texture

For models that have an inherent texture, we sample its albedo from that texture and include it during the final lighting calculations. We also do the same for metallicness, roughness, etc.

As you can see, we’re getting pretty good performance! My laptop has a 120 Hz screen and the renderer is dropping no frames (the recording is limited to 24 FPS unfortunately).

Displacement map

The obsidian block model in particular also has a displacement/normal map. Here it is set to zero and one, respectively.

Zero displacement on black obsidian block
Full displacement of obsidian block.