mrdoob / three.js

JavaScript 3D Library.
https://threejs.org/
MIT License
102.74k stars 35.38k forks source link

GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture. #25990

Closed crystalthoughts closed 1 year ago

crystalthoughts commented 1 year ago

Description

I notice this error message was mentioned in a closed ticket, under a different scenario. It looks like the transmission shader is causing issues. Is it safe to ignore or is it preventing proper functionality?

As an aside, is this shader the same as in the GLTF example?

Reproduction steps

See the fiddle. Turning off transparency on the material will prevent the error.

Code

I have a HDRI loaded (inside my init function):

Adding this to my scene causes the title error:

    const donut = new THREE.TorusKnotGeometry

    const glass = new THREE.MeshPhysicalMaterial( {
        color: 0xffffff,
        // transmission: 1,  // turning this on is the issue
        opacity: 1,
        metalness: 0,
        roughness: 0,
        ior: 1.5,
        thickness: 0.01,
        specularIntensity: 1,
        specularColor: new THREE.Color(0xffffff) ,
        envMapIntensity: 1,
        side: THREE.DoubleSide,
        transparent: true
    } );
    const donutMesh= new THREE.Mesh(donut,glass);

I assume it's related to the refraction code?

Live example

Screenshots

image

Version

0.15.2 (latest)

Device

Desktop

Browser

Chrome

OS

Windows

Mugen87 commented 1 year ago

I don't know why but enabling anti-aliasing fixes the issue: https://jsfiddle.net/kd0jf95y/

Can you please confirm this on your side?

crystalthoughts commented 1 year ago

Yes, this stops the errors on my side too. How strange.

Mugen87 commented 1 year ago

I guess we should report this to the Chromium bug tracker. It's strange that the anti-aliasing setting makes a difference.

BTW: Safari 16.4 on macOS does not show a warning.

crystalthoughts commented 1 year ago

Is aa handled by chrome? What should the ticket look like ?

On Fri, 5 May 2023 at 11:24, Michael Herzog @.***> wrote:

I guess we should report this to the Chromium bug tracker https://bugs.chromium.org/p/chromium/issues/list. It's strange that the anti-aliasing setting makes a difference.

BTW: Safari 16.4 on macOS does not show a warning.

— Reply to this email directly, view it on GitHub https://github.com/mrdoob/three.js/issues/25990#issuecomment-1535978352, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABSNQQDIU6FAGPFDJIVJLWDXETBMHANCNFSM6AAAAAAXWXRBPA . You are receiving this because you authored the thread.Message ID: @.***>

Mugen87 commented 1 year ago

Is aa handled by chrome?

Passing antialias: true to WebGLRenderer enables the default anti-aliasing by WebGL. So it is not implement on engine-level.

What should the ticket look like ?

If possible, it would be good to track the issue further down so we can provide a more simple example to the Chromium bug tracker. Otherwise we can use your fiddle and see what they say about the difference between the anti-aliasing and no anti-aliasing case.

Mugen87 commented 1 year ago

Investigated the issue a bit more and the the warning pops up with r151 the first time: https://jsfiddle.net/1r83edh0/1/

When reverting #25502, the warning goes away. So it seems the two pass rendering of transmissive objects introduces the issue.

Mugen87 commented 1 year ago

I have filed a bug at the Chromium bug tracker: https://bugs.chromium.org/p/chromium/issues/detail?id=1445458

Disabling anti-aliasing not only produces the WebGL warning in the browser console, the transmissive effect actually breaks since the inner reflections are missing. You can easily see this when open the test case twice and enabling anti-aliasing in one of them.

This happens in all browsers I have tested with (Chrome, Firefox and Safari) although only Chrome and Firefox log a WebGL warning.

Mugen87 commented 1 year ago

When reverting https://github.com/mrdoob/three.js/pull/25502, the warning goes away. So it seems the two pass rendering of transmissive objects introduces the issue.

The problem is indeed this part:

https://github.com/mrdoob/three.js/blob/90858b213dcab40509d6b98f776c5e9a4b29dd83/src/renderers/WebGLRenderer.js#L1392-L1406

Meaning when the transmissive objects are rendered with their back sides (which is done to achieve proper inner reflections). The objects are using a transmissive texture (transmissionSamplerMap) which is equal to the active render target. That explains why the browsers complain about a feedback loop.

It would be still interesting to know why enabling anti-aliasing masks the issue.

aardgoose commented 1 year ago

@Mugen87 FWIW Looking at the FF source, the antialias path allocates a RenderBuffer object as a target while the non-AA path allocates a texture directly, presumably the same texture that is already in use. I presume the other browsers follow a similar pattern.

Mugen87 commented 1 year ago

Good point! I think we have to re-evaluate the issue: We have to fix the feedback loop on our side. The fact that the implementation works with enabled anti-aliasing is a side effect of how browser do MSAA.

Um, I guess the issue can only be fixed by using an additional transmission render target?

Mugen87 commented 1 year ago

I've tried to fix the issue by copying the transmission render target into a texture (via copyFramebufferToTexture()) and use the texture for the back side pass, however, it did not work so far. The WebGL warning is gone but the transmissive object does not show up anymore.

Mugen87 commented 1 year ago

The fact that the implementation works with enabled anti-aliasing is a side effect of how browser do MSAA.

Clarification: The problem is not the anti-aliasing of the default framebuffer. It's the usage of a multisampled transmissive render target. If you use 0 at the following line, you can always trigger the WebGL warning no matter how you configure the WebGL rendering context.

https://github.com/mrdoob/three.js/blob/7cba91cee7ff1b36250c1535f717255555b6874b/src/renderers/WebGLRenderer.js#L1349

AlexanderProd commented 10 months ago

I'm getting the same warning when calling renderer.render twice in my render loop.

function render() {
  requestAnimationFrame(render);

  update(0.01);

  renderer.setRenderTarget(renderTarget);
  renderer.render(scene, camera);
  renderer.setRenderTarget(null);
  renderer.render(scene, camera);
}

Enabling AA didn't fix it for me.

I'm using three.js 0.160.0 and Chrome 120.0.6099.129

LukaTizic94 commented 5 months ago

I have the same problem. Did you find any solution? @AlexanderProd