我正在将我在 Blender 4.2 中制作的第一个模型(由一台计算机和两台显示器组成)导入到我的 Three.js 场景中。
我在“计算机屏幕”上设置了一张
VideoTexture
地图,这是我通过遍历场景从模型获得的。我的问题是视频纹理跨越整个网格。
这是代码:
const monitorScreenOne = document.getElementById( 'monitor-1-video' );
const textureTwo = new THREE.VideoTexture( monitorScreenOne );
// MODEL
const loader = new GLTFLoader(loadingManager)
loader.load('resources/script/lol/test.gltf', (gltf) => {
gltf.scene.traverse(function(node) {
if(node.name == 'screen-monitor-display'){
node.position.x = 10
node.material = new THREE.MeshBasicMaterial({
map: textureTwo,
})
monitorScreenOne.load()
monitorScreenOne.setAttribute('playsinline', true)
}
})
scene.add(gltf.scene)
})
这是它的输出: 具有工作视频纹理的电脑屏幕。它是侧面的,但我稍后会修复它。
现在,当我添加一些额外的材质应用于每个面时(这是我从this stackoverflow链接获得的),使用以下代码:
// MODEL
const loader = new GLTFLoader(loadingManager)
loader.load('resources/script/lol/test.gltf', (gltf) => {
gltf.scene.traverse(function(node) {
if(node.name == 'screen-monitor-display'){
node.position.x = 10
node.material = new THREE.MeshBasicMaterial({
map: textureTwo,
})
node.material = new THREE.MeshNormalMaterial()
node.material = new THREE.MeshNormalMaterial()
node.material = new THREE.MeshNormalMaterial()
node.material = new THREE.MeshNormalMaterial()
node.material = new THREE.MeshNormalMaterial()
monitorScreenOne.load()
monitorScreenOne.setAttribute('playsinline', true)
}
})
scene.add(gltf.scene)
})
这是它的输出:具有非工作视频纹理的计算机场景。正如您在图像中看到的,每张脸都是普通材质。
我显然处理这个问题的方式是错误的。如何在场景中屏幕对象的单个面上获取视频纹理,同时使该对象的每个其他面具有不同的材质?
在您链接的示例中,将材质数组分配给
mesh.material
,假设该网格的几何形状已使用多个几何组初始化。例如,THREE.BoxGeometry 默认情况下带有 6 个几何组,每个几何组对应盒子的每一侧,通常每组有两个三角形。材质不能分配给单个三角形 - 只能分配给整个网格或特定的几何体组。
从 glTF 模型加载的网格在 Three.js 中不会有几何组,除非您碰巧知道要使用的屏幕部分是(例如)“屏幕监视器显示”中的三角形 35–75 “网格,以编程方式创建这些组将会很困难。
在大多数情况下,在 Blender 中打开 glTF 模型要容易得多,分离将要修改的部分放入具有不同名称的不同网格中,然后在 Three.js 中查找具有该名称的网格。