OpenGL ES 2.0中的剪切平面 [英] Clipping-planes in OpenGL ES 2.0

查看:73
本文介绍了OpenGL ES 2.0中的剪切平面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在OpenGL ES 2.0中,我需要在裁剪平面下裁剪几百个对象,并且希望从对这部分OpenGL有丰富经验的人那里得到启发.

I need to clip a few hundred objects under a clipping plane in OpenGL ES 2.0 and would appreciate ideas from people more experienced with this subset of OpenGL.

在OpenGL ES 1.x中有glClipPlane.在桌面上,着色器中具有glClipPlane或gl_ClipDistance.在OpenGL ES 2.0中,这两个都不可用.这种功能似乎在2.0中完全消失了.

In OpenGL ES 1.x there is glClipPlane. On the desktop you have glClipPlane, or gl_ClipDistance in your shader. Neither of these two are available in OpenGL ES 2.0. It seems that this kind of functionality disappeared completely with 2.0.

似乎唯一的方法是A)在片段着色器中运行平面方程,或者B)编写一个非常复杂的顶点着色器,如果顶点在平面上,则将顶点放置在平面上.

It seems the only way to do this is either A) run the plane equation in the fragment shader, or B) write a very complex vertex shader that positions vertices on the plane if they are behind it.

(A)与glClipPlane相比要慢一些,因为常规"剪切是在顶点着色器之后和片段着色器之前完成的,所以每个片段仍然必须被部分处理并丢弃.

(A) would be slow compared to glClipPlane, since "regular" clipping is done after the vertex shader and before the fragment shader, each fragment would still have to be partially processed and discarded.

(B)将很难使着色器之间兼容,因为我们无法丢弃顶点,因此必须将其与平面对齐并为剪切"的属性调整属性.如果不将所有顶点发送到纹理中并对其进行采样,则无法在着色器的顶点之间进行插值,这将是非常昂贵的.无论如何,通常不可能正确地插值数据.

(B) would be very hard to make compatible between shaders, since we can't discard vertices we have to align them with the plane and adjust attributes for those that are "cut". It's not possible to interpolate between vertices in the shader without sending all vertices in a texture and sample it, which would be extremely expensive. Often it would probably be impossible to interpolate the data correcly anyway.

我还考虑过将近平面与剪切平面对齐,这将是一种有效的解决方案.

I've also thought of aligning the near plane with the clipping plane which would be an efficient solution.

渲染整个场景并检查深度失败后再绘制平面也将不起作用(除非您看上去与平面垂直).

And drawing a plane after rendering the whole scene and checking for depth-fail will not work either (unless you are looking close to perpendicular to the plane).

对单个对象有效的方法是将平面绘制到深度缓冲区,然后使用glDepthFunc(GL_GREATER)渲染该对象,但是正如预期的那样,当其中一个对象位于另一个对象之后时,它将不起作用.我试图在这个概念的基础上继续前进,但最终得到了与影子卷非常相似且价格昂贵的东西.

What works for a single object is to draw the plane to the depth buffer and then render the object with glDepthFunc(GL_GREATER), but as expected it does not work when one of the objects is behind another. I tried to build on to this concept but eventually ended up with something very similar to shadow volumes and just as expensive.

那我想念什么?您将如何在OpenGL ES 2.0中进行平面裁剪?

So what am I missing? How would you do plane clipping in OpenGL ES 2.0?

推荐答案

以下是我在

  • 使用Harri Smatt的着色器:

    1. Using shaders by 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的四倍深度缓冲区:

  • Using quad in depth buffer by Alessandro Boccalatte:

    • 禁用颜色书写(即设置glColorMask(false, false, false, false);)
    • 渲染与标记形状匹配的四边形(即,仅具有相同大小和标记位置/方向的四边形);这只会呈现到深度缓冲区中(因为我们在上一步中禁用了颜色缓冲区写入功能)
    • 重新启用颜色蒙版(glColorMask(true, true, true, true);)
    • 渲染3D模型
    • 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 2.0中的剪切平面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆