我想用GLKit绘制半透明基元。我已经通过glDisable(GL_DEPTH_TEST)
停用了深度测试,并通过
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
现在对于较大的alpha值(例如0.9),我需要先绘制最远的三角形,这样它们就不会出现 更近的三角形。这也在documentation for glBlendFunc:
中说明最好使用混合函数(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)实现透明度,其中基元从最远到最近排序。请注意,此透明度计算不要求帧缓冲区中存在alpha位平面
在应用程序中使用深度缓冲时,需要注意渲染基元的顺序。需要首先渲染完全不透明的图元,然后按照从前到后的顺序渲染部分不透明的图元。如果不按此顺序渲染图元,原始图形(否则通过部分不透明图元可见)可能会完全失去深度测试。
但是由于视角可以改变(当我更改渲染效果的modelViewMatrix
时),最远到最近的顺序取决于当前的视角。
有没有办法让OpenGL以正确的顺序自动渲染我的原语,如果没有,那么最好的方法是什么?我认为计算z位置(取决于当前视角)并为每个帧排序几千个三角形(或者更准确地说,每次视角变化,可能是每个帧)将是成本过高的,特别是因为我需要将每个帧的顺序推送到GPU。
请注意,我并不关心使用纹理(只是彩色顶点)。
答案 0 :(得分:3)
首先,不,没有办法让OpenGL为你做这个。您必须根据当前相机和模型位置(即模型视图矩阵)手动对透明几何体进行排序。
为了实现这一点,在实时实现中,您通常不会对单个三角形进行排序,而是对其逻辑子集(网格,子网格)进行排序。然后问题案例变成:
在性能方面,重要的是,在构建场景时,将元素拆分为(部分)透明的vs.不透明的。这样就可以避免大型排序操作,因为您只需要对透明几何体进行排序。
高级技巧
对于完全不同的方法,请查找深度剥离和类似技术。如果做得好,这些技术可以提供很多。但是,我不知道实际实现它们的任何OpenGL ES 标题。这并不意味着它不是一个选择。
<强>然而... 强>
如果您对3D编程一般不熟悉,我强烈建议您坚持使用手动排序并尝试将工件减少到最低限度。通过这种方式,您可以根据具体情况做出明智的决定,确定此类实施是否充分。
如果不出意外,实施这些东西将自动授予您超人的能力,以便立即发现(并且极大地分散注意力)与您从现在开始玩的每个视频游戏中的透明度相关渲染问题。一个奇妙的技能。
答案 1 :(得分:3)
没有自动解决方案,因为由于相互重叠的问题,没有强大的实时解决方案。如果您原谅ASCII艺术,请考虑将四个四边形排列为:
+--+ +--+
| | | |
+---------------------| |------+
| | | |
+---------------------| |------+
| | | |
| | | |
| | | |
+----| |-----------------------+
| | | |
+----| |-----------------------+
| | | |
+--+ +--+
没有正确的订购。你需要将至少一个四边形分成两个 - 这就像建立一个BSP树那样的提前计划。这就是存在深度缓冲的原因;在大多数几何体是不透明的基础上解决每个像素的这个问题。
所以最好的方法是: