Skip to content

Fix halfRes crash on three r187: don't override texture on the MRT compat target - #56

Open
martincollignon wants to merge 1 commit into
N8python:masterfrom
martincollignon:fix-r187-mrt-texture
Open

martincollignon wants to merge 1 commit into
N8python:masterfrom
martincollignon:fix-r187-mrt-texture

Conversation

@martincollignon

Copy link
Copy Markdown

Problem

three r187 made Texture.mipmaps always an array and removed the mipmaps && / mipmaps !== undefined guards in WebGLTextures (mrdoob/three.js#35081). setupRenderTarget now reads renderTarget.texture.mipmaps.length directly.

On three >= 162, WebGLMultipleRenderTargetsCompat overrides get texture() to return this.textures, which is an array. An array has no mipmaps, so with halfRes: true every render throws as soon as the depthDownsampleTarget is bound:

TypeError: Cannot read properties of undefined (reading 'length')
    at WebGLTextures.setupRenderTarget

Both N8AOPass and N8AOPostPass are affected. halfRes: false is not, because the compat target is only created for half resolution.

Fix

Remove the texture getter from the >= 162 branch of src/compat.js. It isn't needed there: N8AO only reads the downsample target through .textures[i], and WebGLRenderTarget created with { count } already exposes texture as textures[0]. The < 162 branch is unchanged. dist/ and the example bundles are rebuilt with npm run build; the only change in each is the same three removed lines.

Reproduction

A plain page: three's EffectComposer with N8AOPass, or postprocessing's EffectComposer → RenderPass → N8AOPostPass, with configuration.halfRes = true, rendering 5 frames.

three 0.186.1 + postprocessing 6.39.5 three 0.187.0 + postprocessing 6.39.6
n8ao 2.0.1, half-res 5/5 frames 0/5, throws (both passes)
this PR, half-res 5/5 5/5
either, halfRes: false 5/5 5/5

With this PR, the N8AOPostPass half-res output on r187 is pixel-identical to n8ao 2.0.1 on r186 (max channel difference 0).

🤖 Generated with Claude Code

…compat target

three r187 made `Texture.mipmaps` always an array and dropped the
`mipmaps &&` guards in WebGLTextures (mrdoob/three.js#35081), so
setupRenderTarget now reads `renderTarget.texture.mipmaps.length`
directly. On three >= 162 the compat class returned the `textures`
array from `get texture()`, which has no `mipmaps`, so every render with
`halfRes: true` threw. The override is not needed there: N8AO only reads
`.textures[i]`, and `WebGLRenderTarget` with `{ count }` already exposes
`texture` as `textures[0]`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ameobea added a commit to Ameobea/n8ao that referenced this pull request Nov 6, 2026
Drops the `texture` getter override on the three >= 162 MRT compat target
(upstream 9f0fcbd by Martin Collignon); dist/ and example bundles rebuilt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant