Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 38 additions & 17 deletions examples/webgpu_postprocessing_ao.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
<script type="importmap">
{
"imports": {
"three": "../build/three.webgpu.js",
"three/tsl": "../build/three.webgpu.js",
"three": "../src/Three.WebGPU.js",
"three/tsl": "../src/Three.WebGPU.js",
"three/addons/": "./jsm/"
}
}
Expand All @@ -20,7 +20,7 @@
<script type="module">

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

import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { DRACOLoader } from 'three/addons/loaders/DRACOLoader.js';
Expand All @@ -31,7 +31,7 @@
import { GUI } from 'three/addons/libs/lil-gui.module.min.js';

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

let blendIntensity;
let aoPass;

const params = {
Expand Down Expand Up @@ -78,21 +78,42 @@

//

// Opaque Pass

const normalPassMaterial = new THREE.NodeMaterial();
normalPassMaterial.lights = false;
normalPassMaterial.fog = false;
normalPassMaterial.colorNode = transformedNormalView.directionToColor();

const opaquePass = pass( scene, camera, {
minFilter: THREE.NearestFilter,
magFilter: THREE.NearestFilter,
type: THREE.UnsignedByteType
} );

opaquePass.transparent = false;
opaquePass.overrideMaterial = normalPassMaterial;

// Textures

const normalView = opaquePass.getTextureNode().colorToDirection();
const depth = opaquePass.getTextureNode( 'depth' );

//

aoPass = ao( depth, normalView, camera );

blendIntensity = uniform( 1 );

//

postProcessing = new THREE.PostProcessing( renderer );

const scenePass = pass( scene, camera );
scenePass.setMRT( mrt( {
output: output,
normal: transformedNormalView
} ) );

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

aoPass = scenePassColor.ao( scenePassDepth, scenePassNormal, camera );
const aoFinal = blendIntensity.mix( scenePass, aoPass.mul( scenePass ) );

postProcessing.outputNode = aoPass;
postProcessing.outputNode = aoFinal;

//

Expand Down Expand Up @@ -130,11 +151,11 @@

if ( value === true ) {

postProcessing.outputNode = aoPass;
postProcessing.outputNode = aoFinal;

} else {

postProcessing.outputNode = scenePassColor;
postProcessing.outputNode = scenePass;

}

Expand All @@ -146,7 +167,7 @@

function updateParameters() {

aoPass.blendIntensity.value = params.blendIntensity;
blendIntensity.value = params.blendIntensity;
aoPass.distanceExponent.value = params.distanceExponent;
aoPass.distanceFallOff.value = params.distanceFallOff;
aoPass.radius.value = params.radius;
Expand Down
146 changes: 146 additions & 0 deletions examples/webgpu_postprocessing_standard.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgpu - ambient occlusion (GTAO)</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<link type="text/css" rel="stylesheet" href="main.css">
</head>
<body>
<script type="importmap">
{
"imports": {
"three": "../src/Three.WebGPU.js",
"three/tsl": "../src/Three.WebGPU.js",
"three/addons/": "./jsm/"
}
}
</script>

<script type="module">

import * as THREE from 'three';
import { standardPass, viewportSharedTexture } 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 Stats from 'three/addons/libs/stats.module.js';

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

init();

async function init() {

camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 100 );
camera.position.set( 5, 2, 8 );

scene = new THREE.Scene();
scene.background = new THREE.Color( 0xbfe3dd );

clock = new THREE.Clock();

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

scene.environment = texture;

renderer = new THREE.WebGPURenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setAnimationLoop( animate );
document.body.appendChild( renderer.domElement );

controls = new OrbitControls( camera, renderer.domElement );
controls.target.set( 0, 0.5, 0 );
controls.update();
controls.enablePan = false;
controls.enableDamping = true;

stats = new Stats();
document.body.appendChild( stats.dom );

//

const verticalRefractor = viewportSharedTexture();

const planeRefractor = new THREE.Mesh( new THREE.PlaneGeometry( 3, 3 ), new THREE.MeshStandardNodeMaterial( {
backdropNode: verticalRefractor.saturation( 0 )
} ) );
planeRefractor.material.transparent = true;
planeRefractor.position.z = 3;
planeRefractor.position.y = 1;
scene.add( planeRefractor );

//

const emissiveObject = new THREE.Mesh( new THREE.SphereGeometry( .5, 32, 32 ), new THREE.MeshStandardNodeMaterial( {
emissive: new THREE.Color( 0xFFFFFF )
} ) );
emissiveObject.position.z = 1;
emissiveObject.position.y = 1;
scene.add( emissiveObject );

//

const stdPass = standardPass( scene, camera );

postProcessing = new THREE.PostProcessing( renderer );
postProcessing.outputNode = stdPass;

const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( 'jsm/libs/draco/' );
dracoLoader.setDecoderConfig( { type: 'js' } );
const loader = new GLTFLoader();
loader.setDRACOLoader( dracoLoader );
loader.setPath( 'models/gltf/' );

const gltf = await loader.loadAsync( 'LittlestTokyo.glb' );

const model = gltf.scene;
model.position.set( 1, 1, 0 );
model.scale.set( 0.01, 0.01, 0.01 );
scene.add( model );

mixer = new THREE.AnimationMixer( model );
mixer.clipAction( gltf.animations[ 0 ] ).play();

window.addEventListener( 'resize', onWindowResize );

}

function onWindowResize() {

const width = window.innerWidth;
const height = window.innerHeight;

camera.aspect = width / height;
camera.updateProjectionMatrix();

renderer.setSize( width, height );

}

function animate() {

const delta = clock.getDelta();

if ( mixer ) {

mixer.update( delta );

}

controls.update();

postProcessing.render();
stats.update();

}

</script>
</body>
</html>
4 changes: 3 additions & 1 deletion src/nodes/Nodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export { default as UniformNode, uniform } from './core/UniformNode.js';
export { default as VaryingNode, varying } from './core/VaryingNode.js';
export { default as OutputStructNode, outputStruct } from './core/OutputStructNode.js';
export { default as MRTNode, mrt } from './core/MRTNode.js';
export { default as NodeHandler } from './core/NodeHandler.js';
export { default as AfterNode, after, before } from './utils/AfterNode.js';

import * as NodeUtils from './core/NodeUtils.js';
export { NodeUtils };
Expand Down Expand Up @@ -137,8 +139,8 @@ export { default as Lut3DNode, lut3D } from './display/Lut3DNode.js';
export { default as GTAONode, ao } from './display/GTAONode.js';
export { default as FXAANode, fxaa } from './display/FXAANode.js';
export { default as RenderOutputNode, renderOutput } from './display/RenderOutputNode.js';

export { default as PassNode, pass, passTexture, depthPass } from './display/PassNode.js';
export { default as StandardPassNode, standardPass } from './display/StandardPassNode.js';

// code
export { default as ExpressionNode, expression } from './code/ExpressionNode.js';
Expand Down
8 changes: 8 additions & 0 deletions src/nodes/core/NodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,14 @@ class NodeBuilder {

}

handle( name, node ) {

const handler = this.renderer.nodeHandler;

return handler !== null ? handler.handle( name, node, this ) : node;

}

getPropertyName( node/*, shaderStage*/ ) {

return node.name;
Expand Down
33 changes: 33 additions & 0 deletions src/nodes/core/NodeHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
class NodeHandler {

constructor() {

this.handlers = [];

}

onHandle( name, callback ) {

this.handlers[ name ] = callback;

return this;

}

handle( name, node, builder ) {

const callback = this.handlers[ name ];

if ( callback !== undefined ) {

node = callback( node, builder );

}

return node || null;

}

}

export default NodeHandler;
5 changes: 3 additions & 2 deletions src/nodes/display/AfterImageNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import TempNode from '../core/TempNode.js';
import { nodeObject, addNodeElement, tslFn, float, vec4 } from '../shadernode/ShaderNode.js';
import { NodeUpdateType } from '../core/constants.js';
import { uv } from '../accessors/UVNode.js';
import { after } from '../utils/AfterNode.js'

Check notice

Code scanning / CodeQL

Unused variable, import, function or class

Unused import after.
import { texture } from '../accessors/TextureNode.js';
import { passTexture } from './PassNode.js';
import { uniform } from '../core/UniformNode.js';
import { sign, max } from '../math/MathNode.js';
import QuadMesh from '../../renderers/common/QuadMesh.js';

import { Vector2 } from '../../math/Vector2.js';
import { RenderTarget } from '../../core/RenderTarget.js';
import { viewportTopLeft } from './ViewportNode.js';

const _size = new Vector2();

Expand All @@ -31,7 +32,7 @@ class AfterImageNode extends TempNode {
this._oldRT = new RenderTarget();
this._oldRT.texture.name = 'AfterImageNode.old';

this._textureNode = passTexture( this, this._compRT.texture );
this._textureNode = texture( this._compRT.texture, viewportTopLeft ).before( this );

this.updateBeforeType = NodeUpdateType.RENDER;

Expand Down
Loading