GLKit/OpenGLES 2.0:如何排序基元?

MrM*_*age 1 geometry transparency opengl-es opengl-es-2.0 glkit

我想用 GLKit 绘制半透明图元。我已经通过禁用深度测试glDisable(GL_DEPTH_TEST)并通过启用混合

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
Run Code Online (Sandbox Code Playgroud)

现在,对于较大的 alpha 值(例如 0.9),我需要首先绘制最远的三角形,这样它们就不会出现在较近的三角形上方glBlendFunc 的文档中也说明了这一点:

透明度最好使用混合函数(GL_SRC_ALPHA、GL_ONE_MINUS_SRC_ALPHA)来实现,其中图元从最远到最近排序。请注意,此透明度计算不需要帧缓冲区中存在 alpha 位平面

在OpenGL 透明度常见问题解答中:

在应用程序中使用深度缓冲时,您需要注意渲染图元的顺序。需要首先渲染完全不透明的图元,然后按从后到前的顺序渲染部分不透明的图元。如果不按此顺序渲染图元,则通过部分不透明图元可见的图元可能会完全失去深度测试。

但由于视角可以改变(当我改变渲染效果时modelViewMatrix),从远到近的顺序取决于当前的视角。

有没有办法让 OpenGL 以正确的顺序自动渲染我的图元,如果没有,最好的方法是什么?我认为计算 z 位置(取决于当前视角)并为每帧订购几千个三角形(或者更准确地说,每次视角变化时,可以是每帧)的成本太高,特别是当我需要为每一帧将此订单推送到 GPU 时。

请注意,我不关心使用纹理(只是彩色顶点)。

Tom*_*mmy 5

没有自动解决方案,因为由于相互重叠的问题,没有强大的实时解决方案。如果您能原谅 ASCII 艺术,请考虑将四个四边形排列如下:

\n\n
     +--+             +--+\n     |  |             |  |\n+---------------------|  |------+\n|                     |  |      |\n+---------------------|  |------+\n     |  |             |  |\n     |  |             |  |\n     |  |             |  |\n+----|  |-----------------------+\n|    |  |                       |\n+----|  |-----------------------+\n     |  |             |  |\n     +--+             +--+\n
Run Code Online (Sandbox Code Playgroud)\n\n

没有正确的顺序。您需要将至少一个四边形拆分为两个 \xe2\x80\x94 ,这就是构建 BSP 树等提前方案所做的事情。这就是深度缓冲存在的原因;在大多数几何体都是不透明的基础上逐像素解决这个问题。

\n\n

因此,最好的继续方法是:

\n\n
    \n
  • 为您的透明几何体构建 BSP 树(为了完全准确);
  • \n
  • 为透明几何体构建每个对象的 BSP 树,从后到前对对象进行排序(以获得相当好的准确性);
  • \n
  • 要求对象仅具有或多或少的凸透明段,因此如果您要构建一棵树,则最终会得到一棵带有单叶的 BSP 树,从后到前排序(为了合理的准确性,取决于您的艺术);
  • \n
  • 在绘制所有不透明几何体后,使用加法混合并以任何顺序绘制,并取消深度(以获得不同的外观,但无需考虑顺序)。
  • \n
\n