Browse Source

Port webgpu_compute example to "native" Nodes (#23931)

* Port webgpu_compute example to native Nodes

* Fix
Levi Pesin 3 years ago
parent
commit
9e85d0bbd2
1 changed files with 22 additions and 81 deletions
  1. 22 81
      examples/webgpu_compute.html

+ 22 - 81
examples/webgpu_compute.html

@@ -29,10 +29,10 @@
 			import * as Nodes from 'three-nodes/Nodes.js';
 
 			import {
-				compute,
-				color, add, uniform, element, storage, func,
-				assign, float, mul,
-				positionLocal, instanceIndex
+				ShaderNode, compute,
+				uniform, element, storage, temp,
+				assign, add, sub, cond, abs, negate, max, min, length, vec3, color,
+				greaterThanEqual, lessThanEqual, positionLocal, instanceIndex
 			} from 'three-nodes/Nodes.js';
 
 			import { GUI } from './jsm/libs/lil-gui.module.min.js';
@@ -43,7 +43,7 @@
 			let camera, scene, renderer;
 			let computeNode;
 
-			const pointer = new THREE.Vector2( - 10.0, - 10.0 ); // Out of bounds first
+			const pointerVector = new THREE.Vector2( - 10.0, - 10.0 ); // Out of bounds first
 			const scaleVector = new THREE.Vector2( 1, 1 );
 
 			init().then( animate ).catch( error );
@@ -89,95 +89,36 @@
 				const particleBufferNode = storage( particleBuffer, 'vec3' );
 				const velocityBufferNode = storage( velocityBuffer, 'vec3' );
 
-				// create wgsl function
+				// create function
 
-				const WGSLFnNode = func( `( pointer:vec2<f32>, limit:vec2<f32> ) {
+				const FnNode = new ShaderNode( ( inputs, builder ) => {
 
-						var position = particle + velocity;
+					const particle = element( particleBufferNode, instanceIndex );
+					const velocity = element( velocityBufferNode, instanceIndex );
 
-						if ( abs( position.x ) >= limit.x ) {
+					const pointer = uniform( pointerVector );
+					const limit = uniform( scaleVector );
 
-							if ( position.x > 0.0 ) {
+					const position = temp( vec3() );
+					assign( position, add( particle, velocity ) ).build( builder ); // workaround
 
-								position.x = limit.x;
+					assign( velocity.x, cond( greaterThanEqual( abs( position.x ), limit.x ), negate( velocity.x ), velocity.x ) ).build( builder );
+					assign( velocity.y, cond( greaterThanEqual( abs( position.y ), limit.y ), negate( velocity.y ), velocity.y ) ).build( builder );
 
-							} else {
+					assign( position, max( negate( limit ), min( limit, position ) ) ).build( builder );
 
-								position.x = -limit.x;
+					const pointerSize = 0.1;
+					const distanceFromPointer = length( sub( pointer, position ) );
 
-							}
+					assign( particle, cond( lessThanEqual( distanceFromPointer, pointerSize ), vec3(), position ) ).build( builder );
 
-							velocity.x = - velocity.x;
-
-						}
-
-						if ( abs( position.y ) >= limit.y ) {
-
-							if ( position.y > 0.0 ) {
-
-								position.y = limit.y;
-
-							} else {
-
-								position.y = -limit.y;
-
-							}
-
-							velocity.y = - velocity.y ;
-
-						}
-
-						let POINTER_SIZE = .1;
-
-						let dx = pointer.x - position.x;
-						let dy = pointer.y - position.y;
-						let distanceFromPointer = sqrt( dx * dx + dy * dy );
-
-						if ( distanceFromPointer <= POINTER_SIZE ) {
-
-							position.x = 0.0;
-							position.y = 0.0;
-							position.z = 0.0;
-
-						}
-
-						particle = position;
-
-					}
-				` );
-
-				// define particle and velocity keywords in wgsl function
-				// it's used in case of needed change a global variable like this storageBuffer
-
-				const particleNode = element( particleBufferNode, instanceIndex );
-				const velocityNode = element( velocityBufferNode, instanceIndex );
-
-				WGSLFnNode.keywords[ 'particle' ] = particleNode;
-				WGSLFnNode.keywords[ 'velocity' ] = velocityNode;
+				} );
 
 				// compute
 
 				computeNode = compute( particleNum );
 
-				// Example 1: Calling a WGSL function
-
-				computeNode.computeNode = WGSLFnNode.call( {
-					pointer: uniform( pointer ),
-					limit: uniform( scaleVector )
-				} );
-
-				// Example 2: Creating single storage assign
-
-				//computeNode.computeNode = assign( particleNode, add( particleNode, velocityNode ) );
-
-				// Example 3: Creating multiples storage assign
-
-				/*computeNode.computeNode = new Nodes.ShaderNode( ( {}, builder ) => {
-
-					assign( particleNode, add( particleNode, velocityNode ) ).build( builder );
-					assign( velocityNode, mul( velocityNode, float( 0.99 ) ) ).build( builder );
-
-				} );/**/
+				computeNode.computeNode = FnNode;
 
 				// use a compute shader to animate the point cloud's vertex data.
 
@@ -225,7 +166,7 @@
 				const width = window.innerWidth;
 				const height = window.innerHeight;
 
-				pointer.set(
+				pointerVector.set(
 					( x / width - 0.5 ) * 2.0,
 					( - y / height + 0.5 ) * 2.0
 				);