Skip to content

Commit

Permalink
WebGPURenderer: ReadRenderTargetPixelsAsync (RFC) (#26326)
Browse files Browse the repository at this point in the history
* add support for meshPhongNodeMaterial

* draft readPixel api

* Update examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js

Co-authored-by: Levi Pesin <[email protected]>

* Update examples/jsm/renderers/common/Renderer.js

Co-authored-by: Levi Pesin <[email protected]>

---------

Co-authored-by: aardgoose <[email protected]>
Co-authored-by: Levi Pesin <[email protected]>
  • Loading branch information
3 people authored Jun 26, 2023
1 parent cdfefb4 commit b287bde
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 0 deletions.
2 changes: 2 additions & 0 deletions examples/jsm/renderers/common/Backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class Backend {

createTexture( texture ) { }

copyTextureToBuffer( texture, x, y, width, height ) {}

// attributes

createAttribute( attribute ) { }
Expand Down
6 changes: 6 additions & 0 deletions examples/jsm/renderers/common/Renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,12 @@ class Renderer {

}

readRenderTargetPixelsAsync( renderTarget, x, y, width, height ) {

return this.backend.copyTextureToBuffer( renderTarget.texture, x, y, width, height );

}

_projectObject( object, camera, groupOrder, renderList ) {

if ( object.visible === false ) return;
Expand Down
6 changes: 6 additions & 0 deletions examples/jsm/renderers/webgpu/WebGPUBackend.js
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,12 @@ class WebGPUBackend extends Backend {

}

copyTextureToBuffer( texture, x, y, width, height ) {

return this.textureUtils.copyTextureToBuffer( texture, x, y, width, height );

}

// node builder

createNodeBuilder( object, renderer ) {
Expand Down
82 changes: 82 additions & 0 deletions examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,52 @@ class WebGPUTextureUtils {

}

async copyTextureToBuffer( texture, x, y, width, height ) {

const device = this.backend.device;

const textureData = this.backend.get( texture );
const textureGPU = textureData.texture;
const format = textureData.textureDescriptorGPU.format;
const bytesPerTexel = this._getBytesPerTexel( format );

const readBuffer = device.createBuffer(
{
size: width * height * bytesPerTexel,
usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ
}
);

const encoder = device.createCommandEncoder();

encoder.copyTextureToBuffer(
{
texture: textureGPU,
origin: { x, y },
},
{
buffer: readBuffer,
bytesPerRow: width * bytesPerTexel
},
{
width: width,
height: height
}

);

const typedArrayType = this._getTypedArrayType( format );

device.queue.submit( [ encoder.finish() ] );

await readBuffer.mapAsync( GPUMapMode.READ );

const buffer = readBuffer.getMappedRange();

return new typedArrayType( buffer );

}

_isEnvironmentTexture( texture ) {

const mapping = texture.mapping;
Expand Down Expand Up @@ -579,6 +625,42 @@ class WebGPUTextureUtils {

}

_getTypedArrayType( format ) {

if ( format === GPUTextureFormat.R8Uint ) return Uint8Array;
if ( format === GPUTextureFormat.R8Sint ) return Int8Array;
if ( format === GPUTextureFormat.R8Unorm ) return Uint8Array;
if ( format === GPUTextureFormat.R8Snorm ) return Int8Array;
if ( format === GPUTextureFormat.RG8Uint ) return Uint8Array;
if ( format === GPUTextureFormat.RG8Sint ) return Int8Array;
if ( format === GPUTextureFormat.RG8Unorm ) return Uint8Array;
if ( format === GPUTextureFormat.RG8Snorm ) return Int8Array;
if ( format === GPUTextureFormat.RGBA8Uint ) return Uint8Array;
if ( format === GPUTextureFormat.RGBA8Sint ) return Int8Array;
if ( format === GPUTextureFormat.RGBA8Unorm ) return Uint8Array;
if ( format === GPUTextureFormat.RGBA8Snorm ) return Int8Array;


if ( format === GPUTextureFormat.R16Uint ) return Uint16Array;
if ( format === GPUTextureFormat.R16Sint ) return Int16Array;
if ( format === GPUTextureFormat.RG16Uint ) return Uint16Array;
if ( format === GPUTextureFormat.RG16Sint ) return Int16Array;
if ( format === GPUTextureFormat.RGBA16Uint ) return Uint16Array;
if ( format === GPUTextureFormat.RGBA16Sint ) return Int16Array;


if ( format === GPUTextureFormat.R32Uint ) return Uint32Array;
if ( format === GPUTextureFormat.R32Sint ) return Int32Array;
if ( format === GPUTextureFormat.R32Float ) return Float32Array;
if ( format === GPUTextureFormat.RG32Uint ) return Uint32Array;
if ( format === GPUTextureFormat.RG32Sint ) return Int32Array;
if ( format === GPUTextureFormat.RG32Float ) return Float32Array;
if ( format === GPUTextureFormat.RGBA32Uint ) return Uint32Array;
if ( format === GPUTextureFormat.RGBA32Sint ) return Int32Array;
if ( format === GPUTextureFormat.RGBA32Float ) return Float32Array;

}

_getDimension( texture ) {

let dimension;
Expand Down

0 comments on commit b287bde

Please sign in to comment.