diff --git a/examples/jsm/tsl/display/DenoiseNode.js b/examples/jsm/tsl/display/DenoiseNode.js index ef17ef2d5bb08d..86c67f71dba80f 100644 --- a/examples/jsm/tsl/display/DenoiseNode.js +++ b/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() ); diff --git a/examples/jsm/tsl/display/GTAONode.js b/examples/jsm/tsl/display/GTAONode.js index 1ff641ec10e22d..e6ea2ee31cdd59 100644 --- a/examples/jsm/tsl/display/GTAONode.js +++ b/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 ), () => { diff --git a/examples/screenshots/webgpu_postprocessing_ao.jpg b/examples/screenshots/webgpu_postprocessing_ao.jpg index 623e8fc1c82f81..6810b6bdfb9ed1 100644 Binary files a/examples/screenshots/webgpu_postprocessing_ao.jpg and b/examples/screenshots/webgpu_postprocessing_ao.jpg differ diff --git a/src/nodes/TSL.js b/src/nodes/TSL.js index 7e4c4c4e46a6a5..9331f5de909fbd 100644 --- a/src/nodes/TSL.js +++ b/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'; diff --git a/src/nodes/utils/PostProcessingUtils.js b/src/nodes/utils/PostProcessingUtils.js new file mode 100644 index 00000000000000..1a6e69e49753e7 --- /dev/null +++ b/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 ); + +} );