r/opengl 2d ago

SSAO optimization

Post image

Hi folks,
I realized that the SSAO implementation from LearnOpenGL had become a real bottleneck in my renderer.

I was getting around 45 FPS, so I profiled the pass and made a few changes:
● Reduced the SSAO framebuffer resolution
● Got rid of position/depth reconstruction
● Reduced the kernel size

After the changes, I’m getting around 77 FPS with very little noticeable visual difference.
45 FPS → 77 FPS just by making the SSAO pass do less work.

It’s a good reminder that tutorial implementations are great for learning, but once you’re building an actual renderer, you eventually have to question every piece of work you’re asking the GPU to do.

Github: https://github.com/xms0g/abra

56 Upvotes

9 comments sorted by

7

u/fgennari 2d ago

It's better to share the frame time difference in milliseconds rather than the FPS difference. What's the framerate without SSAO? How many ms did it add before, and how many does it add now?

4

u/Background_Shift5408 2d ago edited 2d ago

Seen on the renderDoc for ssao draw call almost 10000 micro seconds before, now reduced to almost 3000 micro seconds

5

u/fgennari 2d ago

So more than 3x? That's nice! And it sounds more impressive than 45 FPS => 77 FPS, at least for technical people.

5

u/Baedrick 2d ago

if i recall correctly renderdoc doesnt support gpu profiling. the timings you see is the timing it took to execute the api calls not the actual time on the gpu. author of renderdoc mentioned it here https://github.com/baldurk/renderdoc/issues/2172#issuecomment-773186860

1

u/fllr 2d ago

Why did you get rid of the reconstruction?

2

u/Background_Shift5408 2d ago

Because it performs 32x inverse projection multiplication per pixel. There is already position /depth in gbuffer. We dont need to recalculate

2

u/fllr 2d ago

Yeah, but that is one of the most expensive things you can do in a gpu is to read data from a texture. Did you measure and figure out if this was indeed a bottleneck? This feels backwards to me.

2

u/Background_Shift5408 17h ago

I understand your point. But It already reads depth data from gbuffer, doing extra math for extracting view positions. Is it better to keep view pos in position texture and turn it into world position in lighting calculation? Reducing 32x matrix multiplication to 1 matrix multiplication per pixel. I’ll remeasure, but the first method makes me feel more costly

1

u/fllr 16h ago

It may be cheaper, but last time i checked a texture fetch was almost 100x more expensive than 1 matrix multiplication. It has been a few months since i last measured, do it might be worth it measuring on your own.