Skip to content

Commit 2353764

Browse files
authored
XRManager: Add support for WEBGL_multisampled_render_to_texture. (#30418)
1 parent 089e36d commit 2353764

File tree

2 files changed

+73
-10
lines changed

2 files changed

+73
-10
lines changed

src/renderers/webgl-fallback/WebGLBackend.js

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,14 @@ class WebGLBackend extends Backend {
353353

354354
renderTarget.autoAllocateDepthBuffer = false;
355355

356+
// The multisample_render_to_texture extension doesn't work properly if there
357+
// are midframe flushes and an external depth texture.
358+
if ( this.extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true ) {
359+
360+
console.warn( 'THREE.WebGLBackend: Render-to-texture extension was disabled because an external texture was provided' );
361+
362+
}
363+
356364
}
357365

358366
}
@@ -530,7 +538,7 @@ class WebGLBackend extends Backend {
530538

531539
const { samples } = renderContext.renderTarget;
532540

533-
if ( samples > 0 ) {
541+
if ( samples > 0 && this._useMultisampledRTT( renderContext.renderTarget ) === false ) {
534542

535543
const fb = renderTargetContextData.framebuffers[ renderContext.getCacheKey() ];
536544

@@ -1889,6 +1897,8 @@ class WebGLBackend extends Backend {
18891897

18901898
let msaaFb = renderTargetContextData.msaaFrameBuffer;
18911899
let depthRenderbuffer = renderTargetContextData.depthRenderbuffer;
1900+
const multisampledRTTExt = this.extensions.get( 'WEBGL_multisampled_render_to_texture' );
1901+
const useMultisampledRTT = this._useMultisampledRTT( renderTarget );
18921902

18931903
const cacheKey = getCacheKey( descriptor );
18941904

@@ -1951,11 +1961,17 @@ class WebGLBackend extends Backend {
19511961

19521962
} else {
19531963

1954-
gl.framebufferTexture2D( gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0 );
1964+
if ( useMultisampledRTT ) {
19551965

1956-
}
1966+
multisampledRTTExt.framebufferTexture2DMultisampleEXT( gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0, samples );
19571967

1968+
} else {
19581969

1970+
gl.framebufferTexture2D( gl.FRAMEBUFFER, attachment, gl.TEXTURE_2D, textureData.textureGPU, 0 );
1971+
1972+
}
1973+
1974+
}
19591975

19601976
}
19611977

@@ -1966,7 +1982,7 @@ class WebGLBackend extends Backend {
19661982
if ( renderTarget.isXRRenderTarget && renderTarget.autoAllocateDepthBuffer === true ) {
19671983

19681984
const renderbuffer = gl.createRenderbuffer();
1969-
this.textureUtils.setupRenderBufferStorage( renderbuffer, descriptor, 0 );
1985+
this.textureUtils.setupRenderBufferStorage( renderbuffer, descriptor, 0, useMultisampledRTT );
19701986
renderTargetContextData.xrDepthRenderbuffer = renderbuffer;
19711987

19721988
} else {
@@ -1978,7 +1994,15 @@ class WebGLBackend extends Backend {
19781994
textureData.renderTarget = descriptor.renderTarget;
19791995
textureData.cacheKey = cacheKey; // required for copyTextureToTexture()
19801996

1981-
gl.framebufferTexture2D( gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0 );
1997+
if ( useMultisampledRTT ) {
1998+
1999+
multisampledRTTExt.framebufferTexture2DMultisampleEXT( gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0, samples );
2000+
2001+
} else {
2002+
2003+
gl.framebufferTexture2D( gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0 );
2004+
2005+
}
19822006

19832007
}
19842008

@@ -1995,7 +2019,16 @@ class WebGLBackend extends Backend {
19952019
// rebind color
19962020

19972021
const textureData = this.get( descriptor.textures[ 0 ] );
1998-
gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureData.textureGPU, 0 );
2022+
2023+
if ( useMultisampledRTT ) {
2024+
2025+
multisampledRTTExt.framebufferTexture2DMultisampleEXT( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureData.textureGPU, 0, samples );
2026+
2027+
} else {
2028+
2029+
gl.framebufferTexture2D( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureData.textureGPU, 0 );
2030+
2031+
}
19992032

20002033
// rebind depth
20012034

@@ -2010,15 +2043,24 @@ class WebGLBackend extends Backend {
20102043
} else {
20112044

20122045
const textureData = this.get( descriptor.depthTexture );
2013-
gl.framebufferTexture2D( gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0 );
2046+
2047+
if ( useMultisampledRTT ) {
2048+
2049+
multisampledRTTExt.framebufferTexture2DMultisampleEXT( gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0, samples );
2050+
2051+
} else {
2052+
2053+
gl.framebufferTexture2D( gl.FRAMEBUFFER, depthStyle, gl.TEXTURE_2D, textureData.textureGPU, 0 );
2054+
2055+
}
20142056

20152057
}
20162058

20172059
}
20182060

20192061
}
20202062

2021-
if ( samples > 0 ) {
2063+
if ( samples > 0 && useMultisampledRTT === false ) {
20222064

20232065
if ( msaaFb === undefined ) {
20242066

@@ -2323,6 +2365,20 @@ class WebGLBackend extends Backend {
23232365

23242366
}
23252367

2368+
/**
2369+
* Returns `true` if the `WEBGL_multisampled_render_to_texture` extension
2370+
* should be used when MSAA is enabled.
2371+
*
2372+
* @private
2373+
* @param {RenderTarget} renderTarget - The render target that should be multisampled.
2374+
* @return {Boolean} Whether to use the `WEBGL_multisampled_render_to_texture` extension for MSAA or not.
2375+
*/
2376+
_useMultisampledRTT( renderTarget ) {
2377+
2378+
return renderTarget.samples > 0 && this.extensions.has( 'WEBGL_multisampled_render_to_texture' ) === true && renderTarget.autoAllocateDepthBuffer !== false;
2379+
2380+
}
2381+
23262382
/**
23272383
* Frees internal resources.
23282384
*/

src/renderers/webgl-fallback/utils/WebGLTextureUtils.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -918,8 +918,9 @@ class WebGLTextureUtils {
918918
* @param {WebGLRenderbuffer} renderbuffer - The render buffer.
919919
* @param {RenderContext} renderContext - The render context.
920920
* @param {Number} samples - The MSAA sample count.
921+
* @param {Boolean} [useMultisampledRTT=false] - Whether to use WEBGL_multisampled_render_to_texture or not.
921922
*/
922-
setupRenderBufferStorage( renderbuffer, renderContext, samples ) {
923+
setupRenderBufferStorage( renderbuffer, renderContext, samples, useMultisampledRTT = false ) {
923924

924925
const { gl } = this;
925926
const renderTarget = renderContext.renderTarget;
@@ -932,7 +933,13 @@ class WebGLTextureUtils {
932933

933934
let glInternalFormat = gl.DEPTH_COMPONENT24;
934935

935-
if ( samples > 0 ) {
936+
if ( useMultisampledRTT === true ) {
937+
938+
const multisampledRTTExt = this.extensions.get( 'WEBGL_multisampled_render_to_texture' );
939+
940+
multisampledRTTExt.renderbufferStorageMultisampleEXT( gl.RENDERBUFFER, renderTarget.samples, glInternalFormat, width, height );
941+
942+
} else if ( samples > 0 ) {
936943

937944
if ( depthTexture && depthTexture.isDepthTexture ) {
938945

0 commit comments

Comments
 (0)