Explorar el Código

SSGINode: Reduce bandwith with RG11B10. (#33822)

Michael Herzog hace 3 semanas
padre
commit
0f1496ccda

+ 62 - 16
examples/jsm/tsl/display/SSGINode.js

@@ -1,5 +1,5 @@
-import { HalfFloatType, RenderTarget, Vector2, TempNode, QuadMesh, NodeMaterial, RendererUtils, MathUtils } from 'three/webgpu';
-import { clamp, normalize, reference, Fn, NodeUpdateType, uniform, vec4, passTexture, uv, logarithmicDepthToViewZ, viewZToPerspectiveDepth, getViewPosition, screenCoordinate, float, sub, fract, dot, vec2, rand, vec3, Loop, mul, PI, cos, sin, uint, cross, acos, sign, pow, luminance, If, max, abs, Break, sqrt, HALF_PI, div, ceil, shiftRight, convertToTexture, bool, getNormalFromDepth, countOneBits, interleavedGradientNoise } from 'three/tsl';
+import { RenderTarget, Vector2, TempNode, QuadMesh, NodeMaterial, RendererUtils, MathUtils, RGBFormat, RedFormat, UnsignedInt101111Type, UnsignedByteType } from 'three/webgpu';
+import { clamp, normalize, reference, Fn, NodeUpdateType, uniform, vec4, passTexture, uv, logarithmicDepthToViewZ, viewZToPerspectiveDepth, getViewPosition, screenCoordinate, float, sub, fract, dot, vec2, rand, vec3, Loop, mul, PI, cos, sin, uint, cross, acos, sign, pow, luminance, If, max, abs, Break, sqrt, HALF_PI, div, ceil, shiftRight, convertToTexture, bool, getNormalFromDepth, countOneBits, interleavedGradientNoise, property, outputStruct } from 'three/tsl';
 
 const _quadMesh = /*@__PURE__*/ new QuadMesh();
 const _size = /*@__PURE__*/ new Vector2();
@@ -267,13 +267,23 @@ class SSGINode extends TempNode {
 		this._camera = camera;
 
 		/**
-		 * The render target the GI is rendered into.
+		 * The render target the effect is rendered into. The first texture holds the GI,
+		 * the second one the AO.
 		 *
 		 * @private
 		 * @type {RenderTarget}
 		 */
-		this._ssgiRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, type: HalfFloatType } );
-		this._ssgiRenderTarget.texture.name = 'SSGI';
+		this._ssgiRenderTarget = new RenderTarget( 1, 1, { depthBuffer: false, count: 2 } );
+
+		const aoTexture = this._ssgiRenderTarget.textures[ 0 ];
+		aoTexture.name = 'SSGI.AO';
+		aoTexture.type = UnsignedByteType;
+		aoTexture.format = RedFormat;
+
+		const giTexture = this._ssgiRenderTarget.textures[ 1 ];
+		giTexture.name = 'SSGI.GI';
+		giTexture.type = UnsignedInt101111Type;
+		giTexture.format = RGBFormat;
 
 		/**
 		 * The material that is used to render the effect.
@@ -285,23 +295,42 @@ class SSGINode extends TempNode {
 		this._material.name = 'SSGI';
 
 		/**
-		 * The result of the effect is represented as a separate texture node.
+		 * The AO result of the effect is represented as a separate texture node.
+		 *
+		 * @private
+		 * @type {PassTextureNode}
+		 */
+		this._aoNode = passTexture( this, this._ssgiRenderTarget.textures[ 0 ] );
+
+		/**
+		 * The GI result of the effect is represented as a separate texture node.
 		 *
 		 * @private
 		 * @type {PassTextureNode}
 		 */
-		this._textureNode = passTexture( this, this._ssgiRenderTarget.texture );
+		this._giNode = passTexture( this, this._ssgiRenderTarget.textures[ 1 ] );
 
 	}
 
 	/**
-	 * Returns the result of the effect as a texture node.
+	 * Returns the AO result of the effect as a texture node.
 	 *
-	 * @return {PassTextureNode} A texture node that represents the result of the effect.
+	 * @return {PassTextureNode} A texture node that represents the AO result of the effect.
 	 */
-	getTextureNode() {
+	getAONode() {
 
-		return this._textureNode;
+		return this._aoNode;
+
+	}
+
+	/**
+	 * Returns the GI result of the effect as a texture node.
+	 *
+	 * @return {PassTextureNode} A texture node that represents the GI result of the effect.
+	 */
+	getGINode() {
+
+		return this._giNode;
 
 	}
 
@@ -357,9 +386,9 @@ class SSGINode extends TempNode {
 		_quadMesh.material = this._material;
 		_quadMesh.name = 'SSGI';
 
-		// clear
+		// clear (white for the AO attachement)
 
-		renderer.setClearColor( 0x000000, 1 );
+		renderer.setClearColor( 0xffffff, 1 );
 
 		// gi
 
@@ -380,6 +409,14 @@ class SSGINode extends TempNode {
 	 */
 	setup( builder ) {
 
+		const renderer = builder.renderer;
+
+		if ( renderer.backend.isWebGPUBackend === true && renderer.hasFeature( 'rg11b10ufloat-renderable' ) === false ) {
+
+			console.error( 'THREE.SSGINode: The device does not support the "rg11b10ufloat-renderable" feature which is required for SSGI.' );
+
+		}
+
 		const uvNode = uv();
 		const MAX_RAY = uint( 32 );
 		const globalOccludedBitfield = uint( 0 );
@@ -519,6 +556,11 @@ class SSGINode extends TempNode {
 
 		} );
 
+		const aoField = property( 'float' );
+		const giField = property( 'vec3' );
+
+		const outputNode = outputStruct( aoField, giField );
+
 		const gi = Fn( () => {
 
 			const depth = sampleDepth( uvNode ).toVar();
@@ -599,16 +641,20 @@ class SSGINode extends TempNode {
 			const scale = currentLuminance.greaterThan( maxLuminance ).select( maxLuminance.div( currentLuminance ), float( 1 ) );
 			color.mulAssign( scale );
 
-			return vec4( color, ao );
+			aoField.assign( ao );
+			giField.assign( color );
+
+			return vec4( 0 );
 
 		} );
 
-		this._material.fragmentNode = gi().context( builder.getSharedContext() );
+		this._material.colorNode = gi().context( builder.getSharedContext() );
+		this._material.outputNode = outputNode;
 		this._material.needsUpdate = true;
 
 		//
 
-		return this._textureNode;
+		return this._aoNode;
 
 	}
 

+ 3 - 3
examples/webgpu_postprocessing_ssgi.html

@@ -118,10 +118,10 @@
 
 				// composite
 
-				const gi = giPass.rgb.toInspector( 'SSGI' );
-				const ao = giPass.a.toInspector( 'AO' );
+				const ao = giPass.getAONode().toInspector( 'SSGI.AO' );
+				const gi = giPass.getGINode().toInspector( 'SSGI.GI' );
 
-				const compositePass = vec4( add( scenePassColor.rgb.mul( ao ), ( scenePassDiffuse.rgb.mul( gi ) ) ), scenePassColor.a );
+				const compositePass = vec4( add( scenePassColor.rgb.mul( ao.r ), ( scenePassDiffuse.rgb.mul( gi.rgb ) ) ), scenePassColor.a );
 				compositePass.name = 'Composite';
 
 				// traa

+ 3 - 3
examples/webgpu_postprocessing_ssgi_ballpool.html

@@ -137,11 +137,11 @@
 
 				// composite
 
-				const gi = giPass.rgb.toInspector( 'SSGI' );
-				const ao = giPass.a.toInspector( 'AO' );
+				const ao = giPass.getAONode().toInspector( 'SSGI.AO' );
+				const gi = giPass.getGINode().toInspector( 'SSGI.GI' );
 
 				const compositePass = vec4(
-					add( scenePassColor.rgb.mul( ao ), scenePassDiffuse.rgb.mul( gi ) ),
+					add( scenePassColor.rgb.mul( ao.r ), scenePassDiffuse.rgb.mul( gi.rgb ) ),
 					scenePassColor.a
 				);
 

粤ICP备19079148号