opengl-es - OpenGL ES 2.0 中的剪裁平面

标签 opengl-es glsl shader opengl-es-2.0 clipping

我需要在 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 上找到的两个解决方案.

  1. 使用 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..
      }
    }
    
  2. 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

关于opengl-es - OpenGL ES 2.0 中的剪裁平面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7408855/

相关文章:

c++ - glGetObjectParameteriv 不在 GLEW 中

通过 DirectX 11 渲染正方形

ios - 使用GLKit加载纹理时如何在glTexImage2D中传递数据参数?

iphone - 如何在 OpenGL ES 中保存和重绘屏幕内容

objective-c - 从不同着色器导入函数

c++ - 动态数组作为纹理 GLSL

directx - HLSL 中的渲染深度

ios - 条件的 OpenGL ES 最佳实践

android - 将自定义过滤器应用于相机输出

android - android.opengl 和 javax.microedition.khronos.opengles 包之间有什么区别?