Skip to content

Commit a0daeb5

Browse files
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>
1 parent 5d4eeb4 commit a0daeb5

File tree

3 files changed

+75
-21
lines changed

3 files changed

+75
-21
lines changed

examples/jsm/loaders/MaterialXLoader.js

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -893,21 +893,16 @@ class MaterialXNode {
893893

894894
}
895895

896-
// Auto-enable transparency when opacity or transmission is non-default
897-
const hasNonDefaultOpacity = opacityNode && opacityNode.value !== undefined && opacityNode.value < 1.0;
898-
const hasTransmission = transmissionNode && transmissionNode.value !== undefined && transmissionNode.value > 0;
899-
900-
if ( hasNonDefaultOpacity ) {
896+
if ( opacityNode !== null ) {
901897

902898
material.transparent = true;
903899

904900
}
905901

906-
// Set material properties for transmission
907-
if ( hasTransmission ) {
902+
if ( transmissionNode !== null ) {
908903

909-
material.transparent = true;
910904
material.side = DoubleSide;
905+
material.transparent = true;
911906

912907
}
913908

-64.4 KB
Loading

examples/webgpu_loader_materialx.html

Lines changed: 72 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232

3333
import * as THREE from 'three/webgpu';
3434

35+
import { Fn, length, fract, vec4, positionWorld, smoothstep, max, abs, float, cameraPosition, clamp } from 'three/tsl';
36+
3537
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
3638

3739
import { RGBELoader } from 'three/addons/loaders/RGBELoader.js';
@@ -90,7 +92,8 @@
9092
'sheen_test.mtlx',
9193
];
9294

93-
let camera, scene, renderer, prefab;
95+
let camera, scene, renderer;
96+
let controls, prefab;
9497
const models = [];
9598

9699
init();
@@ -100,22 +103,71 @@
100103
const container = document.createElement( 'div' );
101104
document.body.appendChild( container );
102105

103-
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 50 );
104-
camera.position.set( 0, 3, 20 );
105-
106-
scene = new THREE.Scene();
107-
108-
renderer = new THREE.WebGPURenderer( { antialias: true, alpha: true } );
106+
renderer = new THREE.WebGPURenderer( { antialias: true } );
109107
renderer.setPixelRatio( window.devicePixelRatio );
110108
renderer.setSize( window.innerWidth, window.innerHeight );
111109
renderer.toneMapping = THREE.LinearToneMapping;
112110
renderer.toneMappingExposure = .5;
113111
renderer.setAnimationLoop( render );
114112
container.appendChild( renderer.domElement );
115113

114+
camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 0.25, 200 );
115+
camera.position.set( 10, 10, 20 );
116+
117+
scene = new THREE.Scene();
118+
scene.background = new THREE.Color( 0xffffff );
119+
120+
// Ground plane
121+
122+
const material = new THREE.MeshStandardNodeMaterial();
123+
124+
const gridXZ = Fn( ( [ gridSize = float( 1.0 ), dotWidth = float( 0.1 ), lineWidth = float( 0.02 ) ] ) => {
125+
126+
const worldPos = positionWorld;
127+
const grid = fract( worldPos.xz.div( gridSize ) );
128+
129+
// Distance-based antialiasing
130+
const distToCamera = length( worldPos.sub( cameraPosition ) );
131+
const smoothing = clamp( distToCamera.div( 100.0 ), 0.01, 0.02 );
132+
133+
// Create dots at cell centers
134+
const dotDist = length( grid.sub( 0.5 ) );
135+
const dots = smoothstep( dotWidth.add( smoothing ), dotWidth.sub( smoothing ), dotDist );
136+
137+
// Create grid lines
138+
const lineX = smoothstep( lineWidth.add( smoothing ), lineWidth.sub( smoothing ), abs( grid.x.sub( 0.5 ) ) );
139+
const lineZ = smoothstep( lineWidth.add( smoothing ), lineWidth.sub( smoothing ), abs( grid.y.sub( 0.5 ) ) );
140+
const lines = max( lineX, lineZ );
141+
142+
return max( dots, lines );
143+
144+
} );
145+
146+
const radialGradient = Fn( ( [ radius = float( 10.0 ), falloff = float( 1.0 ) ] ) => {
147+
148+
return smoothstep( radius, radius.sub( falloff ), length( positionWorld ) );
149+
150+
} );
151+
152+
// Create grid pattern
153+
const gridPattern = gridXZ( 1.0, 0.04, 0.01 );
154+
const baseColor = vec4( 1.0, 1.0, 1.0, 0.0 );
155+
const gridColor = vec4( 0.2, 0.2, 0.2, 1.0 );
156+
157+
// Mix base color with grid lines
158+
material.colorNode = gridPattern.mix( baseColor, gridColor ).mul( radialGradient( 30.0, 20.0 ) );
159+
material.transparent = true;
160+
161+
const plane = new THREE.Mesh( new THREE.CircleGeometry( 50 ), material );
162+
plane.rotation.x = - Math.PI / 2;
163+
plane.renderOrder = - 1;
164+
scene.add( plane );
165+
116166
//
117167

118-
const controls = new OrbitControls( camera, renderer.domElement );
168+
controls = new OrbitControls( camera );
169+
controls.connect( renderer.domElement );
170+
controls.enableDamping = true;
119171
controls.minDistance = 2;
120172
controls.maxDistance = 40;
121173

@@ -127,7 +179,6 @@
127179

128180
texture.mapping = THREE.EquirectangularReflectionMapping;
129181

130-
scene.background = texture;
131182
scene.environment = texture;
132183

133184
prefab = ( await new GLTFLoader().loadAsync( './models/gltf/ShaderBall.glb' ) ).scene;
@@ -154,21 +205,21 @@
154205

155206
function updateModelsAlign() {
156207

157-
const COLUMN_COUNT = 8;
208+
const COLUMN_COUNT = 6;
158209
const DIST_X = 3;
159-
const DIST_Y = 4;
210+
const DIST_Z = 3;
160211

161212
const lineCount = Math.floor( models.length / COLUMN_COUNT ) - 1.5;
162213

163214
const offsetX = ( DIST_X * ( COLUMN_COUNT - 1 ) ) * - .5;
164-
const offsetY = ( DIST_Y * lineCount ) * .5;
215+
const offsetZ = ( DIST_Z * lineCount ) * .5;
165216

166217
for ( let i = 0; i < models.length; i ++ ) {
167218

168219
const model = models[ i ];
169220

170221
model.position.x = ( ( i % COLUMN_COUNT ) * DIST_X ) + offsetX;
171-
model.position.y = ( Math.floor( i / COLUMN_COUNT ) * - DIST_Y ) + offsetY;
222+
model.position.z = ( Math.floor( i / COLUMN_COUNT ) * - DIST_Z ) + offsetZ;
172223

173224
}
174225

@@ -197,6 +248,13 @@
197248
const previewMesh = model.getObjectByName( 'Preview_Mesh' );
198249
previewMesh.material = material;
199250

251+
if ( material.transparent ) {
252+
253+
calibrationMesh.renderOrder = 1;
254+
previewMesh.renderOrder = 2;
255+
256+
}
257+
200258
}
201259

202260
function addGUI() {
@@ -247,6 +305,7 @@
247305

248306
function render() {
249307

308+
controls.update();
250309
renderer.render( scene, camera );
251310

252311
}

0 commit comments

Comments
 (0)