Explorar o código

Improved MaterialX example (#31541)

* Improved MaterialX example.

* Potential fix for code scanning alert no. 3610: Unused variable, import, function or class

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>

* MaterialXLoader: Set transparent/side when opacityNode and transmissionNode is not null.

* Improved example.

* MaterialXLoader: Simplified auto-enable transparency code.

* Clean up.

* Fix transparent materials.

---------

Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
mrdoob hai 5 meses
pai
achega
a0daeb5b9f

+ 3 - 8
examples/jsm/loaders/MaterialXLoader.js

@@ -893,21 +893,16 @@ class MaterialXNode {
 
 		}
 
-		// Auto-enable transparency when opacity or transmission is non-default
-		const hasNonDefaultOpacity = opacityNode && opacityNode.value !== undefined && opacityNode.value < 1.0;
-		const hasTransmission = transmissionNode && transmissionNode.value !== undefined && transmissionNode.value > 0;
-
-		if ( hasNonDefaultOpacity ) {
+		if ( opacityNode !== null ) {
 
 			material.transparent = true;
 
 		}
 
-		// Set material properties for transmission
-		if ( hasTransmission ) {
+		if ( transmissionNode !== null ) {
 
-			material.transparent = true;
 			material.side = DoubleSide;
+			material.transparent = true;
 
 		}
 

BIN=BIN
examples/screenshots/webgpu_loader_materialx.jpg


+ 72 - 13
examples/webgpu_loader_materialx.html

@@ -32,6 +32,8 @@
 
 			import * as THREE from 'three/webgpu';
 
+			import { Fn, length, fract, vec4, positionWorld, smoothstep, max, abs, float, cameraPosition, clamp } from 'three/tsl';
+
 			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
 
 			import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
@@ -90,7 +92,8 @@
 				'sheen_test.mtlx',
 			];
 
-			let camera, scene, renderer, prefab;
+			let camera, scene, renderer;
+			let controls, prefab;
 			const models = [];
 
 			init();
@@ -100,12 +103,7 @@
 				const container = document.createElement( 'div' );
 				document.body.appendChild( container );
 
-				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 50 );
-				camera.position.set( 0, 3, 20 );
-
-				scene = new THREE.Scene();
-
-				renderer = new THREE.WebGPURenderer( { antialias: true, alpha: true } );
+				renderer = new THREE.WebGPURenderer( { antialias: true } );
 				renderer.setPixelRatio( window.devicePixelRatio );
 				renderer.setSize( window.innerWidth, window.innerHeight );
 				renderer.toneMapping = THREE.LinearToneMapping;
@@ -113,9 +111,63 @@
 				renderer.setAnimationLoop( render );
 				container.appendChild( renderer.domElement );
 
+				camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 200 );
+				camera.position.set( 10, 10, 20 );
+
+				scene = new THREE.Scene();
+				scene.background = new THREE.Color( 0xffffff );
+
+				// Ground plane
+
+				const material = new THREE.MeshStandardNodeMaterial();
+
+				const gridXZ = Fn( ( [ gridSize = float( 1.0 ), dotWidth = float( 0.1 ), lineWidth = float( 0.02 ) ] ) => {
+
+					const worldPos = positionWorld;
+					const grid = fract( worldPos.xz.div( gridSize ) );
+					
+					// Distance-based antialiasing
+					const distToCamera = length( worldPos.sub( cameraPosition ) );
+					const smoothing = clamp( distToCamera.div( 100.0 ), 0.01, 0.02 );
+					
+					// Create dots at cell centers
+					const dotDist = length( grid.sub( 0.5 ) );
+					const dots = smoothstep( dotWidth.add( smoothing ), dotWidth.sub( smoothing ), dotDist );
+					
+					// Create grid lines
+					const lineX = smoothstep( lineWidth.add( smoothing ), lineWidth.sub( smoothing ), abs( grid.x.sub( 0.5 ) ) );
+					const lineZ = smoothstep( lineWidth.add( smoothing ), lineWidth.sub( smoothing ), abs( grid.y.sub( 0.5 ) ) );
+					const lines = max( lineX, lineZ );
+					
+					return max( dots, lines );
+
+				} );
+
+				const radialGradient = Fn( ( [ radius = float( 10.0 ), falloff = float( 1.0 ) ] ) => {
+
+					return smoothstep( radius, radius.sub( falloff ), length( positionWorld ) );
+
+				} );
+				
+				// Create grid pattern
+				const gridPattern = gridXZ( 1.0, 0.04, 0.01 );
+				const baseColor = vec4( 1.0, 1.0, 1.0, 0.0 );
+				const gridColor = vec4( 0.2, 0.2, 0.2, 1.0 );
+				
+				// Mix base color with grid lines
+				material.colorNode = gridPattern.mix( baseColor, gridColor ).mul( radialGradient( 30.0, 20.0 ) );
+				material.transparent = true;
+
+				const plane = new THREE.Mesh( new THREE.CircleGeometry( 50 ), material );
+				plane.rotation.x = - Math.PI / 2;
+				plane.renderOrder = - 1;
+				scene.add( plane );
+
 				//
 
-				const controls = new OrbitControls( camera, renderer.domElement );
+				controls = new OrbitControls( camera );
+				controls.connect( renderer.domElement );
+				controls.enableDamping = true;
 				controls.minDistance = 2;
 				controls.maxDistance = 40;
 
@@ -127,7 +179,6 @@
 
 						texture.mapping = THREE.EquirectangularReflectionMapping;
 
-						scene.background = texture;
 						scene.environment = texture;
 
 						prefab = ( await new GLTFLoader().loadAsync( './models/gltf/ShaderBall.glb' ) ).scene;
@@ -154,21 +205,21 @@
 
 			function updateModelsAlign() {
 
-				const COLUMN_COUNT = 8;
+				const COLUMN_COUNT = 6;
 				const DIST_X = 3;
-				const DIST_Y = 4;
+				const DIST_Z = 3;
 
 				const lineCount = Math.floor( models.length / COLUMN_COUNT ) - 1.5;
 
 				const offsetX = ( DIST_X * ( COLUMN_COUNT - 1 ) ) * - .5;
-				const offsetY = ( DIST_Y * lineCount ) * .5;
+				const offsetZ = ( DIST_Z * lineCount ) * .5;
 
 				for ( let i = 0; i < models.length; i ++ ) {
 
 					const model = models[ i ];
 
 					model.position.x = ( ( i % COLUMN_COUNT ) * DIST_X ) + offsetX;
-					model.position.y = ( Math.floor( i / COLUMN_COUNT ) * - DIST_Y ) + offsetY;
+					model.position.z = ( Math.floor( i / COLUMN_COUNT ) * - DIST_Z ) + offsetZ;
 
 				}
 
@@ -197,6 +248,13 @@
 				const previewMesh = model.getObjectByName( 'Preview_Mesh' );
 				previewMesh.material = material;
 
+				if ( material.transparent ) {
+
+					calibrationMesh.renderOrder = 1;
+					previewMesh.renderOrder = 2;
+
+				}
+
 			}
 
 			function addGUI() {
@@ -247,6 +305,7 @@
 
 			function render() {
 
+				controls.update();
 				renderer.render( scene, camera );
 
 			}

粤ICP备19079148号