diff --git a/packages/dev/core/src/Engines/Extensions/engine.multiRender.ts b/packages/dev/core/src/Engines/Extensions/engine.multiRender.ts index 0d7570b99f0..af3f9fe4e47 100644 --- a/packages/dev/core/src/Engines/Extensions/engine.multiRender.ts +++ b/packages/dev/core/src/Engines/Extensions/engine.multiRender.ts @@ -169,11 +169,13 @@ ThinEngine.prototype.createMultipleRenderTarget = function (size: TextureSize, o const defaultType = Constants.TEXTURETYPE_UNSIGNED_INT; const defaultSamplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE; const defaultUseSRGBBuffer = false; + const defaultFormat = Constants.TEXTUREFORMAT_RGBA; const defaultTarget = Constants.TEXTURE_2D; let types = new Array(); let samplingModes = new Array(); let useSRGBBuffers = new Array(); + let formats = new Array(); let targets = new Array(); let faceIndex = new Array(); let layerIndex = new Array(); @@ -197,6 +199,9 @@ ThinEngine.prototype.createMultipleRenderTarget = function (size: TextureSize, o if (options.useSRGBBuffers) { useSRGBBuffers = options.useSRGBBuffers; } + if (options.formats) { + formats = options.formats; + } if (options.targetTypes) { targets = options.targetTypes; } @@ -249,6 +254,7 @@ ThinEngine.prototype.createMultipleRenderTarget = function (size: TextureSize, o let samplingMode = samplingModes[i] || defaultSamplingMode; let type = types[i] || defaultType; let useSRGBBuffer = useSRGBBuffers[i] || defaultUseSRGBBuffer; + const format = formats[i] || defaultFormat; const target = targets[i] || defaultTarget; const layerCount = layers[i] ?? 1; @@ -289,7 +295,8 @@ ThinEngine.prototype.createMultipleRenderTarget = function (size: TextureSize, o gl.texParameteri(target, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); gl.texParameteri(target, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - const internalSizedFormat = this._getRGBABufferInternalSizedFormat(type, Constants.TEXTUREFORMAT_RGBA, useSRGBBuffer); + const internalSizedFormat = this._getRGBABufferInternalSizedFormat(type, format, useSRGBBuffer); + const internalFormat = this._getInternalFormat(format); const webGLTextureType = this._getWebGLTextureType(type); if (isWebGL2 && (target === Constants.TEXTURE_2D_ARRAY || target === Constants.TEXTURE_3D)) { @@ -301,15 +308,15 @@ ThinEngine.prototype.createMultipleRenderTarget = function (size: TextureSize, o texture.baseDepth = texture.depth = layerCount; - gl.texImage3D(target, 0, internalSizedFormat, width, height, layerCount, 0, gl.RGBA, webGLTextureType, null); + gl.texImage3D(target, 0, internalSizedFormat, width, height, layerCount, 0, internalFormat, webGLTextureType, null); } else if (target === Constants.TEXTURE_CUBE_MAP) { // We have to generate all faces to complete the framebuffer for (let i = 0; i < 6; i++) { - gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalSizedFormat, width, height, 0, gl.RGBA, webGLTextureType, null); + gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, internalSizedFormat, width, height, 0, internalFormat, webGLTextureType, null); } texture.isCube = true; } else { - gl.texImage2D(gl.TEXTURE_2D, 0, internalSizedFormat, width, height, 0, gl.RGBA, webGLTextureType, null); + gl.texImage2D(gl.TEXTURE_2D, 0, internalSizedFormat, width, height, 0, internalFormat, webGLTextureType, null); } if (generateMipMaps) { @@ -329,6 +336,7 @@ ThinEngine.prototype.createMultipleRenderTarget = function (size: TextureSize, o texture.samplingMode = samplingMode; texture.type = type; texture._useSRGBBuffer = useSRGBBuffer; + texture.format = format; this._internalTexturesCache.push(texture); } diff --git a/packages/dev/core/src/Engines/WebGPU/Extensions/engine.multiRender.ts b/packages/dev/core/src/Engines/WebGPU/Extensions/engine.multiRender.ts index b9db05afad9..415cc0cf259 100644 --- a/packages/dev/core/src/Engines/WebGPU/Extensions/engine.multiRender.ts +++ b/packages/dev/core/src/Engines/WebGPU/Extensions/engine.multiRender.ts @@ -52,10 +52,12 @@ WebGPUEngine.prototype.createMultipleRenderTarget = function (size: TextureSize, const defaultType = Constants.TEXTURETYPE_UNSIGNED_INT; const defaultSamplingMode = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE; const defaultUseSRGBBuffer = false; + const defaultFormat = Constants.TEXTUREFORMAT_RGBA; let types = new Array(); let samplingModes = new Array(); let useSRGBBuffers = new Array(); + let formats = new Array(); const rtWrapper = this._createHardwareRenderTargetWrapper(true, false, size) as WebGPURenderTargetWrapper; @@ -76,6 +78,9 @@ WebGPUEngine.prototype.createMultipleRenderTarget = function (size: TextureSize, if (options.useSRGBBuffers) { useSRGBBuffers = options.useSRGBBuffers; } + if (options.formats) { + formats = options.formats; + } } const width = (<{ width: number; height: number }>size).width || size; @@ -110,6 +115,7 @@ WebGPUEngine.prototype.createMultipleRenderTarget = function (size: TextureSize, let samplingMode = samplingModes[i] || defaultSamplingMode; let type = types[i] || defaultType; const useSRGBBuffer = useSRGBBuffers[i] || defaultUseSRGBBuffer; + const format = formats[i] || defaultFormat; if (type === Constants.TEXTURETYPE_FLOAT && !this._caps.textureFloatLinearFiltering) { // if floating point linear (gl.FLOAT) then force to NEAREST_SAMPLINGMODE @@ -142,6 +148,7 @@ WebGPUEngine.prototype.createMultipleRenderTarget = function (size: TextureSize, texture._cachedWrapU = Constants.TEXTURE_CLAMP_ADDRESSMODE; texture._cachedWrapV = Constants.TEXTURE_CLAMP_ADDRESSMODE; texture._useSRGBBuffer = useSRGBBuffer; + texture.format = format; this._internalTexturesCache.push(texture); diff --git a/packages/dev/core/src/Engines/renderTargetWrapper.ts b/packages/dev/core/src/Engines/renderTargetWrapper.ts index 0095e0273ce..c82daf1719e 100644 --- a/packages/dev/core/src/Engines/renderTargetWrapper.ts +++ b/packages/dev/core/src/Engines/renderTargetWrapper.ts @@ -319,6 +319,7 @@ export class RenderTargetWrapper { const samplingModes: number[] = []; const types: number[] = []; + const formats: number[] = []; const targetTypes: number[] = []; const faceIndex: number[] = []; const layerIndex: number[] = []; @@ -330,6 +331,7 @@ export class RenderTargetWrapper { samplingModes.push(texture.samplingMode); types.push(texture.type); + formats.push(texture.format); const index = internalTexture2Index[texture.uniqueId]; if (index !== undefined) { @@ -370,6 +372,7 @@ export class RenderTargetWrapper { generateStencilBuffer: this._generateStencilBuffer, generateDepthTexture, types, + formats, textureCount, targetTypes, faceIndex, diff --git a/packages/dev/core/src/Materials/Textures/multiRenderTarget.ts b/packages/dev/core/src/Materials/Textures/multiRenderTarget.ts index 81ff8d60037..e4e5f110405 100644 --- a/packages/dev/core/src/Materials/Textures/multiRenderTarget.ts +++ b/packages/dev/core/src/Materials/Textures/multiRenderTarget.ts @@ -39,6 +39,10 @@ export interface IMultiRenderTargetOptions { * Define if a depth texture is required instead of a depth buffer */ generateDepthTexture?: boolean; + /** + * Define the internal format of the buffer in the RTT (RED, RG, RGB, RGBA (default), ALPHA...) of all the draw buffers we want to create + */ + formats?: number[]; /** * Define depth texture format to use */ @@ -178,11 +182,12 @@ export class MultiRenderTarget extends RenderTargetTexture { const types: number[] = []; const samplingModes: number[] = []; const useSRGBBuffers: boolean[] = []; + const formats: number[] = []; const targetTypes: number[] = []; const faceIndex: number[] = []; const layerIndex: number[] = []; const layerCounts: number[] = []; - this._initTypes(count, types, samplingModes, useSRGBBuffers, targetTypes, faceIndex, layerIndex, layerCounts, options); + this._initTypes(count, types, samplingModes, useSRGBBuffers, formats, targetTypes, faceIndex, layerIndex, layerCounts, options); const generateDepthBuffer = !options || options.generateDepthBuffer === undefined ? true : options.generateDepthBuffer; const generateStencilBuffer = !options || options.generateStencilBuffer === undefined ? false : options.generateStencilBuffer; @@ -198,6 +203,7 @@ export class MultiRenderTarget extends RenderTargetTexture { types: types, textureCount: count, useSRGBBuffers: useSRGBBuffers, + formats: formats, targetTypes: targetTypes, faceIndex: faceIndex, layerIndex: layerIndex, @@ -218,6 +224,7 @@ export class MultiRenderTarget extends RenderTargetTexture { types: number[], samplingModes: number[], useSRGBBuffers: boolean[], + formats: number[], targets: number[], faceIndex: number[], layerIndex: number[], @@ -243,6 +250,12 @@ export class MultiRenderTarget extends RenderTargetTexture { useSRGBBuffers.push(false); } + if (options && options.formats && options.formats[i] !== undefined) { + formats.push(options.formats[i]); + } else { + formats.push(Constants.TEXTUREFORMAT_RGBA); + } + if (options && options.targetTypes && options.targetTypes[i] !== undefined) { targets.push(options.targetTypes[i]); } else { @@ -491,6 +504,7 @@ export class MultiRenderTarget extends RenderTargetTexture { const types: number[] = []; const samplingModes: number[] = []; const useSRGBBuffers: boolean[] = []; + const formats: number[] = []; const targetTypes: number[] = []; const faceIndex: number[] = []; const layerIndex: number[] = []; @@ -498,10 +512,11 @@ export class MultiRenderTarget extends RenderTargetTexture { this._textureNames = textureNames; - this._initTypes(count, types, samplingModes, useSRGBBuffers, targetTypes, faceIndex, layerIndex, layerCounts, options); + this._initTypes(count, types, samplingModes, useSRGBBuffers, formats, targetTypes, faceIndex, layerIndex, layerCounts, options); this._multiRenderTargetOptions.types = types; this._multiRenderTargetOptions.samplingModes = samplingModes; this._multiRenderTargetOptions.useSRGBBuffers = useSRGBBuffers; + this._multiRenderTargetOptions.formats = formats; this._multiRenderTargetOptions.targetTypes = targetTypes; this._multiRenderTargetOptions.faceIndex = faceIndex; this._multiRenderTargetOptions.layerIndex = layerIndex;