From 4b972f250ad467301a180fc2c27f101aac2b2022 Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Wed, 29 Jan 2025 15:18:27 +0100 Subject: [PATCH] Renderer: Introduce `colorBufferType`. --- examples/webgpu_xr_cubes.html | 2 +- src/nodes/display/PassNode.js | 4 ++- src/renderers/common/Renderer.js | 31 ++++++++++++++++++-- src/renderers/webgpu/WebGPURenderer.Nodes.js | 10 ++++--- src/renderers/webgpu/WebGPURenderer.js | 2 ++ 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/examples/webgpu_xr_cubes.html b/examples/webgpu_xr_cubes.html index eb83322a6bd988..78bab8868dd572 100644 --- a/examples/webgpu_xr_cubes.html +++ b/examples/webgpu_xr_cubes.html @@ -96,7 +96,7 @@ raycaster = new THREE.Raycaster(); - renderer = new THREE.WebGPURenderer( { antialias: true, forceWebGL: true } ); + renderer = new THREE.WebGPURenderer( { antialias: true, forceWebGL: true, colorBufferType: THREE.UnsignedByteType } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); renderer.setAnimationLoop( animate ); diff --git a/src/nodes/display/PassNode.js b/src/nodes/display/PassNode.js index 45ddea6e6db243..fdece54ed8a695 100644 --- a/src/nodes/display/PassNode.js +++ b/src/nodes/display/PassNode.js @@ -546,13 +546,15 @@ class PassNode extends TempNode { this.renderTarget.samples = this.options.samples === undefined ? renderer.samples : this.options.samples; - // Disable MSAA for WebGL backend for now + // TODO: Disable MSAA for WebGL backend for now if ( renderer.backend.isWebGLBackend === true ) { this.renderTarget.samples = 0; } + this.renderTarget.texture.type = renderer.getColorBufferType(); + return this.scope === PassNode.COLOR ? this.getTextureNode() : this.getLinearDepthNode(); } diff --git a/src/renderers/common/Renderer.js b/src/renderers/common/Renderer.js index 6463696ff0c625..388407d9cee9e0 100644 --- a/src/renderers/common/Renderer.js +++ b/src/renderers/common/Renderer.js @@ -55,6 +55,8 @@ class Renderer { * @param {Number} [parameters.samples=0] - When `antialias` is `true`, `4` samples are used by default. This parameter can set to any other integer value than 0 * to overwrite the default. * @param {Function?} [parameters.getFallback=null] - This callback function can be used to provide a fallback backend, if the primary backend can't be targeted. + * @param {Number} [parameters.colorBufferType=HalfFloatType] - Defines the type of color buffers. The default `HalfFloatType` is recommend for best + * quality. To save memory and bandwidth, `UnsignedByteType` might be used. This will reduce rendering quality though. */ constructor( backend, parameters = {} ) { @@ -76,7 +78,8 @@ class Renderer { stencil = false, antialias = false, samples = 0, - getFallback = null + getFallback = null, + colorBufferType = HalfFloatType } = parameters; /** @@ -577,6 +580,17 @@ class Renderer { */ this.onDeviceLost = this._onDeviceLost; + /** + * Defines the type of color buffers. The default `HalfFloatType` is recommend for + * best quality. To save memory and bandwidth, `UnsignedByteType` might be used. + * This will reduce rendering quality though. + * + * @private + * @type {Number} + * @default HalfFloatType + */ + this._colorBufferType = colorBufferType; + /** * Whether the renderer has been initialized or not. * @@ -974,6 +988,17 @@ class Renderer { } + /** + * Returns the color buffer type. + * + * @return {Number} The color buffer type. + */ + getColorBufferType() { + + return this._colorBufferType; + + } + /** * Default implementation of the device lost callback. * @@ -1128,7 +1153,7 @@ class Renderer { frameBufferTarget = new RenderTarget( width, height, { depthBuffer: depth, stencilBuffer: stencil, - type: HalfFloatType, // FloatType + type: this._colorBufferType, format: RGBAFormat, colorSpace: LinearSRGBColorSpace, generateMipmaps: false, @@ -2026,6 +2051,8 @@ class Renderer { this._renderContexts.dispose(); this._textures.dispose(); + if ( this._frameBufferTarget !== null ) this._frameBufferTarget.dispose(); + Object.values( this.backend.timestampQueryPool ).forEach( queryPool => { if ( queryPool !== null ) queryPool.dispose(); diff --git a/src/renderers/webgpu/WebGPURenderer.Nodes.js b/src/renderers/webgpu/WebGPURenderer.Nodes.js index d5c7c18a69e499..62b7d458dc515c 100644 --- a/src/renderers/webgpu/WebGPURenderer.Nodes.js +++ b/src/renderers/webgpu/WebGPURenderer.Nodes.js @@ -7,6 +7,7 @@ import BasicNodeLibrary from './nodes/BasicNodeLibrary.js'; * This alternative version of {@link WebGPURenderer} only supports node materials. * So classes like `MeshBasicMaterial` are not compatible. * + * @private * @augments module:Renderer~Renderer */ class WebGPURenderer extends Renderer { @@ -20,10 +21,11 @@ class WebGPURenderer extends Renderer { * @param {Boolean} [parameters.depth=true] - Whether the default framebuffer should have a depth buffer or not. * @param {Boolean} [parameters.stencil=false] - Whether the default framebuffer should have a stencil buffer or not. * @param {Boolean} [parameters.antialias=false] - Whether MSAA as the default anti-aliasing should be enabled or not. - * @param {Number} [parameters.samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0 - * to overwrite the default. - * @param {Boolean} [parameters.forceWebGL=false] - If set to `true`, the renderer uses it - * WebGL 2 backend no matter if WebGPU is supported or not. + * @param {Number} [parameters.samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0 to overwrite the default. + * @param {Boolean} [parameters.forceWebGL=false] - If set to `true`, the renderer uses it WebGL 2 backend no matter if WebGPU is supported or not. + * @param {Number} [parameters.outputType=undefined] - Texture type for output to canvas. By default, device's preferred format is used; other formats may incur overhead. + * @param {Number} [parameters.colorBufferType=HalfFloatType] - Defines the type of color buffers. The default `HalfFloatType` is recommend for best + * quality. To save memory and bandwidth, `UnsignedByteType` might be used. This will reduce rendering quality though. */ constructor( parameters = {} ) { diff --git a/src/renderers/webgpu/WebGPURenderer.js b/src/renderers/webgpu/WebGPURenderer.js index 2f73348b11ad94..274adbb5270a3d 100644 --- a/src/renderers/webgpu/WebGPURenderer.js +++ b/src/renderers/webgpu/WebGPURenderer.js @@ -38,6 +38,8 @@ class WebGPURenderer extends Renderer { * @param {Number} [parameters.samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0 to overwrite the default. * @param {Boolean} [parameters.forceWebGL=false] - If set to `true`, the renderer uses a WebGL 2 backend no matter if WebGPU is supported or not. * @param {Number} [parameters.outputType=undefined] - Texture type for output to canvas. By default, device's preferred format is used; other formats may incur overhead. + * @param {Number} [parameters.colorBufferType=HalfFloatType] - Defines the type of color buffers. The default `HalfFloatType` is recommend for best + * quality. To save memory and bandwidth, `UnsignedByteType` might be used. This will reduce rendering quality though. */ constructor( parameters = {} ) {