Selaa lähdekoodia

GTAONode: Fix AO with WebGL backend. (#29593)

* GTAONode: Fix AO with WebGL backend.

* E2E: Update screenshot.

* DenoiseNode: Use `getViewPosition()` from core.

* DenoiseNode: Clean up.
Michael Herzog 1 vuosi sitten
vanhempi
sitoutus
35f4555fcc

+ 3 - 14
examples/jsm/tsl/display/DenoiseNode.js

@@ -1,5 +1,5 @@
 import { Vector2, Vector3 } from 'three';
-import { convertToTexture, TempNode, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, luminance, vec2, vec3, vec4, uniformArray, int, dot, max, pow, abs, If, textureSize, sin, cos, mat2, PI } from 'three/tsl';
+import { getViewPosition, convertToTexture, TempNode, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, luminance, vec2, vec3, vec4, uniformArray, int, dot, max, pow, abs, If, textureSize, sin, cos, mat2, PI } from 'three/tsl';
 
 class DenoiseNode extends TempNode {
 
@@ -49,24 +49,13 @@ class DenoiseNode extends TempNode {
 		const sampleNormal = ( uv ) => this.normalNode.uv( uv );
 		const sampleNoise = ( uv ) => this.noiseNode.uv( uv );
 
-		const getViewPosition = Fn( ( [ screenPosition, depth ] ) => {
-
-			screenPosition = vec2( screenPosition.x, screenPosition.y.oneMinus() ).mul( 2.0 ).sub( 1.0 );
-
-			const clipSpacePosition = vec4( vec3( screenPosition, depth ), 1.0 );
-			const viewSpacePosition = vec4( this.cameraProjectionMatrixInverse.mul( clipSpacePosition ) );
-
-			return viewSpacePosition.xyz.div( viewSpacePosition.w );
-
-		} );
-
 		const denoiseSample = Fn( ( [ center, viewNormal, viewPosition, sampleUv ] ) => {
 
 			const texel = sampleTexture( sampleUv );
 			const depth = sampleDepth( sampleUv );
 			const normal = sampleNormal( sampleUv ).rgb.normalize();
 			const neighborColor = texel.rgb;
-			const viewPos = getViewPosition( sampleUv, depth );
+			const viewPos = getViewPosition( sampleUv, depth, this.cameraProjectionMatrixInverse );
 
 			const normalDiff = dot( viewNormal, normal ).toVar();
 			const normalSimilarity = pow( max( normalDiff, 0 ), this.normalPhi ).toVar();
@@ -95,7 +84,7 @@ class DenoiseNode extends TempNode {
 
 			const center = vec3( texel.rgb );
 
-			const viewPosition = getViewPosition( uvNode, depth );
+			const viewPosition = getViewPosition( uvNode, depth, this.cameraProjectionMatrixInverse );
 
 			const noiseResolution = textureSize( this.noiseNode, 0 );
 			let noiseUv = vec2( uvNode.x, uvNode.y.oneMinus() );

+ 4 - 15
examples/jsm/tsl/display/GTAONode.js

@@ -1,5 +1,5 @@
 import { Color, DataTexture, RenderTarget, RepeatWrapping, Vector2, Vector3 } from 'three';
-import { QuadMesh, TempNode, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, vec2, vec3, vec4, int, dot, max, pow, abs, If, textureSize, sin, cos, PI, texture, passTexture, mat3, add, normalize, mul, cross, div, mix, sqrt, sub, acos, clamp, NodeMaterial } from 'three/tsl';
+import { getViewPosition, QuadMesh, TempNode, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, vec2, vec3, vec4, int, dot, max, pow, abs, If, textureSize, sin, cos, PI, texture, passTexture, mat3, add, normalize, mul, cross, div, mix, sqrt, sub, acos, clamp, NodeMaterial } from 'three/tsl';
 
 const _quadMesh = /*@__PURE__*/ new QuadMesh();
 const _currentClearColor = /*@__PURE__*/ new Color();
@@ -106,24 +106,13 @@ class GTAONode extends TempNode {
 
 		} );
 
-		const getViewPosition = Fn( ( [ screenPosition, depth ] ) => {
-
-			screenPosition = vec2( screenPosition.x, screenPosition.y.oneMinus() ).mul( 2.0 ).sub( 1.0 );
-
-			const clipSpacePosition = vec4( vec3( screenPosition, depth ), 1.0 );
-			const viewSpacePosition = vec4( this.cameraProjectionMatrixInverse.mul( clipSpacePosition ) );
-
-			return viewSpacePosition.xyz.div( viewSpacePosition.w );
-
-		} );
-
 		const ao = Fn( () => {
 
 			const depth = sampleDepth( uvNode );
 
 			depth.greaterThanEqual( 1.0 ).discard();
 
-			const viewPosition = getViewPosition( uvNode, depth );
+			const viewPosition = getViewPosition( uvNode, depth, this.cameraProjectionMatrixInverse );
 			const viewNormal = this.normalNode.rgb.normalize();
 
 			const radiusToUse = this.radius;
@@ -163,7 +152,7 @@ class GTAONode extends TempNode {
 					// x
 
 					const sampleSceneUvDepthX = getSceneUvAndDepth( viewPosition.add( sampleViewOffset ) );
-					const sampleSceneViewPositionX = getViewPosition( sampleSceneUvDepthX.xy, sampleSceneUvDepthX.z );
+					const sampleSceneViewPositionX = getViewPosition( sampleSceneUvDepthX.xy, sampleSceneUvDepthX.z, this.cameraProjectionMatrixInverse );
 					const viewDeltaX = sampleSceneViewPositionX.sub( viewPosition );
 
 					If( abs( viewDeltaX.z ).lessThan( this.thickness ), () => {
@@ -176,7 +165,7 @@ class GTAONode extends TempNode {
 					// y
 
 					const sampleSceneUvDepthY = getSceneUvAndDepth( viewPosition.sub( sampleViewOffset ) );
-					const sampleSceneViewPositionY = getViewPosition( sampleSceneUvDepthY.xy, sampleSceneUvDepthY.z );
+					const sampleSceneViewPositionY = getViewPosition( sampleSceneUvDepthY.xy, sampleSceneUvDepthY.z, this.cameraProjectionMatrixInverse );
 					const viewDeltaY = sampleSceneViewPositionY.sub( viewPosition );
 
 					If( abs( viewDeltaY.z ).lessThan( this.thickness ), () => {

BIN
examples/screenshots/webgpu_postprocessing_ao.jpg


+ 1 - 0
src/nodes/TSL.js

@@ -40,6 +40,7 @@ export * from './utils/Timer.js';
 export * from './utils/TriplanarTexturesNode.js';
 export * from './utils/ReflectorNode.js';
 export * from './utils/RTTNode.js';
+export * from './utils/PostProcessingUtils.js';
 
 // three.js shading language
 export * from './tsl/TSLBase.js';

+ 23 - 0
src/nodes/utils/PostProcessingUtils.js

@@ -0,0 +1,23 @@
+import { Fn, vec2, vec3, vec4 } from '../tsl/TSLBase.js';
+import { WebGPUCoordinateSystem } from '../../constants.js';
+
+export const getViewPosition = /*@__PURE__*/ Fn( ( [ screenPosition, depth, projectionMatrixInverse ], builder ) => {
+
+	let clipSpacePosition;
+
+	if ( builder.renderer.coordinateSystem === WebGPUCoordinateSystem ) {
+
+		screenPosition = vec2( screenPosition.x, screenPosition.y.oneMinus() ).mul( 2.0 ).sub( 1.0 );
+		clipSpacePosition = vec4( vec3( screenPosition, depth ), 1.0 );
+
+	} else {
+
+		clipSpacePosition = vec4( vec3( screenPosition.x, screenPosition.y.oneMinus(), depth ).mul( 2.0 ).sub( 1.0 ), 1.0 );
+
+	}
+
+	const viewSpacePosition = vec4( projectionMatrixInverse.mul( clipSpacePosition ) );
+
+	return viewSpacePosition.xyz.div( viewSpacePosition.w );
+
+} );

粤ICP备19079148号