From 2b6771eaf4ad946a741faa6058f56311b77d0447 Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Fri, 24 Jan 2025 22:59:36 +0100 Subject: [PATCH] WebGPURenderer: Only use `HalfFloatType` for the framebuffer target if necessary. --- src/renderers/common/Backend.js | 11 +++++++++++ src/renderers/common/Renderer.js | 23 ++++++++++++++++++++--- src/renderers/webgpu/WebGPUBackend.js | 13 ++++++++++++- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/renderers/common/Backend.js b/src/renderers/common/Backend.js index 028b74463d26eb..b6b9e0dab68f0d 100644 --- a/src/renderers/common/Backend.js +++ b/src/renderers/common/Backend.js @@ -588,6 +588,17 @@ class Backend { } + /** + * Returns `true` if the backend requires a framebuffer target with type `HalfFloat`. + * + * @return {Boolean} Whether the backend requires a framebuffer target with type `HalfFloat` or not. + */ + needsHalfFloatFrameBufferTarget() { + + return false; + + } + /** * Sets a dictionary for the given object into the * internal data structure. diff --git a/src/renderers/common/Renderer.js b/src/renderers/common/Renderer.js index 6463696ff0c625..aedce9cfd64dad 100644 --- a/src/renderers/common/Renderer.js +++ b/src/renderers/common/Renderer.js @@ -26,7 +26,7 @@ import { Matrix4 } from '../../math/Matrix4.js'; import { Vector2 } from '../../math/Vector2.js'; import { Vector4 } from '../../math/Vector4.js'; import { RenderTarget } from '../../core/RenderTarget.js'; -import { DoubleSide, BackSide, FrontSide, SRGBColorSpace, NoToneMapping, LinearFilter, LinearSRGBColorSpace, HalfFloatType, RGBAFormat, PCFShadowMap } from '../../constants.js'; +import { DoubleSide, BackSide, FrontSide, SRGBColorSpace, NoToneMapping, LinearFilter, LinearSRGBColorSpace, HalfFloatType, RGBAFormat, PCFShadowMap, UnsignedByteType } from '../../constants.js'; /** @module Renderer **/ @@ -453,6 +453,15 @@ class Renderer { */ this._frameBufferTarget = null; + /** + * Used to identify the framebuffer target. + * + * @private + * @type {Number?} + * @default null + */ + this._frameBufferTargetKey = null; + const alphaClear = this.alpha === true ? 0 : 1; /** @@ -1123,12 +1132,19 @@ class Renderer { let frameBufferTarget = this._frameBufferTarget; - if ( frameBufferTarget === null ) { + if ( frameBufferTarget === null || this._frameBufferTargetKey !== currentToneMapping ) { + + if ( frameBufferTarget !== null ) frameBufferTarget.dispose(); + + // to improve performance we only want to use HalfFloatType if necessary + // HalfFloatType is required when a) tone mapping is configured or b) the backend specifically requests it + + const type = ( currentToneMapping !== NoToneMapping || this.backend.needsHalfFloatFrameBufferTarget() ) ? HalfFloatType : UnsignedByteType; frameBufferTarget = new RenderTarget( width, height, { depthBuffer: depth, stencilBuffer: stencil, - type: HalfFloatType, // FloatType + type: type, format: RGBAFormat, colorSpace: LinearSRGBColorSpace, generateMipmaps: false, @@ -1140,6 +1156,7 @@ class Renderer { frameBufferTarget.isPostProcessingRenderTarget = true; this._frameBufferTarget = frameBufferTarget; + this._frameBufferTargetKey = currentToneMapping; } diff --git a/src/renderers/webgpu/WebGPUBackend.js b/src/renderers/webgpu/WebGPUBackend.js index da44414d90327f..4b961f7c151ca0 100644 --- a/src/renderers/webgpu/WebGPUBackend.js +++ b/src/renderers/webgpu/WebGPUBackend.js @@ -13,7 +13,7 @@ import WebGPUBindingUtils from './utils/WebGPUBindingUtils.js'; import WebGPUPipelineUtils from './utils/WebGPUPipelineUtils.js'; import WebGPUTextureUtils from './utils/WebGPUTextureUtils.js'; -import { WebGPUCoordinateSystem } from '../../constants.js'; +import { HalfFloatType, WebGPUCoordinateSystem } from '../../constants.js'; import WebGPUTimestampQueryPool from './utils/WebGPUTimestampQueryPool.js'; /** @@ -279,6 +279,17 @@ class WebGPUBackend extends Backend { } + /** + * Returns `true` if the backend requires a framebuffer target with type `HalfFloat`. + * + * @return {Boolean} Whether the backend requires a framebuffer target with type `HalfFloat` or not. + */ + needsHalfFloatFrameBufferTarget() { + + return ( this.parameters.outputType === HalfFloatType ); + + } + /** * Returns the default render pass descriptor. *