Skip to content

Commit

Permalink
GTAONode: Bring getTextureNode() back. (#28883)
Browse files Browse the repository at this point in the history
* GTAONode: Bring `getTextureNode()` back.

* E2E: Update screenshot.
  • Loading branch information
Mugen87 authored Jul 16, 2024
1 parent 0679c55 commit 8a102ea
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 48 deletions.
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.
87 changes: 69 additions & 18 deletions examples/webgpu_postprocessing_ao.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,28 @@
<script type="module">

import * as THREE from 'three';
import { pass, mrt, output, transformedNormalView } from 'three/tsl';
import { pass, mrt, output, transformedNormalView, texture, ao } from 'three/tsl';

import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
import { SimplexNoise } from 'three/addons/math/SimplexNoise.js';

import Stats from 'three/addons/libs/stats.module.js';
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';

let camera, scene, renderer, postProcessing, controls, clock, stats, mixer;

let aoPass;
let aoPass, blendPassAO, blendPassDenoise, scenePassColor;

const params = {
blendIntensity: 1,
distanceExponent: 1,
distanceFallOff: 1,
radius: 0.25,
scale: 1,
thickness: 1,
denoised: true,
enabled: true
};

Expand All @@ -57,10 +58,10 @@
clock = new THREE.Clock();

const hdrloader = new RGBELoader();
const texture = await hdrloader.loadAsync( 'textures/equirectangular/quarry_01_1k.hdr' );
texture.mapping = THREE.EquirectangularReflectionMapping;
const envMap = await hdrloader.loadAsync( 'textures/equirectangular/quarry_01_1k.hdr' );
envMap.mapping = THREE.EquirectangularReflectionMapping;

scene.environment = texture;
scene.environment = envMap;

renderer = new THREE.WebGPURenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
Expand All @@ -86,13 +87,22 @@
normal: transformedNormalView
} ) );

const scenePassColor = scenePass.getTextureNode( 'output' );
scenePassColor = scenePass.getTextureNode( 'output' );
const scenePassNormal = scenePass.getTextureNode( 'normal' );
const scenePassDepth = scenePass.getTextureNode( 'depth' );

aoPass = scenePassColor.ao( scenePassDepth, scenePassNormal, camera );
// ao

postProcessing.outputNode = aoPass;
aoPass = ao( scenePassDepth, scenePassNormal, camera );
blendPassAO = aoPass.getTextureNode().mul( scenePassColor );

// denoise (optional)

const noiseTexture = texture( generateNoise() );
const denoisePass = aoPass.getTextureNode().denoise( scenePassDepth, scenePassNormal, noiseTexture, camera );
blendPassDenoise = denoisePass.mul( scenePassColor );

postProcessing.outputNode = blendPassDenoise;

//

Expand All @@ -119,34 +129,43 @@

const gui = new GUI();
gui.title( 'AO settings' );
gui.add( params, 'blendIntensity' ).min( 0 ).max( 1 ).onChange( updateParameters );
gui.add( params, 'distanceExponent' ).min( 1 ).max( 4 ).onChange( updateParameters );
gui.add( params, 'distanceFallOff' ).min( 0.01 ).max( 1 ).onChange( updateParameters );
gui.add( params, 'radius' ).min( 0.01 ).max( 1 ).onChange( updateParameters );
gui.add( params, 'scale' ).min( 0.01 ).max( 2 ).onChange( updateParameters );
gui.add( params, 'thickness' ).min( 0.01 ).max( 2 ).onChange( updateParameters );
gui.add( params, 'denoised' ).onChange( updatePassChain );
gui.add( params, 'enabled' ).onChange( updatePassChain );

}

function updatePassChain() {

if ( params.enabled === true ) {

gui.add( params, 'enabled' ).onChange( ( value ) => {

if ( value === true ) {
if ( params.denoised === true ) {

postProcessing.outputNode = aoPass;
postProcessing.outputNode = blendPassDenoise;

} else {

postProcessing.outputNode = scenePassColor;
postProcessing.outputNode = blendPassAO;

}

postProcessing.needsUpdate = true;
} else {

postProcessing.outputNode = scenePassColor;

}

postProcessing.needsUpdate = true;

} );

}

function updateParameters() {

aoPass.blendIntensity.value = params.blendIntensity;
aoPass.distanceExponent.value = params.distanceExponent;
aoPass.distanceFallOff.value = params.distanceFallOff;
aoPass.radius.value = params.radius;
Expand All @@ -155,6 +174,38 @@

}

function generateNoise( size = 64 ) {

const simplex = new SimplexNoise();

const arraySize = size * size * 4;
const data = new Uint8Array( arraySize );

for ( let i = 0; i < size; i ++ ) {

for ( let j = 0; j < size; j ++ ) {

const x = i;
const y = j;

data[ ( i * size + j ) * 4 ] = ( simplex.noise( x, y ) * 0.5 + 0.5 ) * 255;
data[ ( i * size + j ) * 4 + 1 ] = ( simplex.noise( x + size, y ) * 0.5 + 0.5 ) * 255;
data[ ( i * size + j ) * 4 + 2 ] = ( simplex.noise( x, y + size ) * 0.5 + 0.5 ) * 255;
data[ ( i * size + j ) * 4 + 3 ] = ( simplex.noise( x + size, y + size ) * 0.5 + 0.5 ) * 255;

}

}

const noiseTexture = new THREE.DataTexture( data, size, size );
noiseTexture.wrapS = THREE.RepeatWrapping;
noiseTexture.wrapT = THREE.RepeatWrapping;
noiseTexture.needsUpdate = true;

return noiseTexture;

}

function onWindowResize() {

const width = window.innerWidth;
Expand Down
43 changes: 13 additions & 30 deletions src/nodes/display/GTAONode.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ import { Color } from '../../math/Color.js';

const _quadMesh = new QuadMesh();
const _currentClearColor = new Color();
const _size = new Vector2();

class GTAONode extends TempNode {

constructor( textureNode, depthNode, normalNode, camera ) {
constructor( depthNode, normalNode, camera ) {

super();

this.textureNode = textureNode;
this.depthNode = depthNode;
this.normalNode = normalNode;

Expand All @@ -36,7 +36,6 @@ class GTAONode extends TempNode {
this.distanceExponent = uniform( 1 );
this.distanceFallOff = uniform( 1 );
this.scale = uniform( 1 );
this.blendIntensity = uniform( 1 );
this.noiseNode = texture( generateMagicSquareNoise() );

this.cameraProjectionMatrix = uniform( camera.projectionMatrix );
Expand All @@ -50,7 +49,13 @@ class GTAONode extends TempNode {
this._material = null;
this._textureNode = passTexture( this, this._aoRenderTarget.texture );

this.updateBeforeType = NodeUpdateType.RENDER;
this.updateBeforeType = NodeUpdateType.FRAME;

}

getTextureNode() {

return this._textureNode;

}

Expand All @@ -65,25 +70,16 @@ class GTAONode extends TempNode {

const { renderer } = frame;

const textureNode = this.textureNode;
const map = textureNode.value;
const size = renderer.getSize( _size );

const currentRenderTarget = renderer.getRenderTarget();
const currentMRT = renderer.getMRT();
renderer.getClearColor( _currentClearColor );
const currentClearAlpha = renderer.getClearAlpha();


const currentTexture = textureNode.value;

_quadMesh.material = this._material;

this.setSize( map.image.width, map.image.height );


const textureType = map.type;

this._aoRenderTarget.texture.type = textureType;
this.setSize( size.width, size.height );

// clear

Expand All @@ -100,17 +96,13 @@ class GTAONode extends TempNode {
renderer.setRenderTarget( currentRenderTarget );
renderer.setMRT( currentMRT );
renderer.setClearColor( _currentClearColor, currentClearAlpha );
textureNode.value = currentTexture;

}

setup( builder ) {

const { textureNode } = this;

const uvNode = uv();

const sampleTexture = ( uv ) => textureNode.uv( uv );
const sampleDepth = ( uv ) => this.depthNode.uv( uv ).x;
const sampleNoise = ( uv ) => this.noiseNode.uv( uv );

Expand Down Expand Up @@ -223,22 +215,13 @@ class GTAONode extends TempNode {

} );

const composite = tslFn( () => {

const beauty = sampleTexture( uvNode );
const ao = this._textureNode.uv( uvNode );

return beauty.mul( mix( vec3( 1.0 ), ao, this.blendIntensity ) );

} );

const material = this._material || ( this._material = builder.createNodeMaterial() );
material.fragmentNode = ao().context( builder.getSharedContext() );
material.needsUpdate = true;

//

return composite();
return this._textureNode;

}

Expand Down Expand Up @@ -328,7 +311,7 @@ function generateMagicSquare( size ) {

}

export const ao = ( node, depthNode, normalNode, camera ) => nodeObject( new GTAONode( nodeObject( node ).toTexture(), nodeObject( depthNode ), nodeObject( normalNode ), camera ) );
export const ao = ( depthNode, normalNode, camera ) => nodeObject( new GTAONode( nodeObject( depthNode ), nodeObject( normalNode ), camera ) );

addNodeElement( 'ao', ao );

Expand Down

0 comments on commit 8a102ea

Please sign in to comment.