Life got in my way a wee bit lately (a trip back to New Zealand, a Windows 11 update bricking an SSD and finishing up the work year to name a few recent events), though I have been tapping away at StaticRectangle.

SSAO

I decided to tackle SSAO (screen space ambient occlusion) after reading through the learnopengl SSAO article, it didn’t seem like too much extra work on top of what I had just completed for shadows.

Would you believe me if I said I was right? I bet you were expecting me to say that I had jinxed myself and it was, in fact, a lot of extra work; that’s usually how these things go.

For SSAO, I needed a new ‘Geometry Pass’ that creates depth and normal resources from the camera’s perspective in screen space.

  • Depth: A depth map that allows you to reconstruct the 3D position of each pixel
  • Normals: The direction of the surface each pixel belongs to

With these maps, you create an SSAO shader that samples around the current pixel and determines if ambient light would be occluded due to the pixel’s proximity to surrounding surfaces.

You then take the output of that shader and multiply it on top of your primary render passes output colour.

This is great for creating contact shadows and accentuating geometric details that are often flattened out by your lighting.

As you can see, the result can be quite subtle, but it’s something you miss when it’s not present.

AT-ST SSAO FTW

To really appreciate this, you need something with a bit more geometric detail1.

  • h toggles the render options
  • ~ opens the terminal
  • Mouse look with left/right mouse buttons
  • w, a, s, d to move

lil-gui

Wait, where did that UI come from? remember how I said that the SSAO pass wasn’t that much work? well that was a half truth.

In order for me to tune the various SSAO parameters (bias, radius etc.) I was really needing a user interface to fiddle with; changing variables and rebuilding, even if relatively quick, was getting rather tedious.

I decided to use a 3rd party solution after coming across lil-gui. It’s reminiscent of Dear ImGUI which I was looking at for the Vulkan C++ version of StaticRectangle.

In order to slot this in, it meant some work on the EventManager to send/recieve signals from the UI.

I will eventually have a first-class UI component for StaticRectangle, but for now lil-gui is perfectly fine, even with its limitations.

SSAO Blur

You may have noticed there is an option for SSAO and SSAO Blur. I left this in there for demonstration, you wouldn’t typically disable SSAO blur.

SSAO generally requires two passes, first to produce the SSAO map, and then to blur it. The blur is required because SSAO can be quite noisy. In my case, not just because of the sample size, but also because in my implementation (as described in the learnopengl SSAO article) I’m rotating the sample kernel per-pixel to try avoid banding/obvious repeating patterns.

To see this best demonstrated, disable Lighting in the Render Options and zoom in closer to the geometry and toggle the blur on/off.


  1. This AT-ST model is the “rough” blocked in shapes I was using as a template for a much more detailed model (that I never finished…). Coincidentally, the blocking version lends itself nicely for real-time. I never intended it to be a real-time/game model which is why it doesn’t have textures and isn’t the best topology wise. Maybe I’ll finish it sometime? ↩︎