JSON模型的透明材质在Three.js场景中看起来很奇怪

时间:2016-07-29 17:41:52

标签: json three.js transparency opacity

当我更改JSON模型的不透明度时,我发现材质看起来很奇怪。

这是我的代码

var jsonLoader = new THREE.JSONLoader();

jsonLoader.load('model/body.json', addBodyToScn);
function addBodyToScn(geometry, material) {
    var Mtl = new THREE.MeshFaceMaterial(material);
    jsonMesh = new THREE.Mesh(geometry, Mtl);
    jsonMesh.scale.set(2, 2, 2);
    jsonMesh.material.materials.forEach(function(m){
        m.transparent = true;
        m.opacity = 1;
    });


jsonLoader.load('model/cow.json', addCowToScn);
function addCowToScn(geometry, material) {
    var Mtl2 = new THREE.MeshFaceMaterial(material);
    jsonMesh = new THREE.Mesh(geometry, Mtl2);
    jsonMesh.scale.set(2, 2, 2);
    jsonMesh.material.materials.forEach(function(m){
        m.transparent = true;
        m.opacity = 1;
    });

我试图改变母牛的不透明度,我想看到母牛内部的一部分。

opacity = 0.5
opacity = 0

无论我使用不同数量的不透明度,我都无法看到人类内部的一部分。

我不明白发生了什么。

1 个答案:

答案 0 :(得分:1)

您看到的问题可能与z缓冲区和透明度有关。 在实时渲染中,正确的透明度比起初看起来更难,我会尝试解释原因。

发生了什么: 首先渲染透明牛。在渲染时,对于牛的每个片段(像素),将深度值(=到相机的距离)写入z缓冲区。像素颜色与颜色缓冲区中的值混合(此时在您的情况下为黑色)。

之后渲染人体,但是对于每个渲染的片段,首先执行深度测试:如果渲染的人体片段位于已经渲染的片段后面(基于z中找到的值) -buffer),该片段被丢弃,不会被写入颜色缓冲区。

来自(优秀)this youtube-videoudacity-course on three.js可能有助于在此处说明问题。

Three.js在两次传递中渲染对象:

  • 首先从前到后渲染所有不透明对象。这样,隐藏在前面的物体后面的物体不需要渲染*(由于深度测试)
  • 在第二遍中,从后面到前面渲染所有透明对象。这是为了允许透明对象后面的透明对象不被深度测试丢弃(这正是你想要的)

现在,哪个对象在前面,哪个在后面,是根据object.positioncamera.position之间的距离确定的。一旦对象开始相交,这会有点棘手,因为在您的示例中可能就是这种情况。

不幸的是,目前还没有针对这个问题的解决方案,它可以在所有情况下使用。

您可以尝试修改对象位置,以便母牛绝对位于人体前方,在这种情况下,渲染应该可以正常工作。

在three.js中还有两个材料属性控制z缓冲区行为,名为depthTestdepthWrite(请参阅here)。因此,您可以禁用牛的深度写入或禁用人体的深度测试。不幸的是,两者都不是真正的解决方案,因为禁用深度测试将导致人体被渲染在场景中的所有内容上(甚至是前面的不透明物体)并且禁用深度写入会导致后面的对象牛被渲染成好像他们在前面。