Browse Source

DepthTexture: Update depth + stencil textures to work with multi sample RTT, make formats consistent (#28460)

* update rendertarget setup logic

* rearrange

* simplification

* More variable sharing

* More simplification

* Support other depth attachment types

* Updates

* fix internal depth buffer target

* reduce code redundancy

* Update example

* Update docs

* Add 248 type support
Garrett Johnson 1 year ago
parent
commit
bb47c32c89

+ 9 - 8
docs/api/en/textures/DepthTexture.html

@@ -33,10 +33,7 @@
 
 			[page:Number height] -- height of the texture.<br />
 
-			[page:Constant type] -- Default is [page:Textures THREE.UnsignedIntType]
-			when using [page:Textures DepthFormat] and [page:Textures THREE.UnsignedInt248Type] 
-			when using [page:Textures DepthStencilFormat].
-			See [page:Textures type constants] for other choices.<br />
+			[page:Constant type] -- Default is [page:Textures THREE.UnsignedIntType]. See [page:DepthTexture DepthTexture.type] for other choices.<br />
 
 			[page:Constant mapping] -- See [page:Textures mapping mode constants] for
 			details.<br />
@@ -87,10 +84,14 @@
 
 		<h3>[page:Texture.type type]</h3>
 		<p>
-			Default is [page:Textures THREE.UnsignedIntType] when using [page:Textures DepthFormat] 
-			and [page:Textures THREE.UnsignedInt248Type] when using
-			[page:Textures DepthStencilFormat]. See [page:Textures format constants]
-			for details.<br />
+			Default is [page:Textures THREE.UnsignedIntType]. The following are options and how they map to internal
+			gl depth format types depending on the stencil format, as well:
+
+			[page:Textures THREE.UnsignedIntType] -- Uses DEPTH_COMPONENT24 or DEPTH24_STENCIL8 internally.<br />
+
+			[page:Textures THREE.FloatType] -- Uses DEPTH_COMPONENT32F or DEPTH32F_STENCIL8 internally.<br />
+
+			[page:Textures THREE.UnsignedShortType] -- Uses DEPTH_COMPONENT16 internally. Stencil buffer is unsupported when using this type.<br />
 		</p>
 
 		<h3>[page:Texture.magFilter magFilter]</h3>

+ 11 - 5
examples/webgl_depth_texture.html

@@ -86,11 +86,12 @@
 
 			const params = {
 				format: THREE.DepthFormat,
-				type: THREE.UnsignedShortType
+				type: THREE.UnsignedShortType,
+				samples: 0,
 			};
 
 			const formats = { DepthFormat: THREE.DepthFormat, DepthStencilFormat: THREE.DepthStencilFormat };
-			const types = { UnsignedShortType: THREE.UnsignedShortType, UnsignedIntType: THREE.UnsignedIntType, UnsignedInt248Type: THREE.UnsignedInt248Type };
+			const types = { UnsignedShortType: THREE.UnsignedShortType, UnsignedIntType: THREE.UnsignedIntType, FloatType: THREE.FloatType };
 
 			init();
 
@@ -130,6 +131,7 @@
 
 				gui.add( params, 'format', formats ).onChange( setupRenderTarget );
 				gui.add( params, 'type', types ).onChange( setupRenderTarget );
+				gui.add( params, 'samples', 0, 16, 1 ).onChange( setupRenderTarget );
 				gui.open();
 
 			}
@@ -138,13 +140,17 @@
 
 				if ( target ) target.dispose();
 
-				const format = parseFloat( params.format );
-				const type = parseFloat( params.type );
+				const format = parseInt( params.format );
+				const type = parseInt( params.type );
+				const samples = parseInt( params.samples );
 
-				target = new THREE.WebGLRenderTarget( window.innerWidth, window.innerHeight );
+				const dpr = renderer.getPixelRatio();
+				target = new THREE.WebGLRenderTarget( window.innerWidth * dpr, window.innerHeight * dpr );
 				target.texture.minFilter = THREE.NearestFilter;
 				target.texture.magFilter = THREE.NearestFilter;
 				target.stencilBuffer = ( format === THREE.DepthStencilFormat ) ? true : false;
+				target.samples = samples;
+
 				target.depthTexture = new THREE.DepthTexture();
 				target.depthTexture.format = format;
 				target.depthTexture.type = type;

+ 58 - 69
src/renderers/webgl/WebGLTextures.js

@@ -1,4 +1,4 @@
-import { LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, RGBAFormat, DepthFormat, DepthStencilFormat, UnsignedIntType, UnsignedInt248Type, FloatType, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, UnsignedByteType, NoColorSpace, LinearSRGBColorSpace, NeverCompare, AlwaysCompare, LessCompare, LessEqualCompare, EqualCompare, GreaterEqualCompare, GreaterCompare, NotEqualCompare, SRGBTransfer, LinearTransfer } from '../../constants.js';
+import { LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, RGBAFormat, DepthFormat, DepthStencilFormat, UnsignedIntType, FloatType, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, UnsignedByteType, NoColorSpace, LinearSRGBColorSpace, NeverCompare, AlwaysCompare, LessCompare, LessEqualCompare, EqualCompare, GreaterEqualCompare, GreaterCompare, NotEqualCompare, SRGBTransfer, LinearTransfer, UnsignedShortType, UnsignedInt248Type } from '../../constants.js';
 import { createElementNS } from '../../utils.js';
 import { ColorManagement } from '../../math/ColorManagement.js';
 import { Vector2 } from '../../math/Vector2.js';
@@ -196,6 +196,48 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 	}
 
+	function getInternalDepthFormat( useStencil, depthType ) {
+
+		let glInternalFormat;
+		if ( useStencil ) {
+
+			if ( depthType === null || depthType === UnsignedIntType || depthType === UnsignedInt248Type ) {
+
+				glInternalFormat = _gl.DEPTH24_STENCIL8;
+
+			} else if ( depthType === FloatType ) {
+
+				glInternalFormat = _gl.DEPTH32F_STENCIL8;
+
+			} else if ( depthType === UnsignedShortType ) {
+
+				glInternalFormat = _gl.DEPTH24_STENCIL8;
+				console.warn( 'DepthTexture: 16 bit depth attachment is not supported with stencil. Using 24-bit attachment.' );
+
+			}
+
+		} else {
+
+			if ( depthType === null || depthType === UnsignedIntType || depthType === UnsignedInt248Type ) {
+
+				glInternalFormat = _gl.DEPTH_COMPONENT24;
+
+			} else if ( depthType === FloatType ) {
+
+				glInternalFormat = _gl.DEPTH_COMPONENT32F;
+
+			} else if ( depthType === UnsignedShortType ) {
+
+				glInternalFormat = _gl.DEPTH_COMPONENT16;
+
+			}
+
+		}
+
+		return glInternalFormat;
+
+	}
+
 	function getMipLevels( texture, image ) {
 
 		if ( textureNeedsGenerateMipmaps( texture ) === true || ( texture.isFramebufferTexture && texture.minFilter !== NearestFilter && texture.minFilter !== LinearFilter ) ) {
@@ -710,23 +752,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 			if ( texture.isDepthTexture ) {
 
-				// populate depth texture with dummy data
-
-				glInternalFormat = _gl.DEPTH_COMPONENT16;
-
-				if ( texture.type === FloatType ) {
-
-					glInternalFormat = _gl.DEPTH_COMPONENT32F;
-
-				} else if ( texture.type === UnsignedIntType ) {
-
-					glInternalFormat = _gl.DEPTH_COMPONENT24;
-
-				} else if ( texture.type === UnsignedInt248Type ) {
-
-					glInternalFormat = _gl.DEPTH24_STENCIL8;
-
-				}
+				glInternalFormat = getInternalDepthFormat( texture.format === DepthStencilFormat, texture.type );
 
 				//
 
@@ -1433,74 +1459,37 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 	}
 
-
 	// Setup storage for internal depth/stencil buffers and bind to correct framebuffer
 	function setupRenderBufferStorage( renderbuffer, renderTarget, isMultisample ) {
 
 		_gl.bindRenderbuffer( _gl.RENDERBUFFER, renderbuffer );
 
-		if ( renderTarget.depthBuffer && ! renderTarget.stencilBuffer ) {
-
-			let glInternalFormat = _gl.DEPTH_COMPONENT24;
-
-			if ( isMultisample || useMultisampledRTT( renderTarget ) ) {
-
-				const depthTexture = renderTarget.depthTexture;
-
-				if ( depthTexture && depthTexture.isDepthTexture ) {
-
-					if ( depthTexture.type === FloatType ) {
-
-						glInternalFormat = _gl.DEPTH_COMPONENT32F;
-
-					} else if ( depthTexture.type === UnsignedIntType ) {
-
-						glInternalFormat = _gl.DEPTH_COMPONENT24;
-
-					}
-
-				}
-
-				const samples = getRenderTargetSamples( renderTarget );
-
-				if ( useMultisampledRTT( renderTarget ) ) {
-
-					multisampledRTTExt.renderbufferStorageMultisampleEXT( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height );
-
-				} else {
-
-					_gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height );
-
-				}
-
-			} else {
-
-				_gl.renderbufferStorage( _gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height );
-
-			}
-
-			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
+		if ( renderTarget.depthBuffer ) {
 
-		} else if ( renderTarget.depthBuffer && renderTarget.stencilBuffer ) {
+			// retrieve the depth attachment types
+			const depthTexture = renderTarget.depthTexture;
+			const depthType = depthTexture && depthTexture.isDepthTexture ? depthTexture.type : null;
+			const glInternalFormat = getInternalDepthFormat( renderTarget.stencilBuffer, depthType );
+			const glAttachmentType = renderTarget.stencilBuffer ? _gl.DEPTH_STENCIL_ATTACHMENT : _gl.DEPTH_ATTACHMENT;
 
+			// set up the attachment
 			const samples = getRenderTargetSamples( renderTarget );
+			const isUseMultisampledRTT = useMultisampledRTT( renderTarget );
+			if ( isUseMultisampledRTT ) {
 
-			if ( isMultisample && useMultisampledRTT( renderTarget ) === false ) {
-
-				_gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height );
+				multisampledRTTExt.renderbufferStorageMultisampleEXT( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height );
 
-			} else if ( useMultisampledRTT( renderTarget ) ) {
+			} else if ( isMultisample ) {
 
-				multisampledRTTExt.renderbufferStorageMultisampleEXT( _gl.RENDERBUFFER, samples, _gl.DEPTH24_STENCIL8, renderTarget.width, renderTarget.height );
+				_gl.renderbufferStorageMultisample( _gl.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height );
 
 			} else {
 
-				_gl.renderbufferStorage( _gl.RENDERBUFFER, _gl.DEPTH_STENCIL, renderTarget.width, renderTarget.height );
+				_gl.renderbufferStorage( _gl.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height );
 
 			}
 
-
-			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, _gl.DEPTH_STENCIL_ATTACHMENT, _gl.RENDERBUFFER, renderbuffer );
+			_gl.framebufferRenderbuffer( _gl.FRAMEBUFFER, glAttachmentType, _gl.RENDERBUFFER, renderbuffer );
 
 		} else {