2015-12-17 46 views
0

我有一个GLViewWidget,在这里我添加不同的对象(GLMeshItem)设置这些属性,以使透明度:启用3D透明度 - pyopengl

 opt = { 
      GL_DEPTH_TEST: True, 
      'glBlendFunc': (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA), 
      } 
     obj.setGLOptions(opt) 

这几乎是工作,在下面的意义: 如果我有两个对象obj1和obj2,并按照这个顺序将它们添加到小部件中,我会在obj1的后面看到obj2,但不是相反。

我试图以不同的顺序添加对象,但显然我会在obj2后面看到obj1,而不是相反。我怎样才能使这个工作对所有的对象漠不关心?

+0

您必须将它们排序并按正确顺序绘制。 – BDL

+0

但正如我所说,这两个对象都是透明的,所以我希望它们的行为方式相同,即obj2显示在obj1后面的obj1和obj1后面,具体取决于我正在观察的点。 – charles

+0

除了顺序无关透明度之外,唯一的方法是根据每个框架中的对象的当前位置对它们进行排序并将它们拉回前面。 – BDL

回答

2

深度测试和透明度不能很好地结合在一起。

假设我们绘制半透明物体obj1。这也会将其深度写入深度缓冲区。 现在假设我们想绘制第二个对象obj2,它具有更大的深度。我们预计我们会看到obj2obj1,因为obj1是半透明的。

但是,由于obj2的深度较大,因深度测试失败而不会绘制重叠像素,因此我们只会看到obj2的部分不与obj1重叠。

深度测试不考虑透明度。因此,为了让它工作,正如BDL在评论中所说的那样,您将不得不手动排序对象并按正确的顺序绘制它们。

+0

禁用深度测试不是必需的。只有当物体从后向前抽出时才能实现正确的混合,这意味着深度测试不再是问题。即使未进行排序,也必须至少启用深度测试并禁用深度写入。否则透明对象不会被不透明的对象隐藏。 – BDL

+1

你是对的,没有必要禁用它。编辑它。我的意思是说可能不再需要启用它。 – Reigertje

+0

所以假设我首先在笛卡尔坐标(0,0,0)处绘制obj1,然后在笛卡尔坐标(2,0,0)处绘制obj2。如果我用x轴指向屏幕看场景,我会在透明obj2后面看到obj1,这是正确的。但是如果我旋转场景,并用屏幕内部的x轴来查看它,我是否应该再次对对象进行排序,以便在透明obj1后面显示obj2? – charles