2016-07-29 75 views
0

当我改变JSON模型的不透明度时,发现材质看起来很奇怪。JSON模型的透明材质在Three.js场景中看起来很奇怪

这里是我的代码

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

您看到的问题可能与z-buffer和transparency有关。 在实时渲染中,正确的透明度比起初看起来要困难得多,我会试着解释原因。

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

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

也许this youtube-video来自(优秀)udacity-course on three.js有助于说明这里的问题。

three.js所呈现的物体在两次通过:

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

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

不幸的是,目前还没有解决方案可以在所有情况下都能正常工作。

您可以尝试修改对象的位置,使牛肯定在人体前面,在这种情况下,渲染应该可以正常工作。

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

+0

谢谢您的解释! 你解释的很清楚,所以我想我明白你的意思。 我是Three.js和WebGL的初学者。 最近我读了这本书<< WebGL Programming Guide >>,因为我需要了解更多关于WebGL的知识。 非常感谢! –