当您在 Three.js / WebGL 中有两个平面并且其中一个或两个都是透明的时,有时后面的平面会被上面的透明平面隐藏。这是为什么?
将
depthWrite
属性设置为 false
解决了我的问题。
new THREE.MeshBasicMaterial({
opacity: 0.25,
transparent: true,
side: THREE.DoubleSide,
depthWrite: false
});
假设您正在使用一些透明的 *.png 图像。那么这会有所帮助:
new THREE.MeshBasicMaterial( {
depthWrite: false,
depthTest: false
side:THREE.DoubleSide,
map:texture
});
尝试将
alphaTest: 0.5
添加到材料中。
这不是一个错误,这只是 OpenGL(以及 WebGL)的工作原理。透明表面不能很好地与 z 缓冲区配合使用,因此必须手动排序并从后到前渲染。三个 JS 正在尝试为您执行此操作(这就是为什么当您设置 X 值 > 0 时问题就会消失),但无法稳健地处理像您所展示的相交几何体的情况。
我已经在一个不同的SO问题中更深入地解释了这个问题,所以你可能想参考一下。
fwiw,如果你有很多平行平面(看不到你的样本,谷歌无法解析你的域名),很容易让它们沿着垂直轴排序。对于平面列表 [A B C D],绘制顺序将是 [A B C D] 或 [D C B A],仅此而已!因此排序不会对性能造成影响。走的时候保持它们井然有序即可。
设置Mesh
renderOrder
来解决我的问题,下面是我的代码,你可以修改node.renderOrder
值:
loader.load(model_url, (gltf)=>{
let scene = gltf.scene
scene.traverse((node)=>{
if(node.isMesh){
node.material.transparent = true
if(node.name === 'car_windows'){
node.material.opacity = 0.4
node.material.side = 0
node.renderOrder = 110
}
if(node.name === 'car_body'){
node.material.opacity = 0.4
node.renderOrder = 100
}
if(node.name === 'car_seats'){
node.material.opacity = .5
node.renderOrder = 90
}
mesh_arr.push(node)
mesh_objs[node.name] = node
}
})
})
这对我有用,不要使用文字布尔值 true 尝试使用 1 代替。
object3d.material.transparent = 1;