Three.js / WebGL - transparent planes hiding other planes behind them

前端 未结 6 491
梦毁少年i
梦毁少年i 2020-11-27 17:18

When you have two planes in Three.js / WebGL and one or both of them are transparent, sometimes the plane behind will be hidden by the transparent plane above. Why is this?<

相关标签:
6条回答
  • 2020-11-27 17:59

    fwiw, if you have lots of parallel planes (can't see your sample, google can't resolve your domain), it's easy to keep them sorted along the perpendicular axis. For a list of planes [A B C D] the order-to-draw will be either [A B C D] or [D C B A] and nothing else! So there need not be a performance hit from sorting. Just keep them in order as you go.

    0 讨论(0)
  • 2020-11-27 18:09

    Let's say that you are using some transparent *.png image. Then this would help:

    new THREE.MeshBasicMaterial( { side:THREE.BackSide,map:texture, depthWrite: false, depthTest: false });
    
    0 讨论(0)
  • 2020-11-27 18:10

    Setting the depthWrite property to false solved my issue.

    new THREE.MeshBasicMaterial({ 
        opacity: 0.25, 
        transparent: true, 
        side: THREE.DoubleSide, 
        depthWrite: false
    });
    
    0 讨论(0)
  • 2020-11-27 18:11

    This is not a bug, it's just how OpenGL (and, hence, WebGL) works. Transparent surfaces don't play well with the z-buffer, and as such must be manually sorted and rendered back-to-front. Three JS is attempting to do this for you (which is why the problem goes away when you set the X value > 0) but cannot robustly handle the case of intersecting geometry like you're showing.

    I've explained the issue more in-depth in a different SO question, so you may want to reference that.

    0 讨论(0)
  • 2020-11-27 18:19

    Try adding alphaTest: 0.5 to the material.

    0 讨论(0)
  • 2020-11-27 18:19

    Setting Mesh renderOrder to solve my problem, below is my code, you can modify node.renderOrder value:

    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
                    }
                })
    })
    
    0 讨论(0)
提交回复
热议问题