You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug] - N8AO works incorrectly with adaptiveDpr #280
Hey everyone! I seems found a bug in N8AO related to AdaptiveDpr
We found a strange effect in our application after adding N8AO to EffectComposer - sometimes it started to add weird 'reflections' to the materials, and we couldn't understand where it's coming from
This is how it looks like: On the surface of the model you can see "reflection" from grid, which should't be present (but it's not only about grid but any objects can appear as reflection).
After debugging for a while I've noticed that this happens on my machine when DPR value is changed. If we (or system) change dpr from 2 to 1, N8AO started to add this 'reflections'. As I can see class has size values which are half of the initial renderer size (if I understand correctly)
If I manually call setSize(width, height) method on N8AOPostPass instance and upscale this values back to dpr=2 values this bug disappears. So it's either should always keep initial values or there is some error in calculation after updating render size
Steps to reproduce
Lest say screen size is 1000x500 with dpr=2. initial values of renderer is 2000x1000px, dpr=2, we set dpr to 1, values are updated to 1000x500, bug appears. If I set values manually by calling setSize() on N8AOPostPass instance to setSize(2x1000, 2x500) it starts working correctly again
Root cause: <EffectComposer> re-checks its size every frame, but only against gl.getSize(), the CSS size. setDpr / <AdaptiveDpr> change the pixel ratio and leave the CSS size as is, so composer.setSize() never runs. The composer's buffers and every pass (N8AO included) stay at the old drawing-buffer size, so they no longer match the canvas.
Measured in Chromium on a 480×320 canvas after setDpr(2) → setDpr(1): the canvas is 480×320, but the composer and the N8AO pass stay at 960×640. That also keeps post-processing at 3.6× the GPU time the lower ratio should cost (3.03 vs 0.83 ms per frame).
postprocessing's setSize() already sizes everything from getDrawingBufferSize(), so the fix is to include gl.getPixelRatio() in that per-frame check. PR: #381
Activity
goce-cz commentedon Jun 25, 2025
Have you ever found a solution to this? I'm facing the same problem.
AlexanderMoroz commentedon Jun 30, 2025
Hey! Sorry, didn't see your comment
I honestly don't remember how I came up with this solution but it was working, at least with those lib versions
tonyblu331 commentedon Sep 25, 2026
Root cause:
<EffectComposer>re-checks its size every frame, but only againstgl.getSize(), the CSS size.setDpr/<AdaptiveDpr>change the pixel ratio and leave the CSS size as is, socomposer.setSize()never runs. The composer's buffers and every pass (N8AO included) stay at the old drawing-buffer size, so they no longer match the canvas.Measured in Chromium on a 480×320 canvas after
setDpr(2)→setDpr(1): the canvas is 480×320, but the composer and the N8AO pass stay at 960×640. That also keeps post-processing at 3.6× the GPU time the lower ratio should cost (3.03 vs 0.83 ms per frame).postprocessing's
setSize()already sizes everything fromgetDrawingBufferSize(), so the fix is to includegl.getPixelRatio()in that per-frame check. PR: #381fix(EffectComposer): resize the composer when the pixel ratio changes