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

WebGPURenderer: Allow specifying texture index for MRT in readRenderTargetPixelsAsync(). #28197

Merged
merged 2 commits into from
Apr 23, 2024

Conversation

Spiri0
Copy link
Contributor

@Spiri0 Spiri0 commented Apr 23, 2024

Related: #22403

The readRenderTargetAsync function accepts a renderTarget, but so far has no option to choose between the different textures of a renderTarget if it has more than just one texture. That's why I added an index = 0 so that everyone who has used the function so far has no disadvantages because the first texture is always selected by default.

Spiri0 and others added 2 commits April 23, 2024 13:03
The readRenderTargetAsync function accepts a renderTarget, but so far has no option to choose between the different textures of a renderTarget if it has more than just one texture. That's why I added an index = 0 so that everyone who has used the function so far has no disadvantages because the first texture is always selected by default.
@Mugen87 Mugen87 changed the title Update Renderer.js Apr 23, 2024

return this.backend.copyTextureToBuffer( renderTarget.texture, x, y, width, height );
return this.backend.copyTextureToBuffer( renderTarget.textures[ index ], x, y, width, height );
Copy link
Collaborator

@Mugen87 Mugen87 Apr 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this code...actually work? At least the WebGL backend won't work until gl.readBuffer() is used in WebGLTextureUtils.copyTextureToBuffer().

I'm not sure about required workflow in WebGPU. Do you mind demonstrating the updated method with an example? E.g. you could use the code from https://threejs.org/examples/webgpu_multiple_rendertargets but instead of rendering to the screen, you extract (color and normal) values via readRenderTargetPixelsAsync().

@Spiri0
Copy link
Contributor Author

Spiri0 commented Apr 23, 2024

I made an example. Since this is my first one I must have missed something in the PR. It works for me. #28198

1 (4)
readback wood from gpu
2 (5)
readback normal from gpu
3 (5)

The textures read back from the GPU were created with a smaller render target. Users have to be careful with readRenderPixelsAsync because the CPU is not intended to receive large amounts of data from the GPU. Maybe a size selection button in the GUI would be nice for different readback sizes?

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 23, 2024

Okay, then it seems to work for WebGPU but not WebGL. However, that can be fixed at a later point as well.

@aardgoose Does this change look good to you?

@sunag sunag added this to the r164 milestone Apr 23, 2024
@aardgoose
Copy link
Contributor

Okay, then it seems to work for WebGPU but not WebGL. However, that can be fixed at a later point as well.

@aardgoose Does this change look good to you?

It looks fine, actually it works with WebGL. The texture copied is always mapped to color attachment 0 so no need for readBuffer() changes.

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 23, 2024

The texture copied is always mapped to color attachment 0 so no need for readBuffer() changes.

But that means it's not possible to read subsequent color attachments, just 0, right? So in the demo it should not be possible to extract normal values.

@aardgoose
Copy link
Contributor

The texture copied is always mapped to color attachment 0 so no need for readBuffer() changes.

But that means it's not possible to read subsequent color attachments, just 0, right? So in the demo it should not be possible to extract normal values.

It works for both, it maps the chosen texture to a temporary framebuffer as attachment 0, I've tested the path and demo to check.

@Spiri0
Copy link
Contributor Author

Spiri0 commented Apr 23, 2024

@Mugen87 In the third screenshot you can see the normal texture read back. In this case, index 0 is then set to 1 (line 218 reads back the normal ones). I now see that it would be better if the respective readback were in the respective selector, then both would not always be read back but only the selected one.
I can improve that later, as well as the option to select the readback resolution.
But the PR in the example didn't work. What did I forget to take into account?

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 23, 2024

But the PR in the example didn't work. What did I forget to take into account?

Not sure what you mean by that. Do you mind rephrasing?

@Spiri0
Copy link
Contributor Author

Spiri0 commented Apr 23, 2024

Doesn't seem like anything important. In the details it says that screenshots could not be created.

Screenshot_20240423_234345_Chrome

@sunag sunag changed the title Renderer: Allow specifying texture index for MRT in readRenderTargetPixelsAsync(). Apr 23, 2024
@sunag sunag merged commit 5493cfa into mrdoob:dev Apr 23, 2024
11 checks passed
@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 24, 2024

Let's talk about this issue in #28198.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
4 participants