瀏覽代碼

Nodes: Refactor examples to use node chaining (#25539)

* Nodes: Refactor examples to use node chaining

* Fix ShaderNode.compute()

* Fixes
Levi Pesin 2 年之前
父節點
當前提交
7cd532e32b
共有 33 個文件被更改,包括 256 次插入298 次删除
  1. 1 1
      examples/jsm/nodes/lighting/LightsNode.js
  2. 5 7
      examples/jsm/nodes/shadernode/ShaderNode.js
  3. 3 4
      examples/webgl_nodes_loader_gltf_iridescence.html
  4. 3 4
      examples/webgl_nodes_loader_gltf_sheen.html
  5. 3 4
      examples/webgl_nodes_loader_gltf_transmission.html
  6. 1 1
      examples/webgl_nodes_loader_materialx.html
  7. 4 4
      examples/webgl_nodes_materials_instance_uniform.html
  8. 7 9
      examples/webgl_nodes_materials_physical_clearcoat.html
  9. 10 10
      examples/webgl_nodes_materials_standard.html
  10. 3 3
      examples/webgl_nodes_materialx_noise.html
  11. 5 5
      examples/webgl_nodes_playground.html
  12. 15 17
      examples/webgl_nodes_points.html
  13. 10 15
      examples/webgpu_audio_processing.html
  14. 17 23
      examples/webgpu_compute.html
  15. 8 9
      examples/webgpu_cubemap_adjustments.html
  16. 2 3
      examples/webgpu_cubemap_mix.html
  17. 5 7
      examples/webgpu_depth_texture.html
  18. 0 1
      examples/webgpu_equirectangular.html
  19. 1 2
      examples/webgpu_instance_mesh.html
  20. 4 4
      examples/webgpu_instance_uniform.html
  21. 9 9
      examples/webgpu_lights_custom.html
  22. 9 11
      examples/webgpu_lights_phong.html
  23. 11 13
      examples/webgpu_lights_selective.html
  24. 10 11
      examples/webgpu_loader_gltf.html
  25. 43 45
      examples/webgpu_materials.html
  26. 6 6
      examples/webgpu_nodes_playground.html
  27. 15 17
      examples/webgpu_particles.html
  28. 7 7
      examples/webgpu_rtt.html
  29. 26 29
      examples/webgpu_sandbox.html
  30. 3 3
      examples/webgpu_skinning.html
  31. 2 4
      examples/webgpu_skinning_instancing.html
  32. 4 4
      examples/webgpu_skinning_points.html
  33. 4 6
      examples/webgpu_sprites.html

+ 1 - 1
examples/jsm/nodes/lighting/LightsNode.js

@@ -80,7 +80,7 @@ class LightsNode extends Node {
 
 	}
 
-	fromLights( lights ) {
+	fromLights( lights = [] ) {
 
 		const lightNodes = [];
 

+ 5 - 7
examples/jsm/nodes/shadernode/ShaderNode.js

@@ -213,12 +213,6 @@ class ShaderNodeInternal extends Node {
 
 }
 
-const ShaderNodeScript = function ( jsFunc ) {
-
-	return new ShaderNodeInternal( jsFunc );
-
-};
-
 const bools = [ false, true ];
 const uints = [ 0, 1, 2, 3 ];
 const ints = [ - 1, - 2 ];
@@ -305,7 +299,11 @@ export const getConstNodeType = ( value ) => ( value !== undefined && value !==
 
 // shader node base
 
-export const ShaderNode = new Proxy( ShaderNodeScript, shaderNodeHandler );
+export function ShaderNode( jsFunc ) {
+
+	return new Proxy( new ShaderNodeInternal( jsFunc ), shaderNodeHandler );
+
+}
 
 export const nodeObject = ( val ) => /* new */ ShaderNodeObject( val );
 export const nodeObjects = ( val ) => new ShaderNodeObjects( val );

+ 3 - 4
examples/webgl_nodes_loader_gltf_iridescence.html

@@ -31,8 +31,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-
-			import { NodeMaterial, uv, add, mul, vec2, checker, float, timerLocal } from 'three/nodes';
+			import { NodeMaterial, uv, vec2, checker, float, timerLocal } from 'three/nodes';
 
 			import { nodeFrame } from 'three/addons/renderers/webgl/nodes/WebGLNodes.js';
 
@@ -86,9 +85,9 @@
 
 					if ( material && material.iridescence > 0 ) {
 
-						const iridescenceFactorNode = checker( mul( add( uv(), vec2( timerLocal( - .05 ), 0 ) ), 20 ) );
+						const iridescenceFactorNode = checker( uv().add( vec2( timerLocal( - .05 ), 0 ) ).mul( 20 ) );
 
-						const nodeMaterial = NodeMaterial.fromMaterial( material );
+						const nodeMaterial = NodeMaterial.fromMaterial( material ); // @TODO: NodeMaterial.fromMaterial can be removed if WebGLNodes will apply it by default (as in WebGPURenderer)
 						nodeMaterial.iridescenceNode = iridescenceFactorNode;
 						nodeMaterial.iridescenceIORNode = float( 1.3 );
 						nodeMaterial.iridescenceThicknessNode = float( 400 );

+ 3 - 4
examples/webgl_nodes_loader_gltf_sheen.html

@@ -35,8 +35,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-
-			import { NodeMaterial, uv, mul, mix, color, checker } from 'three/nodes';
+			import { NodeMaterial, uv, mix, color, checker } from 'three/nodes';
 
 			import { nodeFrame } from 'three/addons/renderers/webgl/nodes/WebGLNodes.js';
 
@@ -70,9 +69,9 @@
 						const object = gltf.scene.getObjectByName( 'SheenChair_fabric' );
 
 						// Convert to NodeMaterial
-						const material = NodeMaterial.fromMaterial( object.material );
+						const material = NodeMaterial.fromMaterial( object.material ); // @TODO: NodeMaterial.fromMaterial can be removed if WebGLNodes will apply it by default (as in WebGPURenderer)
 
-						const checkerNode = checker( mul( uv(), 5 ) );
+						const checkerNode = checker( uv().mul( 5 ) );
 
 						material.sheenNode = mix( color( 0x00ffff ), color( 0xffff00 ), checkerNode );
 						material.sheenRoughnessNode = checkerNode;

+ 3 - 4
examples/webgl_nodes_loader_gltf_transmission.html

@@ -31,8 +31,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-
-			import { NodeMaterial, float, texture, mul } from 'three/nodes';
+			import { NodeMaterial, float, texture } from 'three/nodes';
 
 			import { nodeFrame } from 'three/addons/renderers/webgl/nodes/WebGLNodes.js';
 
@@ -83,10 +82,10 @@
 
 								if ( material && material.transmission > 0 ) {
 
-									const nodeMaterial = NodeMaterial.fromMaterial( material );
+									const nodeMaterial = NodeMaterial.fromMaterial( material ); // @TODO: NodeMaterial.fromMaterial can be removed if WebGLNodes will apply it by default (as in WebGPURenderer)
 									nodeMaterial.transmissionNode = float( 1 );
 									nodeMaterial.iorNode = float( 1.5 );
-									nodeMaterial.thicknessNode = mul( texture( material.thicknessMap ).g, 0.1 );
+									nodeMaterial.thicknessNode = texture( material.thicknessMap ).g.mul( 0.1 );
 									//nodeMaterial.attenuationDistanceNode;
 									//nodeMaterial.attenuationColorNode;
 

+ 1 - 1
examples/webgl_nodes_loader_materialx.html

@@ -33,7 +33,7 @@
 
 		<script type="module">
 
-			import * as THREE from '../build/three.module.js';
+			import * as THREE from 'three';
 
 			import { MaterialXLoader } from './jsm/loaders/MaterialXLoader.js';
 			import { OrbitControls } from './jsm/controls/OrbitControls.js';

+ 4 - 4
examples/webgl_nodes_materials_instance_uniform.html

@@ -28,7 +28,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import { MeshStandardNodeMaterial, Node, NodeUpdateType, uniform, cubeTexture, add, mul } from 'three/nodes';
+			import { MeshStandardNodeMaterial, Node, NodeUpdateType, nodeObject, uniform, cubeTexture } from 'three/nodes';
 
 			import Stats from 'three/addons/libs/stats.module.js';
 
@@ -103,12 +103,12 @@
 
 				// Material
 
-				const instanceUniform = new InstanceUniformNode();
+				const instanceUniform = nodeObject( new InstanceUniformNode() );
 				const cubeTextureNode = cubeTexture( cubeMap );
 
 				const material = new MeshStandardNodeMaterial();
-				material.colorNode = add( instanceUniform, cubeTextureNode );
-				material.emissiveNode = mul( instanceUniform, cubeTextureNode );
+				material.colorNode = instanceUniform.add( cubeTextureNode );
+				material.emissiveNode = instanceUniform.mul( cubeTextureNode );
 
 				// Spheres geometry
 

+ 7 - 9
examples/webgl_nodes_materials_physical_clearcoat.html

@@ -28,9 +28,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
-
-			import { color, float, vec2, texture, normalMap, uv, mul } from 'three/nodes';
+			import { color, float, vec2, texture, normalMap, uv, MeshPhysicalNodeMaterial } from 'three/nodes';
 
 			import { nodeFrame } from 'three/addons/renderers/webgl/nodes/WebGLNodes.js';
 
@@ -95,10 +93,10 @@
 
 							// car paint
 
-							const carPaintUV = mul( uv(), vec2( 10, 6 ) );
+							const carPaintUV = uv().mul( vec2( 10, 6 ) );
 							const carPaintNormalScale = vec2( 0.15 );
 
-							let material = new Nodes.MeshPhysicalNodeMaterial();
+							let material = new MeshPhysicalNodeMaterial();
 							material.clearcoatNode = float( 1 );
 							material.clearcoatRoughnessNode = float( 0.1 );
 							material.metalnessNode = float( 0.9 );
@@ -113,9 +111,9 @@
 
 							// fibers
 
-							const fibersUV = mul( uv(), 10 );
+							const fibersUV = uv().mul( 10 );
 
-							material = new Nodes.MeshPhysicalNodeMaterial();
+							material = new MeshPhysicalNodeMaterial();
 							material.roughnessNode = float( 0.5 );
 							material.clearcoatNode = float( 1 );
 							material.clearcoatRoughnessNode = float( 0.1 );
@@ -129,7 +127,7 @@
 
 							// golf
 
-							material = new Nodes.MeshPhysicalNodeMaterial();
+							material = new MeshPhysicalNodeMaterial();
 							material.clearcoatNode = float( 1 );
 							material.roughnessNode = float( 0.1 );
 							material.metalnessNode = float( 0 );
@@ -145,7 +143,7 @@
 
 							// clearcoat + normalmap
 
-							material = new Nodes.MeshPhysicalNodeMaterial();
+							material = new MeshPhysicalNodeMaterial();
 							material.clearcoatNode = float( 1 );
 							material.roughnessNode = float( 1 );
 							material.metalnessNode = float( 1 );

+ 10 - 10
examples/webgl_nodes_materials_standard.html

@@ -30,7 +30,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { texture, uniform, normalMap, MeshStandardNodeMaterial, NodeObjectLoader } from 'three/nodes';
 
 			import Stats from 'three/addons/libs/stats.module.js';
 
@@ -77,7 +77,7 @@
 
 				// Test Extended Material
 
-				class MeshCustomNodeMaterial extends Nodes.MeshStandardNodeMaterial {
+				class MeshCustomNodeMaterial extends MeshStandardNodeMaterial {
 
 					constructor() {
 
@@ -127,18 +127,18 @@
 						const rmMap = loader.load( 'Cerberus_RM.jpg' );
 						rmMap.wrapS = THREE.RepeatWrapping;
 
-						const normalMap = loader.load( 'Cerberus_N.jpg' );
-						normalMap.wrapS = THREE.RepeatWrapping;
+						const normalMapTexture = loader.load( 'Cerberus_N.jpg' );
+						normalMapTexture.wrapS = THREE.RepeatWrapping;
 
-						const mpMapNode = new Nodes.TextureNode( rmMap );
+						const mgMapNode = texture( rmMap );
 
-						material.colorNode = new Nodes.OperatorNode( '*', new Nodes.TextureNode( diffuseMap ), new Nodes.UniformNode( material.color ) );
+						material.colorNode = texture( diffuseMap ).mul( uniform( material.color ) );
 
 						// roughness is in G channel, metalness is in B channel
-						material.roughnessNode = new Nodes.SplitNode( mpMapNode, 'g' );
-						material.metalnessNode = new Nodes.SplitNode( mpMapNode, 'b' );
+						material.roughnessNode = mgMapNode.g;
+						material.metalnessNode = mgMapNode.b;
 
-						material.normalNode = new Nodes.NormalMapNode( new Nodes.TextureNode( normalMap ) );
+						material.normalNode = normalMap( texture( normalMapTexture ) );
 
 						group.traverse( function ( child ) {
 
@@ -160,7 +160,7 @@
 
 							const groupJSON = JSON.stringify( group.toJSON() );
 
-							const objectLoader = new Nodes.NodeObjectLoader();
+							const objectLoader = new NodeObjectLoader();
 							objectLoader.parse( JSON.parse( groupJSON ), ( newGroup ) => {
 
 								//scene.remove( group );

+ 3 - 3
examples/webgl_nodes_materialx_noise.html

@@ -28,7 +28,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import { MeshPhysicalNodeMaterial, add, mul, normalWorld, timerLocal, mx_noise_vec3, mx_worley_noise_vec3, mx_cell_noise_float, mx_fractal_noise_vec3 } from 'three/nodes';
+			import { MeshPhysicalNodeMaterial, normalWorld, timerLocal, mx_noise_vec3, mx_worley_noise_vec3, mx_cell_noise_float, mx_fractal_noise_vec3 } from 'three/nodes';
 
 			import { nodeFrame } from 'three/addons/renderers/webgl/nodes/WebGLNodes.js';
 
@@ -68,7 +68,7 @@
 							const geometry = new THREE.SphereGeometry( 80, 64, 32 );
 
 							const offsetNode = timerLocal();
-							const customUV = add( mul( normalWorld, 10 ), offsetNode );
+							const customUV = normalWorld.mul( 10 ).add( offsetNode );
 
 							// left top
 
@@ -103,7 +103,7 @@
 							// right bottom
 
 							material = new MeshPhysicalNodeMaterial();
-							material.colorNode = mx_fractal_noise_vec3( mul( customUV, .2 ) );
+							material.colorNode = mx_fractal_noise_vec3( customUV.mul( .2 ) );
 
 							mesh = new THREE.Mesh( geometry, material );
 							mesh.position.x = 100;

+ 5 - 5
examples/webgl_nodes_playground.html

@@ -54,7 +54,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { uniform, MeshBasicNodeMaterial, PointsNodeMaterial } from 'three/nodes';
 
 			import { nodeFrame } from 'three/addons/renderers/webgl/nodes/WebGLNodes.js';
 
@@ -144,8 +144,8 @@
 				const loaderFBX = new FBXLoader();
 				loaderFBX.load( 'models/fbx/stanford-bunny.fbx', ( object ) => {
 
-					const defaultMaterial = new Nodes.MeshBasicNodeMaterial();
-					defaultMaterial.colorNode = new Nodes.UniformNode( 0 );
+					const defaultMaterial = new MeshBasicNodeMaterial();
+					defaultMaterial.colorNode = uniform( 0 );
 
 					const sphere = new THREE.Mesh( new THREE.SphereGeometry( 2, 32, 16 ), defaultMaterial );
 					sphere.name = 'Sphere';
@@ -157,8 +157,8 @@
 					box.position.set( - 5, 0, - 5 );
 					scene.add( box );
 
-					const defaultPointsMaterial = new Nodes.PointsNodeMaterial();
-					defaultPointsMaterial.colorNode = new Nodes.UniformNode( 0 );
+					const defaultPointsMaterial = new PointsNodeMaterial();
+					defaultPointsMaterial.colorNode = uniform( 0 );
 					defaultPointsMaterial.size = 0.01;
 
 					const torusKnot = new THREE.Points( new THREE.TorusKnotGeometry( 1, .3, 100, 16 ), defaultPointsMaterial );

+ 15 - 17
examples/webgl_nodes_points.html

@@ -29,7 +29,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { attribute, timerLocal, positionLocal, spritesheetUV, pointUV, vec2, texture, uniform, mix, PointsNodeMaterial } from 'three/nodes';
 
 			import Stats from 'three/addons/libs/stats.module.js';
 
@@ -96,31 +96,29 @@
 
 				// nodes
 
-				const targetPosition = new Nodes.AttributeNode( 'targetPosition', 'vec3' );
-				const particleSpeed = new Nodes.AttributeNode( 'particleSpeed', 'float' );
-				const particleIntensity = new Nodes.AttributeNode( 'particleIntensity', 'float' );
-				const particleSize = new Nodes.AttributeNode( 'particleSize', 'float' );
+				const targetPosition = attribute( 'targetPosition', 'vec3' );
+				const particleSpeed = attribute( 'particleSpeed', 'float' );
+				const particleIntensity = attribute( 'particleIntensity', 'float' );
+				const particleSize = attribute( 'particleSize', 'float' );
 
-				const time = new Nodes.TimerNode();
+				const time = timerLocal();
 
-				const spriteSheetCount = Nodes.vec2( 6, 6 );
-
-				const fireUV = new Nodes.SpriteSheetUVNode(
-					spriteSheetCount, // count
-					Nodes.pointUV, // uv
-					Nodes.mul( time, particleSpeed ) // current frame
+				const fireUV = spritesheetUV(
+					vec2( 6, 6 ), // count
+					pointUV, // uv
+					time.mul( particleSpeed ) // current frame
 				);
 
-				const fireSprite = new Nodes.TextureNode( fireMap, fireUV );
-				const fire = new Nodes.OperatorNode( '*', fireSprite, particleIntensity );
+				const fireSprite = texture( fireMap, fireUV );
+				const fire = fireSprite.mul( particleIntensity );
 
-				const lerpPosition = new Nodes.UniformNode( 0 );
+				const lerpPosition = uniform( 0 );
 
-				const positionNode = new Nodes.MathNode( Nodes.MathNode.MIX, new Nodes.PositionNode( Nodes.PositionNode.LOCAL ), targetPosition, lerpPosition );
+				const positionNode = mix( positionLocal, targetPosition, lerpPosition );
 
 				// material
 
-				const material = new Nodes.PointsNodeMaterial( {
+				const material = new PointsNodeMaterial( {
 					depthWrite: false,
 					transparent: true,
 					sizeAttenuation: true,

+ 10 - 15
examples/webgpu_audio_processing.html

@@ -31,12 +31,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-
-			import {
-				ShaderNode, compute,
-				uniform, element, storage, instanceIndex,
-				float, add, sub, div, mul, texture, viewportTopLeft, color
-			} from 'three/nodes';
+			import { ShaderNode, uniform, storage, instanceIndex, float, texture, viewportTopLeft, color } from 'three/nodes';
 
 			import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
 
@@ -148,26 +143,26 @@
 
 					// pitch
 
-					const time = mul( index, pitch );
+					const time = index.mul( pitch );
 
-					let wave = element( waveNode, time );
+					let wave = waveNode.element( time );
 
 
 					// delay
 
 					for ( let i = 1; i < 7; i ++ ) {
 
-						const waveOffset = element( waveNode, mul( sub( index, mul( mul( delayOffset, sampleRate ), i ) ), pitch ) );
-						const waveOffsetVolume = mul( waveOffset, div( delayVolume, i * i ) );
+						const waveOffset = waveNode.element( index.sub( delayOffset.mul( sampleRate ).mul( i ) ).mul( pitch ) );
+						const waveOffsetVolume = waveOffset.mul( delayVolume.div( i * i ) );
 
-						wave = add( wave, waveOffsetVolume );
+						wave = wave.add( waveOffsetVolume );
 
 					}
 
 
 					// store
 
-					const waveStorageElementNode = element( waveStorageNode, instanceIndex );
+					const waveStorageElementNode = waveStorageNode.element( instanceIndex );
 
 					stack.assign( waveStorageElementNode, wave );
 
@@ -176,7 +171,7 @@
 
 				// compute
 
-				computeNode = compute( computeShaderNode, waveBuffer.length );
+				computeNode = computeShaderNode.compute( waveBuffer.length );
 
 
 				// gui
@@ -200,8 +195,8 @@
 
 				analyserTexture = new THREE.DataTexture( analyserBuffer, analyserBuffer.length, 1, THREE.RedFormat );
 
-				const spectrum = mul( texture( analyserTexture, viewportTopLeft.x ).x, viewportTopLeft.y );
-				const backgroundNode = mul( color( 0x0000FF ), spectrum );
+				const spectrum = texture( analyserTexture, viewportTopLeft.x ).x.mul( viewportTopLeft.y );
+				const backgroundNode = color( 0x0000FF ).mul( spectrum );
 
 
 				// scene

+ 17 - 23
examples/webgpu_compute.html

@@ -26,13 +26,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
-
-			import {
-				ShaderNode, compute,
-				uniform, element, storage, attribute, mul, sin, cos,
-				add, cond, abs, max, min, float, vec2, vec3, color, instanceIndex
-			} from 'three/nodes';
+			import { ShaderNode, uniform, storage, attribute, float, vec2, vec3, color, instanceIndex, PointsNodeMaterial } from 'three/nodes';
 
 			import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
 
@@ -82,48 +76,48 @@
 
 				const computeShaderNode = new ShaderNode( ( inputs, stack ) => {
 
-					const particle = element( particleBufferNode, instanceIndex );
-					const velocity = element( velocityBufferNode, instanceIndex );
+					const particle = particleBufferNode.element( instanceIndex );
+					const velocity = velocityBufferNode.element( instanceIndex );
 
 					const pointer = uniform( pointerVector );
 					const limit = uniform( scaleVector );
 
-					const position = add( particle, velocity );
+					const position = particle.add( velocity );
 
-					stack.assign( velocity.x, abs( position.x ).greaterThanEqual( limit.x ).cond( velocity.x.negate(), velocity.x ) );
-					stack.assign( velocity.y, abs( position.y ).greaterThanEqual( limit.y ).cond( velocity.y.negate(), velocity.y ) );
+					stack.assign( velocity.x, position.x.abs().greaterThanEqual( limit.x ).cond( velocity.x.negate(), velocity.x ) );
+					stack.assign( velocity.y, position.y.abs().greaterThanEqual( limit.y ).cond( velocity.y.negate(), velocity.y ) );
 
-					stack.assign( position, max( limit.negate(), min( limit, position ) ) );
+					stack.assign( position, position.min( limit ).max( limit.negate() ) );
 
 					const pointerSize = 0.1;
 					const distanceFromPointer = pointer.sub( position ).length();
 
-					stack.assign( particle, cond( distanceFromPointer.lessThanEqual( pointerSize ), vec3(), position ) );
+					stack.assign( particle, distanceFromPointer.lessThanEqual( pointerSize ).cond( vec3(), position ) );
 
 				} );
 
 				// compute
 
-				computeNode = compute( computeShaderNode, particleNum );
+				computeNode = computeShaderNode.compute( particleNum );
 				computeNode.onInit = ( { renderer } ) => {
 
 					const precomputeShaderNode = new ShaderNode( ( inputs, stack ) => {
 
 						const particleIndex = float( instanceIndex );
 
-						const randomAngle = mul( mul( particleIndex, .005 ), Math.PI * 2 );
-						const randomSpeed = add( mul( particleIndex, 0.00000001 ), 0.0000001 );
+						const randomAngle = particleIndex.mul( .005 ).mul( Math.PI * 2 );
+						const randomSpeed = particleIndex.mul( 0.00000001 ).add( 0.0000001 );
 
-						const velX = mul( sin( randomAngle ), randomSpeed );
-						const velY = mul( cos( randomAngle ), randomSpeed );
+						const velX = randomAngle.sin().mul( randomSpeed );
+						const velY = randomAngle.cos().mul( randomSpeed );
 
-						const velocity = element( velocityBufferNode, instanceIndex );
+						const velocity = velocityBufferNode.element( instanceIndex );
 
 						stack.assign( velocity.xy, vec2( velX, velY ) );
 
 					} );
 
-					renderer.compute( compute( precomputeShaderNode, computeNode.count ) );
+					renderer.compute( precomputeShaderNode.compute( particleNum ) );
 
 				};
 
@@ -136,8 +130,8 @@
 				pointsGeometry.setAttribute( 'particle', particleBuffer ); // dummy the position points as instances
 				pointsGeometry.drawRange.count = 1; // force render points as instances ( not triangle )
 
-				const pointsMaterial = new Nodes.PointsNodeMaterial();
-				pointsMaterial.colorNode = add( particleNode, color( 0xFFFFFF ) );
+				const pointsMaterial = new PointsNodeMaterial();
+				pointsMaterial.colorNode = particleNode.add( color( 0xFFFFFF ) );
 				pointsMaterial.positionNode = particleNode;
 
 				const mesh = new THREE.Points( pointsGeometry, pointsMaterial );

+ 8 - 9
examples/webgpu_cubemap_adjustments.html

@@ -31,8 +31,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-
-			import { uniform, mix, cubeTexture, mul, reference, add, positionWorld, normalWorld, modelWorldMatrix, transformDirection, clamp, saturation, hue, reflectVector, context, toneMapping } from 'three/nodes';
+			import { uniform, mix, cubeTexture, reference, positionWorld, normalWorld, modelWorldMatrix, reflectVector, toneMapping } from 'three/nodes';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
@@ -108,15 +107,15 @@
 
 				const getEnvironmentNode = ( reflectNode ) => {
 
-					const custom1UV = mul( reflectNode.xyz, uniform( rotateY1Matrix ) );
-					const custom2UV = mul( reflectNode.xyz, uniform( rotateY2Matrix ) );
+					const custom1UV = reflectNode.xyz.mul( uniform( rotateY1Matrix ) );
+					const custom2UV = reflectNode.xyz.mul( uniform( rotateY2Matrix ) );
+					const mixCubeMaps = mix( cubeTexture( cube1Texture, custom1UV ), cubeTexture( cube2Texture, custom2UV ), positionWorld.y.add( mixNode ).clamp() );
 
-					const mixCubeMaps = mix( cubeTexture( cube1Texture, custom1UV ), cubeTexture( cube2Texture, custom2UV ), clamp( add( positionWorld.y, mixNode ) ) );
 					const proceduralEnv = mix( mixCubeMaps, normalWorld, proceduralNode );
-					const intensityFilter = mul( proceduralEnv, intensityNode );
-					const hueFilter = hue( intensityFilter, hueNode );
 
-					return saturation( hueFilter, saturationNode );
+					const intensityFilter = proceduralEnv.mul( intensityNode );
+					const hueFilter = intensityFilter.hue( hueNode );
+					return hueFilter.saturation( saturationNode );
 
 				};
 
@@ -124,7 +123,7 @@
 
 				scene.environmentNode = getEnvironmentNode( reflectVector );
 
-				scene.backgroundNode = context( getEnvironmentNode( transformDirection( positionWorld, modelWorldMatrix ) ), {
+				scene.backgroundNode = getEnvironmentNode( positionWorld.transformDirection( modelWorldMatrix ) ).context( {
 					getSamplerLevelNode: () => blurNode
 				} );
 

+ 2 - 3
examples/webgpu_cubemap_mix.html

@@ -31,8 +31,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-
-			import { mix, oscSine, timerLocal, cubeTexture, context, float, toneMapping } from 'three/nodes';
+			import { mix, oscSine, timerLocal, cubeTexture, float, toneMapping } from 'three/nodes';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
@@ -83,7 +82,7 @@
 
 				scene.environmentNode = mix( cubeTexture( cube2Texture ), cubeTexture( cube1Texture ), oscSine( timerLocal( .1 ) ) );
 
-				scene.backgroundNode = context( scene.environmentNode, {
+				scene.backgroundNode = scene.environmentNode.context( {
 					getSamplerLevelNode: () => float( 1 )
 				} );
 

+ 5 - 7
examples/webgpu_depth_texture.html

@@ -26,14 +26,12 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { smoothstep, positionView, texture, MeshBasicNodeMaterial } from 'three/nodes';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
 			import WebGPUTextureRenderer from 'three/addons/renderers/webgpu/WebGPUTextureRenderer.js';
 
-			import { smoothstep, negate, positionView, invert } from 'three/nodes';
-
 			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
 
 			let camera, scene, controls, renderer;
@@ -62,8 +60,8 @@
 
 				// depth material
 
-				const material = new Nodes.MeshBasicNodeMaterial();
-				material.colorNode = invert( smoothstep( camera.near, camera.far, negate( positionView.z ) ) );
+				const material = new MeshBasicNodeMaterial();
+				material.colorNode = smoothstep( camera.near, camera.far, positionView.z.negate() ).invert();
 
 				//
 
@@ -111,8 +109,8 @@
 
 				//
 
-				const materialFX = new Nodes.MeshBasicNodeMaterial();
-				materialFX.colorNode = new Nodes.TextureNode( textureRenderer.getTexture() );
+				const materialFX = new MeshBasicNodeMaterial();
+				materialFX.colorNode = texture( textureRenderer.getTexture() );
 
 				const quad = new THREE.Mesh( geometryFX, materialFX );
 				sceneFX.add( quad );

+ 0 - 1
examples/webgpu_equirectangular.html

@@ -29,7 +29,6 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-
 			import { texture, equirectUV } from 'three/nodes';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';

+ 1 - 2
examples/webgpu_instance_mesh.html

@@ -27,12 +27,11 @@
 		<script type="module">
 
 			import * as THREE from 'three';
+			import { mix, range, normalWorld, oscSine, timerLocal } from 'three/nodes';
 
 			import Stats from 'three/addons/libs/stats.module.js';
 			import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
 
-			import { mix, range, normalWorld, oscSine, timerLocal } from 'three/nodes';
-
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
 

+ 4 - 4
examples/webgpu_instance_uniform.html

@@ -27,7 +27,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import { MeshStandardNodeMaterial, NodeUpdateType, Node, uniform, attribute, cubeTexture, add, mul } from 'three/nodes';
+			import { MeshStandardNodeMaterial, NodeUpdateType, Node, nodeObject, uniform, attribute, cubeTexture } from 'three/nodes';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
@@ -116,12 +116,12 @@
 
 				// Materials
 
-				const instanceUniform = new InstanceUniformNode();
+				const instanceUniform = nodeObject( new InstanceUniformNode() );
 				const cubeTextureNode = cubeTexture( cTexture );
 
 				const material = new MeshStandardNodeMaterial();
-				material.colorNode = add( instanceUniform, cubeTextureNode );
-				material.emissiveNode = mul( instanceUniform, cubeTextureNode );
+				material.colorNode = instanceUniform.add( cubeTextureNode );
+				material.emissiveNode = instanceUniform.mul( cubeTextureNode );
 
 				// Geometry
 

+ 9 - 9
examples/webgpu_lights_custom.html

@@ -26,7 +26,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { ShaderNode, color, lights, toneMapping, MeshStandardNodeMaterial, PointsNodeMaterial } from 'three/nodes';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
@@ -61,9 +61,9 @@
 
 				const addLight = ( hexColor, intensity = 2, distance = 1 ) => {
 
-					const material = new Nodes.MeshStandardNodeMaterial();
-					material.colorNode = new Nodes.ConstNode( new THREE.Color( hexColor ) );
-					material.lightsNode = new Nodes.LightsNode(); // ignore scene lights
+					const material = new MeshStandardNodeMaterial();
+					material.colorNode = color( hexColor );
+					material.lightsNode = lights(); // ignore scene lights
 
 					const mesh = new THREE.Mesh( sphereGeometry, material );
 
@@ -82,7 +82,7 @@
 
 				//light nodes ( selective lights )
 
-				const allLightsNode = new Nodes.LightsNode().fromLights( [ light1, light2, light3 ] );
+				const allLightsNode = lights( [ light1, light2, light3 ] );
 
 				// points
 
@@ -96,11 +96,11 @@
 				}
 
 				const geometryPoints = new THREE.BufferGeometry().setFromPoints( points );
-				const materialPoints = new Nodes.PointsNodeMaterial();
+				const materialPoints = new PointsNodeMaterial();
 
 				// custom lighting model
 
-				const customLightingModel = new Nodes.ShaderNode( ( inputs ) => {
+				const customLightingModel = new ShaderNode( ( inputs ) => {
 
 					const { lightColor, reflectedLight } = inputs;
 
@@ -108,7 +108,7 @@
 
 				} );
 
-				const lightingModelContext = Nodes.context( allLightsNode, { lightingModelNode: { direct: customLightingModel } } );
+				const lightingModelContext = allLightsNode.context( { lightingModelNode: { direct: customLightingModel } } );
 
 				materialPoints.lightsNode = lightingModelContext;
 
@@ -123,7 +123,7 @@
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setAnimationLoop( animate );
-				renderer.toneMappingNode = Nodes.toneMapping( THREE.LinearToneMapping, 1 );
+				renderer.toneMappingNode = toneMapping( THREE.LinearToneMapping, 1 );
 				renderer.outputEncoding = THREE.sRGBEncoding;
 				document.body.appendChild( renderer.domElement );
 

+ 9 - 11
examples/webgpu_lights_phong.html

@@ -28,7 +28,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { color, rangeFog, checker, uv, mix, texture, lights, normalMap, MeshPhongNodeMaterial } from 'three/nodes';
 
 			import Stats from 'three/addons/libs/stats.module.js';
 
@@ -38,8 +38,6 @@
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
 
-			import { float, color, rangeFog, checker, uv, mix, texture } from 'three/nodes';
-
 			let camera, scene, renderer,
 				light1, light2, light3, light4,
 				stats, controls;
@@ -80,7 +78,7 @@
 
 				const addLight = ( hexColor, power = 1700, distance = 100 ) => {
 
-					const material = new Nodes.MeshPhongNodeMaterial();
+					const material = new MeshPhongNodeMaterial();
 					material.colorNode = color( hexColor );
 					material.lights = false;
 
@@ -103,25 +101,25 @@
 
 				// light nodes ( selective lights )
 
-				const blueLightsNode = Nodes.lights( [ light1 ] );
-				const whiteLightsNode = Nodes.lights( [ light2 ] );
+				const blueLightsNode = lights( [ light1 ] );
+				const whiteLightsNode = lights( [ light2 ] );
 
 				// models
 
 				const geometryTeapot = new TeapotGeometry( .8, 18 );
 
-				const leftObject = new THREE.Mesh( geometryTeapot, new Nodes.MeshPhongNodeMaterial( { color: 0x555555 } ) );
+				const leftObject = new THREE.Mesh( geometryTeapot, new MeshPhongNodeMaterial( { color: 0x555555 } ) );
 				leftObject.material.lightsNode = blueLightsNode;
 				leftObject.material.specularNode = texture( alphaTexture );
 				leftObject.position.x = - 3;
 				scene.add( leftObject );
 
-				const centerObject = new THREE.Mesh( geometryTeapot, new Nodes.MeshPhongNodeMaterial( { color: 0x555555 } ) );
-				centerObject.material.normalNode = new Nodes.NormalMapNode( texture( normalMapTexture ) );
-				centerObject.material.shininessNode = float( 80 );
+				const centerObject = new THREE.Mesh( geometryTeapot, new MeshPhongNodeMaterial( { color: 0x555555 } ) );
+				centerObject.material.normalNode = normalMap( texture( normalMapTexture ) );
+				centerObject.material.shininess = 80;
 				scene.add( centerObject );
 
-				const rightObject = new THREE.Mesh( geometryTeapot, new Nodes.MeshPhongNodeMaterial( { color: 0x555555 } ) );
+				const rightObject = new THREE.Mesh( geometryTeapot, new MeshPhongNodeMaterial( { color: 0x555555 } ) );
 				rightObject.material.lightsNode = whiteLightsNode;
 				//rightObject.material.specular.setHex( 0xFF00FF );
 				rightObject.material.specularNode = mix( color( 0x0000FF ), color( 0xFF0000 ), checker( uv().mul( 5 ) ) );

+ 11 - 13
examples/webgpu_lights_selective.html

@@ -28,7 +28,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { rangeFog, color, lights, texture, normalMap, MeshStandardNodeMaterial } from 'three/nodes';
 
 			import Stats from 'three/addons/libs/stats.module.js';
 
@@ -40,8 +40,6 @@
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
 
-			import { color, float } from 'three/nodes';
-
 			let camera, scene, renderer,
 				light1, light2, light3, light4,
 				stats, controls;
@@ -62,7 +60,7 @@
 				camera.position.z = 7;
 
 				scene = new THREE.Scene();
-				scene.fogNode = new Nodes.FogRangeNode( color( 0xFF00FF ), float( 3 ), float( 30 ) );
+				scene.fogNode = rangeFog( color( 0xFF00FF ), 3, 30 );
 
 				const sphereGeometry = new THREE.SphereGeometry( 0.1, 16, 8 );
 
@@ -82,7 +80,7 @@
 
 				const addLight = ( hexColor, power = 1700, distance = 100 ) => {
 
-					const material = new Nodes.MeshStandardNodeMaterial();
+					const material = new MeshStandardNodeMaterial();
 					material.colorNode = color( hexColor );
 					material.lights = false;
 
@@ -105,29 +103,29 @@
 
 				//light nodes ( selective lights )
 
-				const redLightsNode = Nodes.lights( [ light1 ] );
-				const blueLightsNode = Nodes.lights( [ light2 ] );
+				const redLightsNode = lights( [ light1 ] );
+				const blueLightsNode = lights( [ light2 ] );
 
 				//models
 
 				const geometryTeapot = new TeapotGeometry( .8, 18 );
 
-				const leftObject = new THREE.Mesh( geometryTeapot, new Nodes.MeshStandardNodeMaterial( { color: 0x555555 } ) );
+				const leftObject = new THREE.Mesh( geometryTeapot, new MeshStandardNodeMaterial( { color: 0x555555 } ) );
 				leftObject.material.lightsNode = redLightsNode;
-				leftObject.material.roughnessNode = new Nodes.TextureNode( alphaTexture );
+				leftObject.material.roughnessNode = texture( alphaTexture );
 				leftObject.material.metalness = 0;
 				leftObject.position.x = - 3;
 				scene.add( leftObject );
 
-				const centerObject = new THREE.Mesh( geometryTeapot, new Nodes.MeshStandardNodeMaterial( { color: 0x555555 } ) );
-				centerObject.material.normalNode = new Nodes.NormalMapNode( Nodes.texture( normalMapTexture ) );
+				const centerObject = new THREE.Mesh( geometryTeapot, new MeshStandardNodeMaterial( { color: 0x555555 } ) );
+				centerObject.material.normalNode = normalMap( texture( normalMapTexture ) );
 				centerObject.material.metalness = .5;
 				centerObject.material.roughness = .5;
 				scene.add( centerObject );
 
-				const rightObject = new THREE.Mesh( geometryTeapot, new Nodes.MeshStandardNodeMaterial( { color: 0x555555 } ) );
+				const rightObject = new THREE.Mesh( geometryTeapot, new MeshStandardNodeMaterial( { color: 0x555555 } ) );
 				rightObject.material.lightsNode = blueLightsNode;
-				rightObject.material.metalnessNode = new Nodes.TextureNode( alphaTexture );
+				rightObject.material.metalnessNode = texture( alphaTexture );
 				rightObject.position.x = 3;
 				scene.add( rightObject );
 

+ 10 - 11
examples/webgpu_loader_gltf.html

@@ -32,7 +32,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { cubeTexture, texture, normalMap, toneMapping } from 'three/nodes';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
@@ -67,15 +67,15 @@
 
 				const rgbmUrls = [ 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' ];
 
-				const cubeTexture = new RGBMLoader()
+				const cubeMap = new RGBMLoader()
 					.setMaxRange( 16 )
 					.setPath( './textures/cube/pisaRGBM16/' )
 					.loadCubemap( rgbmUrls );
 
-				cubeTexture.generateMipmaps = true;
-				cubeTexture.minFilter = THREE.LinearMipmapLinearFilter;
+				cubeMap.generateMipmaps = true;
+				cubeMap.minFilter = THREE.LinearMipmapLinearFilter;
 
-				scene.environmentNode = new Nodes.CubeTextureNode( cubeTexture );
+				scene.environmentNode = cubeTexture( cubeMap );
 				scene.backgroundNode = scene.environmentNode;
 
 				const loader = new GLTFLoader().setPath( 'models/gltf/DamagedHelmet/glTF/' );
@@ -85,16 +85,15 @@
 					//camera.add( light );
 
 					const mesh = gltf.scene.children[ 0 ];
-					const nodeMaterial = Nodes.NodeMaterial.fromMaterial( mesh.material );
+					const material = mesh.material;
 
-					nodeMaterial.normalNode = Nodes.normalMap( Nodes.texture( nodeMaterial.normalMap ) );
-					nodeMaterial.normalMap = null; // ignore non-node normalMap material
+					const oldNormalMap = material.normalMap;
+					material.normalNode = normalMap( texture( oldNormalMap ) );
+					material.normalMap = null; // ignore non-node normalMap material
 
 					// optional: use tangent to compute normalMap
 					mesh.geometry.computeTangents();
 
-					mesh.material = nodeMaterial;
-
 					scene.add( gltf.scene );
 
 					render();
@@ -114,7 +113,7 @@
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setAnimationLoop( render );
-				renderer.toneMappingNode = Nodes.toneMapping( THREE.LinearToneMapping, 1 );
+				renderer.toneMappingNode = toneMapping( THREE.LinearToneMapping, 1 );
 				renderer.outputEncoding = THREE.sRGBEncoding;
 				container.appendChild( renderer.domElement );
 

+ 43 - 45
examples/webgpu_materials.html

@@ -27,15 +27,13 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { attribute, positionLocal, normalLocal, normalWorld, normalView, color, texture, ShaderNode, func, uv, vec3, triplanarTexture, viewportBottomLeft, MeshBasicNodeMaterial } from 'three/nodes';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
 
 			import { TeapotGeometry } from 'three/addons/geometries/TeapotGeometry.js';
 
-			import { ShaderNode, vec3, dot, triplanarTexture, viewportBottomLeft } from 'three/nodes';
-
 			import Stats from 'three/addons/libs/stats.module.js';
 
 			let stats;
@@ -67,7 +65,7 @@
 				// Grid
 
 				const helper = new THREE.GridHelper( 1000, 40, 0x303030, 0x303030 );
-				helper.material.colorNode = new Nodes.AttributeNode( 'color' );
+				helper.material.colorNode = attribute( 'color' );
 				helper.position.y = - 75;
 				scene.add( helper );
 
@@ -75,9 +73,9 @@
 
 				const textureLoader = new THREE.TextureLoader();
 
-				const texture = textureLoader.load( './textures/uv_grid_opengl.jpg' );
-				texture.wrapS = THREE.RepeatWrapping;
-				texture.wrapT = THREE.RepeatWrapping;
+				const uvTexture = textureLoader.load( './textures/uv_grid_opengl.jpg' );
+				uvTexture.wrapS = THREE.RepeatWrapping;
+				uvTexture.wrapT = THREE.RepeatWrapping;
 
 				const opacityTexture = textureLoader.load( './textures/alphaMap.jpg' );
 				opacityTexture.wrapS = THREE.RepeatWrapping;
@@ -89,43 +87,43 @@
 				//	BASIC
 				//
 
-				// PositionNode.LOCAL
-				material = new Nodes.MeshBasicNodeMaterial();
-				material.colorNode = new Nodes.PositionNode( Nodes.PositionNode.LOCAL );
+				// PositionLocal
+				material = new MeshBasicNodeMaterial();
+				material.colorNode = positionLocal;
 				materials.push( material );
 
-				// NormalNode.LOCAL
-				material = new Nodes.MeshBasicNodeMaterial();
-				material.colorNode = new Nodes.NormalNode( Nodes.NormalNode.LOCAL );
+				// NormalLocal
+				material = new MeshBasicNodeMaterial();
+				material.colorNode = normalLocal;
 				materials.push( material );
 
-				// NormalNode.WORLD
-				material = new Nodes.MeshBasicNodeMaterial();
-				material.colorNode = new Nodes.NormalNode( Nodes.NormalNode.WORLD );
+				// NormalWorld
+				material = new MeshBasicNodeMaterial();
+				material.colorNode = normalWorld;
 				materials.push( material );
 
-				// NormalNode.VIEW
-				material = new Nodes.MeshBasicNodeMaterial();
-				material.colorNode = new Nodes.NormalNode( Nodes.NormalNode.VIEW );
+				// NormalView
+				material = new MeshBasicNodeMaterial();
+				material.colorNode = normalView;
 				materials.push( material );
 
-				// TextureNode
-				material = new Nodes.MeshBasicNodeMaterial();
-				material.colorNode = new Nodes.TextureNode( texture );
+				// Texture
+				material = new MeshBasicNodeMaterial();
+				material.colorNode = texture( uvTexture );
 				materials.push( material );
 
 				// Opacity
-				material = new Nodes.MeshBasicNodeMaterial();
-				material.colorNode = new Nodes.UniformNode( new THREE.Color( 0x0099FF ) );
-				material.opacityNode = new Nodes.TextureNode( texture );
+				material = new MeshBasicNodeMaterial();
+				material.colorNode = color( 0x0099FF );
+				material.opacityNode = texture( uvTexture );
 				material.transparent = true;
 				materials.push( material );
 
 				// AlphaTest
-				material = new Nodes.MeshBasicNodeMaterial();
-				material.colorNode = new Nodes.TextureNode( texture );
-				material.opacityNode = new Nodes.TextureNode( opacityTexture );
-				material.alphaTestNode = new Nodes.UniformNode( 0.5 );
+				material = new MeshBasicNodeMaterial();
+				material.colorNode = texture( uvTexture );
+				material.opacityNode = texture( opacityTexture );
+				material.alphaTestNode = 0.5;
 				materials.push( material );
 
 				// Normal
@@ -142,29 +140,29 @@
 
 				const desaturateShaderNode = new ShaderNode( ( input ) => {
 
-					return dot( vec3( 0.299, 0.587, 0.114 ), input.color.xyz );
+					return vec3( 0.299, 0.587, 0.114 ).dot( input.color.xyz );
 
 				} );
 
-				material = new Nodes.MeshBasicNodeMaterial();
-				material.colorNode = desaturateShaderNode.call( { color: new Nodes.TextureNode( texture ) } );
+				material = new MeshBasicNodeMaterial();
+				material.colorNode = desaturateShaderNode.call( { color: texture( uvTexture ) } );
 				materials.push( material );
 
 				// Custom ShaderNode(no inputs) > Approach 2
 
 				const desaturateNoInputsShaderNode = new ShaderNode( () => {
 
-					return dot( vec3( 0.299, 0.587, 0.114 ), Nodes.texture( texture ).xyz );
+					return vec3( 0.299, 0.587, 0.114 ).dot( texture( uvTexture ).xyz );
 
 				} );
 
-				material = new Nodes.MeshBasicNodeMaterial();
+				material = new MeshBasicNodeMaterial();
 				material.colorNode = desaturateNoInputsShaderNode;
 				materials.push( material );
 
 				// Custom WGSL ( desaturate filter )
 
-				const desaturateWGSLNode = Nodes.func( `
+				const desaturateWGSLNode = func( `
 					fn desaturate( color:vec3<f32> ) -> vec3<f32> {
 
 						let lum = vec3<f32>( 0.299, 0.587, 0.114 );
@@ -174,13 +172,13 @@
 					}
 				` );
 
-				material = new Nodes.MeshBasicNodeMaterial();
-				material.colorNode = desaturateWGSLNode.call( { color: new Nodes.TextureNode( texture ) } );
+				material = new MeshBasicNodeMaterial();
+				material.colorNode = desaturateWGSLNode.call( { color: texture( uvTexture ) } );
 				materials.push( material );
 
 				// Custom WGSL ( get texture from keywords )
 
-				const getWGSLTextureSample = Nodes.func( `
+				const getWGSLTextureSample = func( `
 					fn getWGSLTextureSample( tex: texture_2d<f32>, tex_sampler: sampler, uv:vec2<f32> ) -> vec4<f32> {
 
 						return textureSample( tex, tex_sampler, uv ) * vec4<f32>( 0.0, 1.0, 0.0, 1.0 );
@@ -188,21 +186,21 @@
 					}
 				` );
 
-				const textureNode = new Nodes.TextureNode( texture );
+				const textureNode = texture( uvTexture );
 				//getWGSLTextureSample.keywords = { tex: textureNode, tex_sampler: sampler( textureNode ) };
 
-				material = new Nodes.MeshBasicNodeMaterial();
-				material.colorNode = getWGSLTextureSample.call( { tex: textureNode, tex_sampler: textureNode, uv: new Nodes.UVNode() } );
+				material = new MeshBasicNodeMaterial();
+				material.colorNode = getWGSLTextureSample.call( { tex: textureNode, tex_sampler: textureNode, uv: uv() } );
 				materials.push( material );
 
 				// Triplanar Texture Mapping
-				material = new Nodes.MeshBasicNodeMaterial();
-				material.colorNode = triplanarTexture( new Nodes.TextureNode( texture ) );
+				material = new MeshBasicNodeMaterial();
+				material.colorNode = triplanarTexture( texture( uvTexture ) );
 				materials.push( material );
 
 				// Screen Projection Texture
-				material = new Nodes.MeshBasicNodeMaterial();
-				material.colorNode = Nodes.texture( texture, viewportBottomLeft );
+				material = new MeshBasicNodeMaterial();
+				material.colorNode = texture( uvTexture, viewportBottomLeft );
 				materials.push( material );
 
 				//

+ 6 - 6
examples/webgpu_nodes_playground.html

@@ -54,7 +54,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { toneMapping, uniform, MeshBasicNodeMaterial, PointsNodeMaterial } from 'three/nodes';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
@@ -108,7 +108,7 @@
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setAnimationLoop( render );
 				renderer.outputEncoding = THREE.sRGBEncoding;
-				renderer.toneMappingNode = Nodes.toneMapping( THREE.LinearToneMapping, 1 );
+				renderer.toneMappingNode = toneMapping( THREE.LinearToneMapping, 1 );
 				document.body.appendChild( renderer.domElement );
 
 				renderer.domElement.className = 'renderer';
@@ -156,8 +156,8 @@
 				const loaderFBX = new FBXLoader();
 				loaderFBX.load( 'models/fbx/stanford-bunny.fbx', ( object ) => {
 
-					const defaultMaterial = new Nodes.MeshBasicNodeMaterial();
-					defaultMaterial.colorNode = new Nodes.UniformNode( 0 );
+					const defaultMaterial = new MeshBasicNodeMaterial();
+					defaultMaterial.colorNode = uniform( 0 );
 
 					const sphere = new THREE.Mesh( new THREE.SphereGeometry( 2, 32, 16 ), defaultMaterial );
 					sphere.name = 'Sphere';
@@ -169,8 +169,8 @@
 					box.position.set( - 5, 0, - 5 );
 					scene.add( box );
 
-					const defaultPointsMaterial = new Nodes.PointsNodeMaterial();
-					defaultPointsMaterial.colorNode = new Nodes.UniformNode( 0 );
+					const defaultPointsMaterial = new PointsNodeMaterial();
+					defaultPointsMaterial.colorNode = uniform( 0 );
 
 					const torusKnot = new THREE.Points( new THREE.TorusKnotGeometry( 1, .3, 100, 16 ), defaultPointsMaterial );
 					torusKnot.name = 'Torus Knot ( Points )';

+ 15 - 17
examples/webgpu_particles.html

@@ -26,12 +26,10 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { range, texture, mix, uv, color, positionWorld, timerLocal, attribute, SpriteNodeMaterial } from 'three/nodes';
 
 			import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
 
-			import { range, texture, mix, uv, mul, mod, rotateUV, color, max, min, div, clamp, positionWorld, invert, timerLocal } from 'three/nodes';
-
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
 
@@ -58,7 +56,7 @@
 				camera.position.set( 1300, 500, 0 );
 
 				scene = new THREE.Scene();
-				//scene.fogNode = new Nodes.FogRangeNode( Nodes.color( 0x0000ff ), Nodes.float( 1500 ), Nodes.float( 2100 )  );
+				//scene.fogNode = rangeFog( color( 0x0000ff ), 1500, 2100 );
 
 				// textures
 
@@ -72,27 +70,27 @@
 
 				const timer = timerLocal( .2, 1/*100000*/ ); // @TODO: need to work with 64-bit precision
 
-				const lifeTime = mod( mul( timer, lifeRange ), 1 );
+				const lifeTime = timer.mul( lifeRange ).mod( 1 );
 				const scaleRange = range( .3, 2 );
 				const rotateRange = range( .1, 4 );
 
-				const life = div( lifeTime, lifeRange );
+				const life = lifeTime.div( lifeRange );
 
-				const fakeLightEffect = max( .2, invert( positionWorld.y ) );
+				const fakeLightEffect = positionWorld.y.invert().max( 0.2 );
 
-				const textureNode = texture( map, rotateUV( uv(), mul( timer, rotateRange ) ) );
+				const textureNode = texture( map, uv().rotateUV( timer.mul( rotateRange ) ) );
 
-				const opacityNode = mul( textureNode.a, invert( life ) );
+				const opacityNode = textureNode.a.mul( life.invert() );
 
-				const smokeColor = mix( color( 0x2c1501 ), color( 0x222222 ), clamp( mul( positionWorld.y, 3 ) ) );
+				const smokeColor = mix( color( 0x2c1501 ), color( 0x222222 ), positionWorld.y.mul( 3 ).clamp() );
 
 				// create particles
 
-				const smokeNodeMaterial = new Nodes.SpriteNodeMaterial();
-				smokeNodeMaterial.colorNode = mul( mix( color( 0xf27d0c ), smokeColor, min( mul( life, 2.5 ), 1 ) ), fakeLightEffect );
+				const smokeNodeMaterial = new SpriteNodeMaterial();
+				smokeNodeMaterial.colorNode = mix( color( 0xf27d0c ), smokeColor, life.mul( 2.5 ).min( 1 ) ).mul( fakeLightEffect );
 				smokeNodeMaterial.opacityNode = opacityNode;
-				smokeNodeMaterial.positionNode = mul( offsetRange, lifeTime );
-				smokeNodeMaterial.scaleNode = mul( scaleRange, max( .3, lifeTime ) );
+				smokeNodeMaterial.positionNode = offsetRange.mul( lifeTime );
+				smokeNodeMaterial.scaleNode = scaleRange.mul( lifeTime.max( 0.3 ) );
 				smokeNodeMaterial.depthWrite = false;
 				smokeNodeMaterial.transparent = true;
 
@@ -104,9 +102,9 @@
 
 				//
 
-				const fireNodeMaterial = new Nodes.SpriteNodeMaterial();
+				const fireNodeMaterial = new SpriteNodeMaterial();
 				fireNodeMaterial.colorNode = mix( color( 0xb72f17 ), color( 0xb72f17 ), life );
-				fireNodeMaterial.positionNode = mul( range( new THREE.Vector3( - 1, 1, - 1 ), new THREE.Vector3( 1, 2, 1 ) ), lifeTime );
+				fireNodeMaterial.positionNode = range( new THREE.Vector3( - 1, 1, - 1 ), new THREE.Vector3( 1, 2, 1 ) ).mul( lifeTime );
 				fireNodeMaterial.scaleNode = smokeNodeMaterial.scaleNode;
 				fireNodeMaterial.opacityNode = opacityNode;
 				fireNodeMaterial.blending = THREE.AdditiveBlending;
@@ -124,7 +122,7 @@
 				//
 
 				const helper = new THREE.GridHelper( 3000, 40, 0x303030, 0x303030 );
-				helper.material.colorNode = new Nodes.AttributeNode( 'color' );
+				helper.material.colorNode = attribute( 'color' );
 				helper.position.y = - 75;
 				scene.add( helper );
 

+ 7 - 7
examples/webgpu_rtt.html

@@ -26,7 +26,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { texture, uniform, vec2, MeshBasicNodeMaterial } from 'three/nodes';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
@@ -63,11 +63,11 @@
 				// textured mesh
 
 				const loader = new THREE.TextureLoader();
-				const texture = loader.load( './textures/uv_grid_opengl.jpg' );
+				const uvTexture = loader.load( './textures/uv_grid_opengl.jpg' );
 
 				const geometryBox = new THREE.BoxGeometry();
-				const materialBox = new Nodes.MeshBasicNodeMaterial();
-				materialBox.colorNode = new Nodes.TextureNode( texture );
+				const materialBox = new MeshBasicNodeMaterial();
+				materialBox.colorNode = texture( uvTexture );
 
 				//
 
@@ -96,10 +96,10 @@
 
 				// modulate the final color based on the mouse position
 
-				const screenFXNode = new Nodes.OperatorNode( '+', new Nodes.UniformNode( mouse ), new Nodes.ConstNode( new THREE.Vector2( 0.5, 0.5 ) ) );
+				const screenFXNode = uniform( mouse ).add( vec2( 0.5, 0.5 ) );
 
-				const materialFX = new Nodes.MeshBasicNodeMaterial();
-				materialFX.colorNode = new Nodes.OperatorNode( '*', new Nodes.TextureNode( textureRenderer.getTexture() ), screenFXNode );
+				const materialFX = new MeshBasicNodeMaterial();
+				materialFX.colorNode = texture( textureRenderer.getTexture() ).mul( screenFXNode );
 
 				const quad = new THREE.Mesh( geometryFX, materialFX );
 				sceneFX.add( quad );

+ 26 - 29
examples/webgpu_sandbox.html

@@ -26,7 +26,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { timerLocal, vec2, uv, texture, mix, checker, normalLocal, positionLocal, color, oscSine, attribute, MeshBasicNodeMaterial, PointsNodeMaterial, LineBasicNodeMaterial } from 'three/nodes';
 
 			import { DDSLoader } from 'three/addons/loaders/DDSLoader.js';
 
@@ -58,10 +58,10 @@
 				// textures
 
 				const textureLoader = new THREE.TextureLoader();
-				const texture = textureLoader.load( './textures/uv_grid_opengl.jpg' );
-				texture.wrapS = THREE.RepeatWrapping;
-				texture.wrapT = THREE.RepeatWrapping;
-				texture.name = 'uv_grid';
+				const uvTexture = textureLoader.load( './textures/uv_grid_opengl.jpg' );
+				uvTexture.wrapS = THREE.RepeatWrapping;
+				uvTexture.wrapT = THREE.RepeatWrapping;
+				uvTexture.name = 'uv_grid';
 
 				const textureDisplace = textureLoader.load( './textures/transition/transition1.png' );
 				textureDisplace.wrapS = THREE.RepeatWrapping;
@@ -75,21 +75,19 @@
 				// box mesh
 
 				const geometryBox = new THREE.BoxGeometry();
-				const materialBox = new Nodes.MeshBasicNodeMaterial();
-
-				const timerNode = new Nodes.TimerNode();
+				const materialBox = new MeshBasicNodeMaterial();
 
 				// birection speed
-				const timerScaleNode = new Nodes.OperatorNode( '*', timerNode, new Nodes.ConstNode( new THREE.Vector2( - 0.5, 0.1 ) ) );
-				const animateUV = new Nodes.OperatorNode( '+', new Nodes.UVNode(), timerScaleNode );
+				const timerScaleNode = timerLocal().mul( vec2( - 0.5, 0.1 ) );
+				const animateUV = uv().add( timerScaleNode );
 
-				const textureNode = new Nodes.TextureNode( texture, animateUV );
+				const textureNode = texture( uvTexture, animateUV );
 
-				materialBox.colorNode = new Nodes.MathNode( 'mix', textureNode, new Nodes.CheckerNode( animateUV ), new Nodes.UniformNode( .5 ) );
+				materialBox.colorNode = mix( textureNode, checker( animateUV ), 0.5 );
 
 				// test uv 2
 				//geometryBox.setAttribute( 'uv2', geometryBox.getAttribute( 'uv' ) );
-				//materialBox.colorNode = new TextureNode( texture, new UVNode( 1 ) );
+				//materialBox.colorNode = texture( uvTexture, uv( 1 ) );
 
 				box = new THREE.Mesh( geometryBox, materialBox );
 				box.position.set( 0, 1, 0 );
@@ -98,15 +96,14 @@
 				// displace example
 
 				const geometrySphere = new THREE.SphereGeometry( .5, 64, 64 );
-				const materialSphere = new Nodes.MeshBasicNodeMaterial();
+				const materialSphere = new MeshBasicNodeMaterial();
 
-				const displaceAnimated = new Nodes.SplitNode( new Nodes.TextureNode( textureDisplace ), 'x' );
-				const displaceY = new Nodes.OperatorNode( '*', displaceAnimated, new Nodes.ConstNode( .25 ) );
+				const displaceY = texture( textureDisplace ).x.mul( 0.25 );
 
-				const displace = new Nodes.OperatorNode( '*', new Nodes.NormalNode( Nodes.NormalNode.LOCAL ), displaceY );
+				const displace = normalLocal.mul( displaceY );
 
 				materialSphere.colorNode = displaceY;
-				materialSphere.positionNode = new Nodes.OperatorNode( '+', new Nodes.PositionNode( Nodes.PositionNode.LOCAL ), displace );
+				materialSphere.positionNode = positionLocal.add( displace );
 
 				const sphere = new THREE.Mesh( geometrySphere, materialSphere );
 				sphere.position.set( - 2, - 1, 0 );
@@ -115,9 +112,9 @@
 				// data texture
 
 				const geometryPlane = new THREE.PlaneGeometry();
-				const materialPlane = new Nodes.MeshBasicNodeMaterial();
-				materialPlane.colorNode = new Nodes.OperatorNode( '+', new Nodes.TextureNode( createDataTexture() ), new Nodes.UniformNode( new THREE.Color( 0x0000FF ) ) );
-				materialPlane.opacityNode = new Nodes.SplitNode( new Nodes.TextureNode( dxt5Texture ), 'a' );
+				const materialPlane = new MeshBasicNodeMaterial();
+				materialPlane.colorNode = texture( createDataTexture() ).add( color( 0x0000FF ) );
+				materialPlane.opacityNode = texture( dxt5Texture ).a;
 				materialPlane.transparent = true;
 
 				const plane = new THREE.Mesh( geometryPlane, materialPlane );
@@ -126,10 +123,10 @@
 
 				// compressed texture
 
-				const materialCompressed = new Nodes.MeshBasicNodeMaterial();
-				materialCompressed.colorNode = new Nodes.TextureNode( dxt5Texture );
-				materialCompressed.emissiveNode = new Nodes.UniformNode( new THREE.Color( 0x663300 ) );
-				materialCompressed.alphaTestNode = new Nodes.OscNode();
+				const materialCompressed = new MeshBasicNodeMaterial();
+				materialCompressed.colorNode = texture( dxt5Texture );
+				materialCompressed.emissiveNode = color( 0x663300 );
+				materialCompressed.alphaTestNode = oscSine();
 				materialCompressed.transparent = true;
 
 				const boxCompressed = new THREE.Mesh( geometryBox, materialCompressed );
@@ -148,9 +145,9 @@
 				}
 
 				const geometryPoints = new THREE.BufferGeometry().setFromPoints( points );
-				const materialPoints = new Nodes.PointsNodeMaterial();
+				const materialPoints = new PointsNodeMaterial();
 
-				materialPoints.colorNode = new Nodes.OperatorNode( '*', new Nodes.PositionNode(), new Nodes.ConstNode( 3 ) );
+				materialPoints.colorNode = positionLocal.mul( 3 );
 
 				const pointCloud = new THREE.Points( geometryPoints, materialPoints );
 				pointCloud.position.set( 2, - 1, 0 );
@@ -167,8 +164,8 @@
 
 				geometryLine.setAttribute( 'color', geometryLine.getAttribute( 'position' ) );
 
-				const materialLine = new Nodes.LineBasicNodeMaterial();
-				materialLine.colorNode = new Nodes.AttributeNode( 'color' );
+				const materialLine = new LineBasicNodeMaterial();
+				materialLine.colorNode = attribute( 'color' );
 
 				const line = new THREE.Line( geometryLine, materialLine );
 				line.position.set( 2, 1, 0 );

+ 3 - 3
examples/webgpu_skinning.html

@@ -27,7 +27,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { toneMapping, MeshStandardNodeMaterial } from 'three/nodes';
 
 			import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';
 
@@ -79,7 +79,7 @@
 
 						if ( child.isMesh ) {
 
-							child.material = new Nodes.MeshStandardNodeMaterial();
+							child.material = new MeshStandardNodeMaterial();
 							child.material.roughness = .1;
 
 						}
@@ -97,7 +97,7 @@
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.setAnimationLoop( animate );
 				renderer.outputEncoding = THREE.sRGBEncoding;
-				renderer.toneMappingNode = Nodes.toneMapping( THREE.LinearToneMapping, .15 );
+				renderer.toneMappingNode = toneMapping( THREE.LinearToneMapping, .15 );
 				document.body.appendChild( renderer.domElement );
 
 				window.addEventListener( 'resize', onWindowResize );

+ 2 - 4
examples/webgpu_skinning_instancing.html

@@ -27,9 +27,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
-
-			import { mix, range, color, oscSine, timerLocal, toneMapping } from 'three/nodes';
+			import { mix, range, color, oscSine, timerLocal, toneMapping, MeshStandardNodeMaterial } from 'three/nodes';
 
 			import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';
 
@@ -98,7 +96,7 @@
 							// random [ 0, 1 ] values between instances
 							const randomMetalness = range( 0, 1 );
 
-							child.material = new Nodes.MeshStandardNodeMaterial();
+							child.material = new MeshStandardNodeMaterial();
 							child.material.roughness = .1;
 							child.material.metalnessNode = mix( 0.0, randomMetalness, oscNode );
 							child.material.colorNode = mix( color( 0xFFFFFF ), randomColors, oscNode );

+ 4 - 4
examples/webgpu_skinning_points.html

@@ -27,7 +27,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
+			import { uniform, skinning, PointsNodeMaterial } from 'three/nodes';
 
 			import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';
 
@@ -72,9 +72,9 @@
 
 							child.visible = false;
 
-							const materialPoints = new Nodes.PointsNodeMaterial();
-							materialPoints.colorNode = new Nodes.UniformNode( new THREE.Color() );
-							materialPoints.positionNode = new Nodes.SkinningNode( child );
+							const materialPoints = new PointsNodeMaterial();
+							materialPoints.colorNode = uniform( new THREE.Color() );
+							materialPoints.positionNode = skinning( child );
 
 							const pointCloud = new THREE.Points( child.geometry, materialPoints );
 							scene.add( pointCloud );

+ 4 - 6
examples/webgpu_sprites.html

@@ -26,9 +26,7 @@
 		<script type="module">
 
 			import * as THREE from 'three';
-			import * as Nodes from 'three/nodes';
-
-			import { texture, uv, mul, float, color, userData } from 'three/nodes';
+			import { texture, uv, userData, rangeFog, color, SpriteNodeMaterial } from 'three/nodes';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
@@ -60,7 +58,7 @@
 				camera.position.z = 1500;
 
 				scene = new THREE.Scene();
-				scene.fogNode = new Nodes.FogRangeNode( color( 0x0000ff ), float( 1500 ), float( 2100 ) );
+				scene.fogNode = rangeFog( color( 0x0000ff ), 1500, 2100 );
 
 				// create sprites
 
@@ -80,8 +78,8 @@
 
 				const textureNode = texture( map );
 
-				const material = new Nodes.SpriteNodeMaterial();
-				material.colorNode = mul( textureNode, mul( uv(), 2 ) );
+				const material = new SpriteNodeMaterial();
+				material.colorNode = textureNode.mul( uv() ).mul( 2 );
 				material.opacityNode = textureNode.a;
 				material.rotationNode = userData( 'rotation', 'float' ); // get value of: sprite.userData.rotation
 				material.transparent = true;