Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

readRenderTargetPixels() works for WebGLRenderTarget but is all 0 for WebGL3DRenderTarget #28501

Open
hubtub2 opened this issue May 27, 2024 · 21 comments

Comments

@hubtub2
Copy link

hubtub2 commented May 27, 2024

Description

I am using a shader to write to a 3D render target.
To debug the result I am using renderer.readRenderTargetPixels()

The result for WebGLRenderTarget is correct, the result for WebGL3DRenderTarget is all zero.

Reproduction steps

Please check the fiddle:

  1. First run as is and check the output on the console: the buffer contains 0,0,0,255
  2. Now go to line 66 and enable the line with WebGLRenderTarget and disable the line with WebGL3DRenderTarget
  3. The output now is correct: 102, 255, 15, 255

Code

See fiddle for complete example.

//-- 3D or 2D Render target
// brushTarget = new THREE.WebGLRenderTarget(32, 32) 
brushTarget = new THREE.WebGL3DRenderTarget(32, 32, 32)


var layer=0;   // Layer in 3D Texture

renderer.setRenderTarget(brushTarget, layer);
renderer.render( brushScene, brushCamera );    
    
var buffer = new Uint8Array(4); 
renderer.readRenderTargetPixels(brushTarget, 16, 16, 1, 1, buffer, layer)

console.log("Debug read brush", buffer)   // Press F12 to show chrome console

Live example

https://jsfiddle.net/92xa60g4/25/

Screenshots

No response

Version

r164

Device

Desktop

Browser

Chrome

OS

Windows

@hubtub2
Copy link
Author

hubtub2 commented May 28, 2024

An alternative cause would be that RTT 3D does not work - but I do not see a reason for it.

@Mugen87
Copy link
Collaborator

Mugen87 commented May 28, 2024

I have tested with the latest version r164 and the methods seems to work as expected. Below is the result for a 3D render target (first log) and a normal render target (second log):

image

Can you try it with the latest version as well?

Side note: When calling readRenderTargetPixels(), the last parameter is only relevant for cube render targets since it defines which cube face you want to select. When setting 3D render targets via setRenderTarget(), the method always uses framebufferTextureLayer() to define what layer (depth) should be bound. By default it is zero but you can set any index between [0, depth - 1]. This part is used correctly in the fiddle and it ensures the scene is rendered in the respective layer. Since you don't alter the render target configuration, the readback selects the same layer as well.

@hubtub2
Copy link
Author

hubtub2 commented May 28, 2024

Thank you for testing.
The fiddle imports already the current revision 164, see image:

image

(r156 was just my dev environment - I will change it in the bug report)

Any idea why the output is 0,0,0 on my system? I tried the fiddle in Firefox & Chrome and on Laptop and Workstation - same result - always 0,0,0 for 3D render target :-(

@Mugen87
Copy link
Collaborator

Mugen87 commented May 28, 2024

Oh, I misunderstood your bug report. I was assuming you had issues with an older version of three.js. But since you are also having trouble with r164, this might be a system related issue.

Since you are using Chrome, do you mind typing chrome://gpu/ into the address bar, download the report and share it in this issue? Besides, what happens if you make a test with Firefox?

@hubtub2
Copy link
Author

hubtub2 commented May 28, 2024

So I tried on 3 browsers on 2 systems - the output is consistent:

Firefox Notebook:
image

Chrome Notebook:
image

Firefox Workstation:
image

Chrome Workstation:
image

Edge Workstation:
image

Here is the output of the chrome://gpu/ for both systems:

Notebook:
about-gpu-2024-05-28T12-52-23-516Z.txt

Workstation:
about-gpu-2024-05-28T12-53-45-799Z.txt

I wonder if it is a read or a write problem.

@Mugen87
Copy link
Collaborator

Mugen87 commented May 28, 2024

Is the plane in the following fiddle red or white on your systems? https://jsfiddle.net/9ecums7j/1/

The demo has two passes. The first one renders the scene into the first layer of a 3D render target. The second one uses the first layer as a texture for a plane mesh.

@hubtub2
Copy link
Author

hubtub2 commented May 28, 2024

The render window is black, both computers, Chrome and Firefox.

image

No error message on the console.
After clicking "run" the render window "flashes white" for an instance.

When I replace the WebGL3DRenderTarget with a WebGLRenderTarget, I see a white plane:
image

@Mugen87
Copy link
Collaborator

Mugen87 commented May 28, 2024

When I replace the WebGL3DRenderTarget with a WebGLRenderTarget, I see a white plane:

Using a normal render target is incompatible with the custom shader since it uses sampler3D.

So it seems there is an issue with rendering into 3D render targets on your devices. Or there is an issue with using them as a texture. Maybe the call of gl.framebufferTextureLayer() is broken or something similar.

This is unfortunately not something we can fix in this repository. Would you mind reporting the issue at the Chromium bug tracker (https://issues.chromium.org/issues)? Please attach your Chrome GPU reports, a link to this issue and the below fiddle. I've simplified it a bit so it is focused on the most important things: https://jsfiddle.net/47donLx0/

I've also changed the color semantics. Green color means using the 3D render target as a texture works as expected.

@Mugen87
Copy link
Collaborator

Mugen87 commented May 28, 2024

BTW: Do you see any WebGL warnings in the browser console on the affected devices? Just want to be sure we do not overlook something obvious...

@hubtub2
Copy link
Author

hubtub2 commented May 28, 2024

Will do.
But isn't it suspicious that the behavior is the same on Firefox, which is not using Chromium?
Do they have a common WebGL implementation?

@Mugen87
Copy link
Collaborator

Mugen87 commented May 28, 2024

But isn't it suspicious that the behavior is the same on Firefox, which is not using Chromium?

If it's a GPU driver issue, the used browser does not necessarily matter. If the Chromium devs conclude the root cause is driver related, they might adapt a workaround on browser level or redirect the issue to the GPU vendor.

@aardgoose
Copy link
Contributor

aardgoose commented May 29, 2024

An added datapoint:

I have the same issues, I came across it while implementing WebGL3DRenderTarget in the WebGPURenderer.
WebGPU worked fine, WebGL failed as described above, using FF and Chrome with Intel integrated and external GPUs using D3D and Vulkan backends, which suggests this is an ANGLE problem which is also used by Firefox for WebGL, but not WebGPU in either browser.

In my tests I also noted a flash of color sometimes appearing in the developer console window which I had open as usual.

An elderly MacBook works OK for Safari and Chrome (116 - it hadn't been used for a while) and Chrome 125.

@Mugen87
Copy link
Collaborator

Mugen87 commented May 29, 2024

If the problem is in ANGLE, the Chromium bug tracker is definitely the right sport to report the issue.

@Mugen87
Copy link
Collaborator

Mugen87 commented May 29, 2024

@aardgoose Out of curiosity: Does the reproduction test case also fail on your affected systems? You should see a green plane in https://jsfiddle.net/47donLx0/

@aardgoose
Copy link
Contributor

@Mugen87 Yes, I was just using your test case, I wasn't assuming my patches worked!

@gkjohnson
Copy link
Collaborator

This looks like it's related to, if not a duplicate of, #25353 which shows that rendering to 3d render targets fails in D3D backends (which is used in both reported platforms here). Unfortunately there's been no movement from Chromium in well over a year:

https://issues.chromium.org/issues/40890022

@aardgoose
Copy link
Contributor

@gkjohnson It does look very similar. As noted I saw screen corruption (flashes of color in the developer tools console panel.

@Mugen87
Copy link
Collaborator

Mugen87 commented May 30, 2024

Thanks for mentioning #25353. Before filing a new issue at the Chromium bug tracker, it's probably better to bump the existing one with a new comment. I'll do that later.

Besides, it's not much but maybe it would help if more devs upvote the bug at the Chromium bug tracker. This can be done here:

image
@Mugen87
Copy link
Collaborator

Mugen87 commented Jun 1, 2024

WebGL failed as described above, using FF and Chrome with Intel integrated and external GPUs using D3D and Vulkan backends,

@aardgoose Someone from the Chromium team tested the fiddle with different systems with Vulkan backend and couldn't reproduce, see https://issues.chromium.org/issues/40890022#comment12. Do you mind responding at the bug tracker and share a Chrome GPU report as an attachment of an affected system using Vulkan?

@hubtub2
Copy link
Author

hubtub2 commented Jun 3, 2024

@aardgoose Someone from the Chromium team tested the fiddle with different systems with Vulkan backend and couldn't reproduce, see https://issues.chromium.org/issues/40890022#comment12. Do you mind responding at the bug tracker and share a Chrome GPU report as an attachment of an affected system using Vulkan?

Two follow-up questions:

  1. Which systems are using Vulkan backends for WebGL? MacOS? Then I can test later on my MacBook at home and report for the Chromium team.

  2. Can I switch the rendering backend somehow in Chrome on Windows to make this work for now?

Thx

@Mugen87
Copy link
Collaborator

Mugen87 commented Jun 7, 2024

Which systems are using Vulkan backends for WebGL? MacOS?

AFAIK, mostly Linux systems. Recent Apple devices use Metal. You can check this by opening chrome://gpu/ and then look at the GL_RENDERER value of the report. On my system it says ANGLE (Apple, ANGLE Metal Renderer: Apple M2 Pro, Version 14.4.1 (Build 23E224)) which means it uses a Metal backend.

Can I switch the rendering backend somehow in Chrome on Windows to make this work for now?

You can force a backend when starting the browser via console. However, it is no lasting setting and the selected backend might not be supported on your system. For macOS, it looks like so using Chrome Canary.

Applications/Google\ Chrome\ Canary.app/Contents/MacOS/Google\ Chrome\ Canary --user-data-dir=/tmp/c1 --use-angle=vulkan
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment