Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
25 changes: 22 additions & 3 deletions examples/webgpu_postprocessing_ssr.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@
</head>

<body>

<div id="info">
<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> webgpu - postprocessing - screen space reflections<br />
<a href="https://skfb.ly/6tqYD" target="_blank" rel="noopener">Steampunk Camera</a> by
<a href="https://sketchfab.com/lumoize" target="_blank" rel="noopener">dylanheyes</a> is licensed under <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank" rel="noopener">Creative Commons Attribution</a>.<br />
</div>

<script type="importmap">
{
"imports": {
Expand All @@ -28,8 +30,9 @@
</script>

<script type="module">

import * as THREE from 'three';
import { pass, mrt, output, normalView, metalness, blendColor, screenUV, color } from 'three/tsl';
import { pass, mrt, output, normalView, metalness, blendColor, screenUV, color, sample, directionToColor, colorToDirection } from 'three/tsl';
import { ssr } from 'three/addons/tsl/display/SSRNode.js';
import { smaa } from 'three/addons/tsl/display/SMAANode.js';

Expand Down Expand Up @@ -109,7 +112,7 @@
const scenePass = pass( scene, camera, { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter } );
scenePass.setMRT( mrt( {
output: output,
normal: normalView,
normal: directionToColor( normalView ),
metalness: metalness
} ) );

Expand All @@ -118,7 +121,23 @@
const scenePassDepth = scenePass.getTextureNode( 'depth' );
const scenePassMetalness = scenePass.getTextureNode( 'metalness' );

ssrPass = ssr( scenePassColor, scenePassDepth, scenePassNormal, scenePassMetalness, camera );
// optimization bandwidth packing the normals and reducing the texture precision if possible

const metalnessTexture = scenePass.getTexture( 'metalness' );
metalnessTexture.type = THREE.UnsignedByteType;

const normalTexture = scenePass.getTexture( 'normal' );
normalTexture.type = THREE.UnsignedByteType;

const customNormal = sample( ( uv ) => {

return colorToDirection( scenePassNormal.sample( uv ) );

} );

//

ssrPass = ssr( scenePassColor, scenePassDepth, customNormal, scenePassMetalness, camera );
ssrPass.resolutionScale = 1.0;

// blend SSR over beauty
Expand Down
1 change: 1 addition & 0 deletions src/Three.TSL.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ export const round = TSL.round;
export const rtt = TSL.rtt;
export const sRGBTransferEOTF = TSL.sRGBTransferEOTF;
export const sRGBTransferOETF = TSL.sRGBTransferOETF;
export const sample = TSL.sample;
export const sampler = TSL.sampler;
export const samplerComparison = TSL.samplerComparison;
export const saturate = TSL.saturate;
Expand Down
1 change: 1 addition & 0 deletions src/nodes/TSL.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export * from './utils/TriplanarTexturesNode.js';
export * from './utils/ReflectorNode.js';
export * from './utils/RTTNode.js';
export * from './utils/PostProcessingUtils.js';
export * from './utils/SampleNode.js';

// three.js shading language
export * from './tsl/TSLBase.js';
Expand Down
81 changes: 81 additions & 0 deletions src/nodes/utils/SampleNode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import Node from '../core/Node.js';
import { uv } from '../accessors/UV.js';
import { nodeObject } from '../tsl/TSLCore.js';

/**
* Class representing a node that samples a value using a provided callback function.
*
* @extends Node
*/
class SampleNode extends Node {

/**
* Returns the type of the node.
*
* @type {string}
* @readonly
* @static
*/
static get type() {

return 'SampleNode';

}

/**
* Creates an instance of SampleNode.
*
* @param {Function} callback - The function to be called when sampling. Should accept a UV node and return a value.
*/
constructor( callback ) {

super();

this.callback = callback;

/**
* This flag can be used for type testing.
*
* @type {boolean}
* @readonly
* @default true
*/
this.isSampleNode = true;

}

/**
* Sets up the node by sampling with the default UV accessor.
*
* @returns {Node} The result of the callback function when called with the UV node.
*/
setup() {

return this.sample( uv() );

}

/**
* Calls the callback function with the provided UV node.
*
* @param {Node<vec2>} uv - The UV node or value to be passed to the callback.
* @returns {Node} The result of the callback function.
*/
sample( uv ) {

return this.callback( uv );

}

}

export default SampleNode;

/**
* Helper function to create a SampleNode wrapped as a node object.
*
* @function
* @param {Function} callback - The function to be called when sampling. Should accept a UV node and return a value.
* @returns {SampleNode} The created SampleNode instance wrapped as a node object.
*/
export const sample = /*@__PURE__*/ ( callback ) => nodeObject( new SampleNode( callback ) );