我需要在 OpenGL ES 2.0 中的剪切平面下剪切几百个对象,并且希望了解对 OpenGL 的这个子集更有经验的人提供的想法。
在 OpenGL ES 1.x 中有 glClipPlane。在桌面上,您的着色器中有 glClipPlane 或 gl_ClipDistance。这两者在 OpenGL ES 2.0 中都不可用。看来这种功能在2.0中就完全消失了。
似乎唯一的方法是 A)在片段着色器中运行平面方程,或者 B)编写一个非常复杂的顶点着色器,如果顶点位于平面后面,则将顶点定位在平面上。
(A) 与 glClipPlane 相比会很慢,因为“常规”裁剪是在顶点着色器之后和片段着色器之前完成的,每个片段仍然需要部分处理和丢弃。
(B) 很难在着色器之间兼容,因为我们不能丢弃顶点,我们必须将它们与平面对齐并调整“剪切”的属性。如果不发送纹理中的所有顶点并对其进行采样,则无法在着色器中的顶点之间进行插值,这将非常昂贵。通常,无论如何都可能无法正确插入数据。
我还考虑过将近平面与裁剪平面对齐,这将是一个有效的解决方案。
在渲染整个场景并检查深度失败后绘制平面也不起作用(除非您看起来接近垂直于平面)。
对单个对象有效的方法是将平面绘制到深度缓冲区,然后使用 glDepthFunc(GL_GREATER) 渲染该对象,但正如预期的那样,当一个对象位于另一个对象后面时,它不起作用。我尝试以这个概念为基础,但最终得到了与影子卷非常相似的东西,而且同样昂贵。
那我错过了什么?如何在 OpenGL ES 2.0 中进行平面裁剪?
最佳答案
这是我在 Vuforia SDK forums 上找到的两个解决方案.
使用 Harri Smatt 的着色器:
<小时/>uniform mat4 uModelM; uniform mat4 uViewProjectionM; attribute vec3 aPosition; varying vec3 vPosition; void main() { vec4 pos = uModelM * vec4(aPosition, 1.0); gl_Position = uViewProjectionM * pos; vPosition = pos.xyz / pos.w; }
precision mediump float; varying vec3 vPosition; void main() { if (vPosition.z < 0.0) { discard; } else { // Choose actual color for rendering.. } }
Alessandro Boccalatte 在深度缓冲区中使用四元:
- disable color writing (i.e. set the
glColorMask(false, false, false, false);
) - render a quad which matches the marker shape (i.e. just a quad with the same size and position/orientation of the marker); this will only be rendered into the depth buffer (because we disabled color buffer writing in the previous step)
- enable back the color mask (
glColorMask(true, true, true, true);
) - render your 3D models
- disable color writing (i.e. set the
关于opengl-es - OpenGL ES 2.0 中的剪裁平面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7408855/