Three.js / WebGL - 透明平面将其他平面隐藏在其后面

问题描述 投票:0回答:7

当您在 Three.js / WebGL 中有两个平面并且其中一个或两个都是透明的时,有时后面的平面会被上面的透明平面隐藏。这是为什么?

javascript three.js webgl depth zbuffer
7个回答
26
投票

depthWrite
属性设置为
false
解决了我的问题。

new THREE.MeshBasicMaterial({ 
    opacity: 0.25, 
    transparent: true, 
    side: THREE.DoubleSide, 
    depthWrite: false
});

25
投票

假设您正在使用一些透明的 *.png 图像。那么这会有所帮助:

new THREE.MeshBasicMaterial( {
    depthWrite: false,
    depthTest: false
    side:THREE.DoubleSide,
    map:texture
});

21
投票

尝试将

alphaTest: 0.5
添加到材料中。


15
投票

这不是一个错误,这只是 OpenGL(以及 WebGL)的工作原理。透明表面不能很好地与 z 缓冲区配合使用,因此必须手动排序并从后到前渲染。三个 JS 正在尝试为您执行此操作(这就是为什么当您设置 X 值 > 0 时问题就会消失),但无法稳健地处理像您所展示的相交几何体的情况。

我已经在一个不同的SO问题中更深入地解释了这个问题,所以你可能想参考一下。


6
投票

fwiw,如果你有很多平行平面(看不到你的样本,谷歌无法解析你的域名),很容易让它们沿着垂直轴排序。对于平面列表 [A B C D],绘制顺序将是 [A B C D] 或 [D C B A],仅此而已!因此排序不会对性能造成影响。走的时候保持它们井然有序即可。


1
投票

设置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
                }
            })
})

1
投票

这对我有用,不要使用文字布尔值 true 尝试使用 1 代替。

object3d.material.transparent = 1; 
© www.soinside.com 2019 - 2024. All rights reserved.