Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGPURenderer: Introduce TimestampQueryPool #30359

Merged
merged 13 commits into from
Jan 21, 2025
65 changes: 41 additions & 24 deletions examples/webgpu_compute_birds.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"three": "../build/three.webgpu.js",
"three/webgpu": "../build/three.webgpu.js",
"three/tsl": "../build/three.tsl.js",
"three/addons/": "./jsm/"
"three/addons/": "./jsm/",
"stats-gl": "https://cdn.jsdelivr.net/npm/[email protected]/dist/main.js"
}
}
</script>
Expand All @@ -40,7 +41,7 @@

import { OrbitControls } from 'three/addons/controls/OrbitControls.js';

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

let container, stats;
Expand Down Expand Up @@ -168,7 +169,7 @@

//

renderer = new THREE.WebGPURenderer( { antialias: true } );
renderer = new THREE.WebGPURenderer( { antialias: true, forceWebGL: false } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setAnimationLoop( animate );
Expand Down Expand Up @@ -310,30 +311,29 @@
// Destructure uniforms
const { alignment, separation, cohesion, deltaTime, rayOrigin, rayDirection } = effectController;

const zoneRadius = separation.add( alignment ).add( cohesion );
const separationThresh = separation.div( zoneRadius );
const alignmentThresh = ( separation.add( alignment ) ).div( zoneRadius );
const zoneRadiusSq = zoneRadius.mul( zoneRadius );
const zoneRadius = separation.add( alignment ).add( cohesion ).toConst();
const separationThresh = separation.div( zoneRadius ).toConst();
const alignmentThresh = ( separation.add( alignment ) ).div( zoneRadius ).toConst();
const zoneRadiusSq = zoneRadius.mul( zoneRadius ).toConst();

const position = positionStorage.element( instanceIndex );
const velocity = velocityStorage.element( instanceIndex );

// Add influence of pointer position to velocity.
const directionToRay = rayOrigin.sub( position );
const projectionLength = dot( directionToRay, rayDirection );

const closestPoint = rayOrigin.sub( rayDirection.mul( projectionLength ) );
// Cache current bird's position and velocity outside the loop
const birdIndex = instanceIndex.toConst( 'birdIndex' );
const position = positionStorage.element( birdIndex ).toVar();
const velocity = velocityStorage.element( birdIndex ).toVar();

const directionToClosestPoint = closestPoint.sub( position );
const distanceToClosestPoint = length( directionToClosestPoint );
const distanceToClosestPointSq = distanceToClosestPoint.mul( distanceToClosestPoint );
// Add influence of pointer position to velocity using cached position
const directionToRay = rayOrigin.sub( position ).toConst();
const projectionLength = dot( directionToRay, rayDirection ).toConst();
const closestPoint = rayOrigin.sub( rayDirection.mul( projectionLength ) ).toConst();
const directionToClosestPoint = closestPoint.sub( position ).toConst();
const distanceToClosestPoint = length( directionToClosestPoint ).toConst();
const distanceToClosestPointSq = distanceToClosestPoint.mul( distanceToClosestPoint ).toConst();

const rayRadius = float( 150.0 );
const rayRadiusSq = rayRadius.mul( rayRadius );
const rayRadius = float( 150.0 ).toConst();
const rayRadiusSq = rayRadius.mul( rayRadius ).toConst();

If( distanceToClosestPointSq.lessThan( rayRadiusSq ), () => {

// Scale bird velocity inversely with distance from prey radius center.
const velocityAdjust = ( distanceToClosestPointSq.div( rayRadiusSq ).sub( 1.0 ) ).mul( deltaTime ).mul( 100.0 );
velocity.addAssign( normalize( directionToClosestPoint ).mul( velocityAdjust ) );
limit.addAssign( 5.0 );
Expand All @@ -347,11 +347,18 @@

Loop( { start: uint( 0 ), end: uint( BIRDS ), type: 'uint', condition: '<' }, ( { i } ) => {

If( i.equal( birdIndex ), () => {

Continue();

} );

// Cache bird's position and velocity

const birdPosition = positionStorage.element( i );
const dirToBird = birdPosition.sub( position );
const distToBird = length( dirToBird );

// Don't apply any changes to velocity if the distance to this bird is negligible.
If( distToBird.lessThan( 0.0001 ), () => {

Continue();
Expand Down Expand Up @@ -413,8 +420,10 @@

} );

} )().compute( BIRDS );
// Write back the final velocity to storage
velocityStorage.element( birdIndex ).assign( velocity );

} )().compute( BIRDS );
computePosition = Fn( () => {

const { deltaTime } = effectController;
Expand All @@ -430,7 +439,13 @@

scene.add( birdMesh );

stats = new Stats();
stats = new Stats( {
precision: 3,
horizontal: false,
trackGPU: true,
trackCPT: true
} );
stats.init( renderer );
container.appendChild( stats.dom );

container.style.touchAction = 'none';
Expand Down Expand Up @@ -468,6 +483,7 @@
function animate() {

render();
renderer.resolveTimestampsAsync();
stats.update();

}
Expand All @@ -489,6 +505,7 @@

renderer.compute( computeVelocity );
renderer.compute( computePosition );
renderer.resolveTimestampsAsync( 'compute' );
renderer.render( scene, camera );

// Move pointer away so we only affect birds when moving the mouse
Expand Down
16 changes: 10 additions & 6 deletions examples/webgpu_compute_particles_snow.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
<script type="importmap">
{
"imports": {
"three": "../build/three.webgpu.js",
"three/webgpu": "../build/three.webgpu.js",
"three": "../src/Three.WebGPU.js",
"three/webgpu": "../src/Three.WebGPU.js",
Comment on lines -17 to +18
Copy link
Owner

@mrdoob mrdoob Jan 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"three/tsl": "../build/three.tsl.js",
"three/addons/": "./jsm/",
"stats-gl": "https://cdn.jsdelivr.net/npm/stats-gl@2.2.8/dist/main.js"
"stats-gl": "https://cdn.jsdelivr.net/npm/stats-gl@3.6.0/dist/main.js"
}
}
</script>
Expand Down Expand Up @@ -273,7 +273,9 @@

stats = new Stats( {
precision: 3,
horizontal: false
horizontal: false,
trackGPU: true,
trackCPT: true
} );
stats.init( renderer );
document.body.appendChild( stats.dom );
Expand Down Expand Up @@ -343,11 +345,12 @@

scene.overrideMaterial = collisionPosMaterial;
renderer.setRenderTarget( collisionPosRT );
await renderer.renderAsync( scene, collisionCamera );
renderer.render( scene, collisionCamera );

// compute

await renderer.computeAsync( computeParticles );
renderer.compute( computeParticles );
renderer.resolveTimestampsAsync( 'compute' );
Copy link
Collaborator

@sunag sunag Jan 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to have a static definition for this like TimestampQuery.COMPUTE ?


// result

Expand All @@ -356,6 +359,7 @@

await postProcessing.renderAsync();

renderer.resolveTimestampsAsync();
stats.update();

}
Expand Down
31 changes: 29 additions & 2 deletions examples/webgpu_compute_points.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,24 @@
"three": "../build/three.webgpu.js",
"three/webgpu": "../build/three.webgpu.js",
"three/tsl": "../build/three.tsl.js",
"three/addons/": "./jsm/"
"three/addons/": "./jsm/",
"stats-gl": "https://cdn.jsdelivr.net/npm/[email protected]/dist/main.js"
}
}
</script>

<script type="module">

import * as THREE from 'three';

import Stats from 'stats-gl';


import { Fn, uniform, instancedArray, float, vec2, vec3, color, instanceIndex } from 'three/tsl';

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

let camera, scene, renderer;
let camera, scene, renderer, stats;
let computeNode;

const pointerVector = new THREE.Vector2( - 10.0, - 10.0 ); // Out of bounds first
Expand Down Expand Up @@ -120,6 +125,19 @@
renderer.setAnimationLoop( animate );
document.body.appendChild( renderer.domElement );

stats = new Stats( {
precision: 4,
horizontal: false,
trackGPU: true,
trackCPT: true,
logsPerSecond: 10,
graphsPerSecond: 60,
samplesGraph: 30,
} );
stats.init( renderer );
document.body.appendChild( stats.dom );
stats.dom.style.position = 'absolute';

window.addEventListener( 'resize', onWindowResize );
window.addEventListener( 'mousemove', onMouseMove );

Expand Down Expand Up @@ -158,8 +176,17 @@
function animate() {

renderer.compute( computeNode );
renderer.resolveTimestampsAsync( 'compute' );

renderer.render( scene, camera );


renderer.resolveTimestampsAsync().then( () => {

stats.update();

} );

}

</script>
Expand Down
21 changes: 15 additions & 6 deletions examples/webgpu_performance.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@
"imports": {
"three": "../build/three.webgpu.js",
"three/webgpu": "../build/three.webgpu.js",
"three/addons/": "./jsm/"
"three/addons/": "./jsm/",
"stats-gl": "https://cdn.jsdelivr.net/npm/[email protected]/dist/main.js"

}
}
</script>
Expand All @@ -29,7 +31,7 @@

import * as THREE from 'three';

import Stats from 'three/addons/libs/stats.module.js';
import Stats from 'stats-gl';

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

Expand Down Expand Up @@ -71,7 +73,7 @@
scene = new THREE.Scene();


renderer = new THREE.WebGPURenderer( { antialias: true, forceWebGL: false } );
renderer = new THREE.WebGPURenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.toneMapping = THREE.ACESFilmicToneMapping;
Expand All @@ -82,7 +84,13 @@

//

stats = new Stats();
stats = new Stats( {
precision: 3,
horizontal: false,
trackGPU: true,
} );
stats.init( renderer );

document.body.appendChild( stats.dom );

new RGBELoader()
Expand Down Expand Up @@ -149,9 +157,10 @@

//

function render() {
async function render() {

renderer.renderAsync( scene, camera );
await renderer.renderAsync( scene, camera );
renderer.resolveTimestampsAsync( 'render' );

stats.update();

Expand Down
11 changes: 7 additions & 4 deletions examples/webgpu_performance_renderbundle.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,10 @@
{
"imports": {
"three": "../build/three.webgpu.js",
"three/webgpu": "../build/three.webgpu.js",
"three/webgpu": "../build/three.webgpu.js",
"three/tsl": "../build/three.tsl.js",
"three/addons/": "./jsm/",
"stats-gl": "https://cdn.jsdelivr.net/npm/stats-gl@2.2.7/dist/main.js"
"stats-gl": "https://cdn.jsdelivr.net/npm/stats-gl@3.6.0/dist/main.js"
}
}
</script>
Expand Down Expand Up @@ -229,9 +229,10 @@

stats = new Stats( {
precision: 3,
horizontal: false
horizontal: false,
trackGPU: true,
} );
// stats.init( renderer );
stats.init( renderer );
document.body.appendChild( stats.dom );
stats.dom.style.position = 'absolute';

Expand Down Expand Up @@ -288,6 +289,8 @@
if ( renderTimeAverages.length > 60 ) renderTimeAverages.shift();

const average = renderTimeAverages.reduce( ( a, b ) => a + b, 0 ) / renderTimeAverages.length;

renderer.resolveTimestampsAsync();
stats.update();

document.getElementById( 'backend' ).innerText = `Average Render Time ${api.renderBundle ? '(Bundle)' : ''}: ` + average.toFixed( 2 ) + 'ms';
Expand Down
4 changes: 2 additions & 2 deletions src/nodes/accessors/Arrays.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { getLengthFromType, getTypedArrayFromType } from '../core/NodeUtils.js';
* TSL function for creating a storage buffer node with a configured `StorageBufferAttribute`.
*
* @function
* @param {Number} count - The data count.
* @param {Number|TypedArray} count - The data count.
* @param {String} [type='float'] - The data type.
* @returns {StorageBufferNode}
*/
Expand All @@ -29,7 +29,7 @@ export const attributeArray = ( count, type = 'float' ) => {
* TSL function for creating a storage buffer node with a configured `StorageInstancedBufferAttribute`.
*
* @function
* @param {Number} count - The data count.
* @param {Number|TypedArray} count - The data count.
* @param {String} [type='float'] - The data type.
* @returns {StorageBufferNode}
*/
Expand Down
Loading
Loading