Selaa lähdekoodia

Examples: Small changes to Procedural Wood Example (#31786)

* Replaced grainPosition and grainRotation with transformation matrix. Added GUI to modify custom wood

* Improved contrast of white text
Logan Seeley 7 kuukautta sitten
vanhempi
sitoutus
28b0bf1b1b
2 muutettua tiedostoa jossa 81 lisäystä ja 57 poistoa
  1. 32 43
      examples/jsm/materials/WoodNodeMaterial.js
  2. 49 14
      examples/webgpu_tsl_wood.html

+ 32 - 43
examples/jsm/materials/WoodNodeMaterial.js

@@ -227,9 +227,9 @@ const spaceWarp = TSL.Fn( ( [ p, warpStrength, xyScale, zScale ] ) => {
 
 } );
 
-const woodRings = TSL.Fn( ( [ w, ringCount, ringBias, ringSizeVariance, ringVarianceScale, barkThickness ] ) => {
+const woodRings = TSL.Fn( ( [ w, ringThickness, ringBias, ringSizeVariance, ringVarianceScale, barkThickness ] ) => {
 
-	const rings = noiseFbm( w.mul( ringVarianceScale ), TSL.float( 1 ), TSL.float( 0.5 ), TSL.float( 1 ), TSL.int( 1 ) ).mul( ringSizeVariance ).add( w ).mul( ringCount ).fract().mul( barkThickness );
+	const rings = noiseFbm( w.mul( ringVarianceScale ), TSL.float( 1 ), TSL.float( 0.5 ), TSL.float( 1 ), TSL.int( 1 ) ).mul( ringSizeVariance ).add( w ).mul( ringThickness ).fract().mul( barkThickness );
 
 	const sharpRings = TSL.min( mapRange( rings, 0, ringBias, 0, 1, TSL.bool( true ) ), mapRange( rings, ringBias, 1, 1, 0, TSL.bool( true ) ) );
 
@@ -268,7 +268,7 @@ const wood = TSL.Fn( ( [
 	smallWarpScale,
 	fineWarpStrength,
 	fineWarpScale,
-	ringCount,
+	ringThickness,
 	ringBias,
 	ringSizeVariance,
 	ringVarianceScale,
@@ -284,7 +284,7 @@ const wood = TSL.Fn( ( [
 	const center = woodCenter( p, centerSize );
 	const mainWarp = spaceWarp( spaceWarp( p, center, largeWarpScale, largeGrainStretch ), smallWarpStrength, smallWarpScale, 0.17 );
 	const detailWarp = spaceWarp( mainWarp, fineWarpStrength, fineWarpScale, 0.17 );
-	const rings = woodRings( detailWarp.length(), ringCount, ringBias, ringSizeVariance, ringVarianceScale, barkThickness );
+	const rings = woodRings( detailWarp.length(), TSL.float( 1 ).div( ringThickness ), ringBias, ringSizeVariance, ringVarianceScale, barkThickness );
 	const detail = woodDetail( detailWarp, p, detailWarp.length(), splotchScale );
 	const cells = cellStructure( mainWarp, cellScale, cellSize.div( TSL.max( TSL.positionView.length().mul( 10 ), 1 ) ) );
 	const baseColor = TSL.mix( darkGrainColor, lightGrainColor, rings );
@@ -295,91 +295,81 @@ const wood = TSL.Fn( ( [
 
 const woodParams = {
 	teak: {
-		grainPosition: { x: - 0.4, y: 0, z: 0 },
-		grainRotation: { x: 0, y: 0, z: 0 },
+		transformationMatrix: new THREE.Matrix4().identity(),
 		centerSize: 1.11, largeWarpScale: 0.32, largeGrainStretch: 0.24, smallWarpStrength: 0.059,
-		smallWarpScale: 2, fineWarpStrength: 0.006, fineWarpScale: 32.8, ringCount: 34,
+		smallWarpScale: 2, fineWarpStrength: 0.006, fineWarpScale: 32.8, ringThickness: 1/34,
 		ringBias: 0.03, ringSizeVariance: 0.03, ringVarianceScale: 4.4, barkThickness: 0.3,
 		splotchScale: 0.2, splotchIntensity: 0.541, cellScale: 910, cellSize: 0.1,
 		darkGrainColor: '#0c0504', lightGrainColor: '#926c50'
 	},
 	walnut: {
-		grainPosition: { x: - 0.4, y: 0, z: 0 },
-		grainRotation: { x: 0, y: 0, z: 0 },
+		transformationMatrix: new THREE.Matrix4().identity(),
 		centerSize: 1.07, largeWarpScale: 0.42, largeGrainStretch: 0.34, smallWarpStrength: 0.016,
-		smallWarpScale: 10.3, fineWarpStrength: 0.028, fineWarpScale: 12.7, ringCount: 32,
+		smallWarpScale: 10.3, fineWarpStrength: 0.028, fineWarpScale: 12.7, ringThickness: 1/32,
 		ringBias: 0.08, ringSizeVariance: 0.03, ringVarianceScale: 5.5, barkThickness: 0.98,
 		splotchScale: 1.84, splotchIntensity: 0.97, cellScale: 710, cellSize: 0.31,
 		darkGrainColor: '#311e13', lightGrainColor: '#523424'
 	},
 	white_oak: {
-		grainPosition: { x: - 0.4, y: 0, z: 0 },
-		grainRotation: { x: 0, y: 0, z: 0 },
+		transformationMatrix: new THREE.Matrix4().identity(),
 		centerSize: 1.23, largeWarpScale: 0.21, largeGrainStretch: 0.21, smallWarpStrength: 0.034,
-		smallWarpScale: 2.44, fineWarpStrength: 0.01, fineWarpScale: 14.3, ringCount: 34,
+		smallWarpScale: 2.44, fineWarpStrength: 0.01, fineWarpScale: 14.3, ringThickness: 1/34,
 		ringBias: 0.82, ringSizeVariance: 0.16, ringVarianceScale: 1.4, barkThickness: 0.7,
 		splotchScale: 0.2, splotchIntensity: 0.541, cellScale: 800, cellSize: 0.28,
 		darkGrainColor: '#8b4c21', lightGrainColor: '#c57e43'
 	},
 	pine: {
-		grainPosition: { x: - 0.4, y: 0, z: - 0.2 },
-		grainRotation: { x: 0, y: 0, z: 0 },
+		transformationMatrix: new THREE.Matrix4().identity(),
 		centerSize: 1.23, largeWarpScale: 0.21, largeGrainStretch: 0.18, smallWarpStrength: 0.041,
-		smallWarpScale: 2.44, fineWarpStrength: 0.006, fineWarpScale: 23.2, ringCount: 24,
+		smallWarpScale: 2.44, fineWarpStrength: 0.006, fineWarpScale: 23.2, ringThickness: 1/24,
 		ringBias: 0.1, ringSizeVariance: 0.07, ringVarianceScale: 5, barkThickness: 0.35,
 		splotchScale: 0.51, splotchIntensity: 3.32, cellScale: 1480, cellSize: 0.07,
 		darkGrainColor: '#c58355', lightGrainColor: '#d19d61'
 	},
 	poplar: {
-		grainPosition: { x: - 0.4, y: 0, z: 0.2 },
-		grainRotation: { x: 0, y: 0, z: 0 },
+		transformationMatrix: new THREE.Matrix4().identity(),
 		centerSize: 1.43, largeWarpScale: 0.33, largeGrainStretch: 0.18, smallWarpStrength: 0.04,
-		smallWarpScale: 4.3, fineWarpStrength: 0.004, fineWarpScale: 33.6, ringCount: 37,
+		smallWarpScale: 4.3, fineWarpStrength: 0.004, fineWarpScale: 33.6, ringThickness: 1/37,
 		ringBias: 0.07, ringSizeVariance: 0.03, ringVarianceScale: 3.8, barkThickness: 0.3,
 		splotchScale: 1.92, splotchIntensity: 0.71, cellScale: 830, cellSize: 0.04,
 		darkGrainColor: '#716347', lightGrainColor: '#998966'
 	},
 	maple: {
-		grainPosition: { x: - 0.4, y: 0.3, z: - 0.2 },
-		grainRotation: { x: 0, y: 0, z: 0 },
+		transformationMatrix: new THREE.Matrix4().identity(),
 		centerSize: 1.4, largeWarpScale: 0.38, largeGrainStretch: 0.25, smallWarpStrength: 0.067,
-		smallWarpScale: 2.5, fineWarpStrength: 0.005, fineWarpScale: 33.6, ringCount: 35,
+		smallWarpScale: 2.5, fineWarpStrength: 0.005, fineWarpScale: 33.6, ringThickness: 1/35,
 		ringBias: 0.1, ringSizeVariance: 0.07, ringVarianceScale: 4.6, barkThickness: 0.61,
 		splotchScale: 0.46, splotchIntensity: 1.49, cellScale: 800, cellSize: 0.03,
 		darkGrainColor: '#b08969', lightGrainColor: '#bc9d7d'
 	},
 	red_oak: {
-		grainPosition: { x: - 0.4, y: 0, z: 0.4 },
-		grainRotation: { x: 0, y: 0, z: 0 },
+		transformationMatrix: new THREE.Matrix4().identity(),
 		centerSize: 1.21, largeWarpScale: 0.24, largeGrainStretch: 0.25, smallWarpStrength: 0.044,
-		smallWarpScale: 2.54, fineWarpStrength: 0.01, fineWarpScale: 14.5, ringCount: 34,
+		smallWarpScale: 2.54, fineWarpStrength: 0.01, fineWarpScale: 14.5, ringThickness: 1/34,
 		ringBias: 0.92, ringSizeVariance: 0.03, ringVarianceScale: 5.6, barkThickness: 1.01,
 		splotchScale: 0.28, splotchIntensity: 3.48, cellScale: 800, cellSize: 0.25,
 		darkGrainColor: '#af613b', lightGrainColor: '#e0a27a'
 	},
 	cherry: {
-		grainPosition: { x: - 0.4, y: 0.3, z: 0 },
-		grainRotation: { x: 0, y: 0, z: 0 },
+		transformationMatrix: new THREE.Matrix4().identity(),
 		centerSize: 1.33, largeWarpScale: 0.11, largeGrainStretch: 0.33, smallWarpStrength: 0.024,
-		smallWarpScale: 2.48, fineWarpStrength: 0.01, fineWarpScale: 15.3, ringCount: 36,
+		smallWarpScale: 2.48, fineWarpStrength: 0.01, fineWarpScale: 15.3, ringThickness: 1/36,
 		ringBias: 0.02, ringSizeVariance: 0.04, ringVarianceScale: 6.5, barkThickness: 0.09,
 		splotchScale: 1.27, splotchIntensity: 1.24, cellScale: 1530, cellSize: 0.15,
 		darkGrainColor: '#913f27', lightGrainColor: '#b45837'
 	},
 	cedar: {
-		grainPosition: { x: - 0.4, y: 0.1, z: 0.1 },
-		grainRotation: { x: 0, y: 0, z: 0 },
+		transformationMatrix: new THREE.Matrix4().identity(),
 		centerSize: 1.11, largeWarpScale: 0.39, largeGrainStretch: 0.12, smallWarpStrength: 0.061,
-		smallWarpScale: 1.9, fineWarpStrength: 0.006, fineWarpScale: 4.8, ringCount: 25,
+		smallWarpScale: 1.9, fineWarpStrength: 0.006, fineWarpScale: 4.8, ringThickness: 1/25,
 		ringBias: 0.01, ringSizeVariance: 0.07, ringVarianceScale: 6.7, barkThickness: 0.1,
 		splotchScale: 0.61, splotchIntensity: 2.54, cellScale: 630, cellSize: 0.19,
 		darkGrainColor: '#9a5b49', lightGrainColor: '#ae745e'
 	},
 	mahogany: {
-		grainPosition: { x: - 0.4, y: 0.2, z: 0 },
-		grainRotation: { x: 0, y: 0, z: 0 },
+		transformationMatrix: new THREE.Matrix4().identity(),
 		centerSize: 1.25, largeWarpScale: 0.26, largeGrainStretch: 0.29, smallWarpStrength: 0.044,
-		smallWarpScale: 2.54, fineWarpStrength: 0.01, fineWarpScale: 15.3, ringCount: 38,
+		smallWarpScale: 2.54, fineWarpStrength: 0.01, fineWarpScale: 15.3, ringThickness: 1/38,
 		ringBias: 0.01, ringSizeVariance: 0.33, ringVarianceScale: 1.2, barkThickness: 0.07,
 		splotchScale: 0.77, splotchIntensity: 1.39, cellScale: 1400, cellSize: 0.23,
 		darkGrainColor: '#501d12', lightGrainColor: '#6d3722'
@@ -415,7 +405,7 @@ export function GetWoodPreset( genus, finish ) {
 
 	}
 
-	return { ...params, grainPosition: new THREE.Vector3().copy( params.grainPosition ), grainRotation: new THREE.Vector3().copy( params.grainRotation ), genus, finish, clearcoat, clearcoatRoughness, clearcoatDarken };
+	return { ...params, transformationMatrix: new THREE.Matrix4().copy( params.transformationMatrix ), genus, finish, clearcoat, clearcoatRoughness, clearcoatDarken };
 
 }
 
@@ -429,7 +419,7 @@ uniforms.smallWarpStrength = TSL.uniform( params.smallWarpStrength ).onObjectUpd
 uniforms.smallWarpScale = TSL.uniform( params.smallWarpScale ).onObjectUpdate( ( { material } ) => material.smallWarpScale );
 uniforms.fineWarpStrength = TSL.uniform( params.fineWarpStrength ).onObjectUpdate( ( { material } ) => material.fineWarpStrength );
 uniforms.fineWarpScale = TSL.uniform( params.fineWarpScale ).onObjectUpdate( ( { material } ) => material.fineWarpScale );
-uniforms.ringCount = TSL.uniform( params.ringCount ).onObjectUpdate( ( { material } ) => material.ringCount );
+uniforms.ringThickness = TSL.uniform( params.ringThickness ).onObjectUpdate( ( { material } ) => material.ringThickness );
 uniforms.ringBias = TSL.uniform( params.ringBias ).onObjectUpdate( ( { material } ) => material.ringBias );
 uniforms.ringSizeVariance = TSL.uniform( params.ringSizeVariance ).onObjectUpdate( ( { material } ) => material.ringSizeVariance );
 uniforms.ringVarianceScale = TSL.uniform( params.ringVarianceScale ).onObjectUpdate( ( { material } ) => material.ringVarianceScale );
@@ -440,11 +430,10 @@ uniforms.cellScale = TSL.uniform( params.cellScale ).onObjectUpdate( ( { materia
 uniforms.cellSize = TSL.uniform( params.cellSize ).onObjectUpdate( ( { material } ) => material.cellSize );
 uniforms.darkGrainColor = TSL.uniform( new THREE.Color( params.darkGrainColor ) ).onObjectUpdate( ( { material }, self ) => self.value.set( material.darkGrainColor ) );
 uniforms.lightGrainColor = TSL.uniform( new THREE.Color( params.lightGrainColor ) ).onObjectUpdate( ( { material }, self ) => self.value.set( material.lightGrainColor ) );
-uniforms.grainPosition = TSL.uniform( new THREE.Vector3().copy( params.grainPosition ) ).onObjectUpdate( ( { material } ) => material.grainPosition );
-uniforms.grainRotation = TSL.uniform( new THREE.Vector3().copy( params.grainRotation ) ).onObjectUpdate( ( { material } ) => material.grainRotation );
+uniforms.transformationMatrix = TSL.uniform( new THREE.Matrix4().copy( params.transformationMatrix ) ).onObjectUpdate( ( { material } ) => material.transformationMatrix );
 
 const colorNode = wood(
-	TSL.rotate( TSL.positionLocal.add( uniforms.grainPosition ), uniforms.grainRotation ),
+	uniforms.transformationMatrix.mul( TSL.vec4(TSL.positionLocal, 1) ).xyz,
 	uniforms.centerSize,
 	uniforms.largeWarpScale,
 	uniforms.largeGrainStretch,
@@ -452,7 +441,7 @@ const colorNode = wood(
 	uniforms.smallWarpScale,
 	uniforms.fineWarpStrength,
 	uniforms.fineWarpScale,
-	uniforms.ringCount,
+	uniforms.ringThickness,
 	uniforms.ringBias,
 	uniforms.ringSizeVariance,
 	uniforms.ringVarianceScale,
@@ -476,7 +465,7 @@ const colorNode = wood(
  * // Using custom parameters (for advanced customization)
  * const material = new WoodNodeMaterial({
  *   centerSize: 1.2,
- *   ringCount: 40,
+ *   ringThickness: 1/40,
  *   darkGrainColor: new THREE.Color('#2a1a0a'),
  *   lightGrainColor: new THREE.Color('#8b4513'),
  *   clearcoat: 1,
@@ -487,11 +476,11 @@ const colorNode = wood(
  * const walnutParams = GetWoodPreset('walnut', 'raw');
  * const material = new WoodNodeMaterial({
  *   ...walnutParams,
- *   ringCount: 50,  // Override specific parameter
+ *   ringThickness: 1/50,  // Override specific parameter
  *   clearcoat: 1    // Add finish
  * });
  */
-export class WoodNodeMaterial extends THREE.MeshPhysicalNodeMaterial {
+export class WoodNodeMaterial extends THREE.MeshPhysicalMaterial {
 
 	static get type() {
 

+ 49 - 14
examples/webgpu_tsl_wood.html

@@ -9,7 +9,7 @@
 		<style>
 
 			body {
-				color:white;
+				color:rgb(55, 55, 55);
 			}
 
 			#info a {
@@ -45,10 +45,11 @@
 			import { HDRLoader } from 'three/addons/loaders/HDRLoader.js';
 			import { FontLoader } from 'three/addons/loaders/FontLoader.js';
 			import { TextGeometry } from 'three/addons/geometries/TextGeometry.js';
+			import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
 			import { RoundedBoxGeometry } from 'three/addons/geometries/RoundedBoxGeometry.js';
 			import { WoodNodeMaterial, WoodGenuses, Finishes } from 'three/addons/materials/WoodNodeMaterial.js';
 
-			let scene, base, camera, renderer, controls, stats, font, blockGeometry;
+			let scene, base, camera, renderer, controls, stats, font, blockGeometry, gui;
 
 			// Helper function to get grid position
 			function getGridPosition( woodIndex, finishIndex ) {
@@ -163,6 +164,8 @@
 
 				stats = new Stats();
 				document.body.appendChild( stats.dom );
+
+				gui = new GUI();
 			
 				font = await new FontLoader().loadAsync( './fonts/helvetiker_regular.typeface.json' );
 
@@ -213,7 +216,9 @@
 
 						const material = WoodNodeMaterial.fromPreset( WoodGenuses[ x ], Finishes[ y ] );
 						const cube = new THREE.Mesh( blockGeometry, material );
+
 						cube.position.copy( getGridPosition( x, y ) );
+						material.transformationMatrix = new THREE.Matrix4().setPosition( new THREE.Vector3( -0.1, 0, Math.random() ) );
 						base.add( cube );
 
 						await new Promise( resolve => setTimeout( resolve, 0 ) );
@@ -222,7 +227,7 @@
 
 				}
 
-				 add_custom_wood( text_mat );
+				add_custom_wood( text_mat );
 
 			}
 
@@ -262,22 +267,52 @@
 
 				// Create custom wood material with unique parameters
 				const customMaterial = new WoodNodeMaterial( {
-					centerSize: 1.8,
-					largeWarpScale: 0.5,
-					ringCount: 45,
-					ringBias: 0.15,
-					barkThickness: 0.8,
-					splotchScale: 2.5,
-					splotchIntensity: 1.8,
-					cellScale: 1200,
-					cellSize: 0.05,
-					darkGrainColor: new THREE.Color( '#0a0a0a' ),
-					lightGrainColor: new THREE.Color( '#8b4513' ),
+					centerSize: 1.11,
+					largeWarpScale: 0.32,
+					largeGrainStretch: 0.24,
+					smallWarpStrength: 0.059,
+					smallWarpScale: 2,
+					fineWarpStrength: 0.006,
+					fineWarpScale: 32.8,
+					ringThickness: 1/34,
+					ringBias: 0.03,
+					ringSizeVariance: 0.03,
+					ringVarianceScale: 4.4,
+					barkThickness: 0.3,
+					splotchScale: 0.2,
+					splotchIntensity: 0.541,
+					cellScale: 910,
+					cellSize: 0.1,
+					darkGrainColor: new THREE.Color( '#0c0504') ,
+					lightGrainColor: new THREE.Color( '#926c50' ),
 					clearcoat: 1,
 					clearcoatRoughness: 0.2
 				} );
 
+				gui.add( customMaterial, 'centerSize', 0.0, 2.0, 0.01 ).name( 'centerSize' );
+				gui.add( customMaterial, 'largeWarpScale', 0.0, 1.0, 0.001 ).name( 'largeWarpScale' );
+				gui.add( customMaterial, 'largeGrainStretch', 0.0, 1.0, 0.001 ).name( 'largeGrainStretch' );
+				gui.add( customMaterial, 'smallWarpStrength', 0.0, 0.2, 0.001 ).name( 'smallWarpStrength' );
+				gui.add( customMaterial, 'smallWarpScale', 0.0, 5.0, 0.01 ).name( 'smallWarpScale' );
+				gui.add( customMaterial, 'fineWarpStrength', 0.0, 0.05, 0.001 ).name( 'fineWarpStrength' );
+				gui.add( customMaterial, 'fineWarpScale', 0.0, 50.0, 0.1 ).name( 'fineWarpScale' );
+				gui.add( customMaterial, 'ringThickness', 0.0, 0.1, 0.001 ).name( 'ringThickness' );
+				gui.add( customMaterial, 'ringBias', -0.2, 0.2, 0.001 ).name( 'ringBias' );
+				gui.add( customMaterial, 'ringSizeVariance', 0.0, 0.2, 0.001 ).name( 'ringSizeVariance' );
+				gui.add( customMaterial, 'ringVarianceScale', 0.0, 10.0, 0.1 ).name( 'ringVarianceScale' );
+				gui.add( customMaterial, 'barkThickness', 0.0, 1.0, 0.01 ).name( 'barkThickness' );
+				gui.add( customMaterial, 'splotchScale', 0.0, 1.0, 0.01 ).name( 'splotchScale' );
+				gui.add( customMaterial, 'splotchIntensity', 0.0, 1.0, 0.01 ).name( 'splotchIntensity' );
+				gui.add( customMaterial, 'cellScale', 100, 2000, 1 ).name( 'cellScale' );
+				gui.add( customMaterial, 'cellSize', 0.01, 0.5, 0.001 ).name( 'cellSize' );
+				gui.addColor( { darkGrainColor: '#0c0504' }, 'darkGrainColor' ).onChange( v => customMaterial.darkGrainColor.set( v ) );
+				gui.addColor( { lightGrainColor: '#926c50' }, 'lightGrainColor' ).onChange( v => customMaterial.lightGrainColor.set( v ) );
+				gui.add( customMaterial, 'clearcoat', 0.0, 1.0, 0.01 ).name( 'clearcoat' );
+				gui.add( customMaterial, 'clearcoatRoughness', 0.0, 1.0, 0.01 ).name( 'clearcoatRoughness' );
+
 				const cube = new THREE.Mesh( blockGeometry, customMaterial );
+
+				customMaterial.transformationMatrix = new THREE.Matrix4().setPosition( new THREE.Vector3( -0.1, 0, Math.random() ) );
 				cube.position.copy( getGridPosition( Math.round( WoodGenuses.length / 2 ), 5 ) );
 
 				base.add( cube );

粤ICP备19079148号