Skip to content

Commit

Permalink
GTAONode: Fix AO with WebGL backend. (mrdoob#29593)
Browse files Browse the repository at this point in the history
* GTAONode: Fix AO with WebGL backend.

* E2E: Update screenshot.

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

* DenoiseNode: Clean up.
  • Loading branch information
Mugen87 authored Oct 8, 2024
1 parent 322aece commit 35f4555
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 29 deletions.
17 changes: 3 additions & 14 deletions examples/jsm/tsl/display/DenoiseNode.js
Original file line number Diff line number Diff line change
@@ -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 {

Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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() );
Expand Down
19 changes: 4 additions & 15 deletions examples/jsm/tsl/display/GTAONode.js
Original file line number Diff line number Diff line change
@@ -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();
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 ), () => {
Expand All @@ -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 ), () => {
Expand Down
Binary file modified examples/screenshots/webgpu_postprocessing_ao.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/nodes/TSL.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
23 changes: 23 additions & 0 deletions src/nodes/utils/PostProcessingUtils.js
Original file line number Diff line number Diff line change
@@ -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 );

} );

0 comments on commit 35f4555

Please sign in to comment.