OpenGL - 在 3D 空间中裁剪

Posted

技术标签:

【中文标题】OpenGL - 在 3D 空间中裁剪【英文标题】:OpenGL - Clipping in 3D space 【发布时间】:2013-05-28 23:45:16 【问题描述】:

我一直在努力寻找如何做到这一点:在 OpenGL 中的定义区域之外进行剪辑。

顺便说一句,我不想​​使用视口或剪刀进行剪辑。我一直在疯狂搜索,但我发现的只是如何使用视口/剪刀。

我想定义类似“如果该像素的 x 小于 10 个单位,则不要绘制它”。比如“如果x在10-20之间,y在10-20之间,z在10-20之间,就可以绘制,否则不渲染像素”。

脚注:很糟糕,*** 要求您注册才能提出问题。最好是在网站开放并且帐户创建是可选的之前。

【问题讨论】:

【参考方案1】:

在搜索了一段时间后想通了,典型的是我刚刚在这个网站上提出了问题。

Java 代码(我使用的是 LWJGL):

DoubleBuffer eqn1 = BufferUtils.createDoubleBuffer(8).put(new double[] -1, 0, 0, 100);
eqn1.flip();
GL11.glClipPlane(GL11.GL_CLIP_PLANE0, eqn1);
GL11.glEnable(GL11.GL_CLIP_PLANE0);

像往常一样,OpenGL 的文档记录很糟糕(因为很差,不容易掌握),我不得不四处搜索,直到最后我在某个论坛上找到了一些解释这一点的内容(并显示缓冲区必须翻转):前三个doubles 是剪切平面的法线,最后一个 (100) 是平面距离世界原点 (0,0,0) 的距离。

因此,如果相机直视 (0,0,0),上面的示例代码将在右侧创建一个平面,使 OpenGL 不会在其右侧渲染内容。平面位于 x=100 并面向左侧 (-1)。

我希望这将是人们在未来寻找答案的搜索结果。

【讨论】:

【参考方案2】:

Fixed-Function 有用户定义的剪裁平面,详见glClipPlane()。你可以定义6个这样的平面来达到你所说的效果。

现代基于着色器的 GL 提供了gl_ClipDistance[] 输出变量数组来实现这样的事情。

您描述的测试似乎是按片段进行的,因此您也可以在片段着色器中执行此操作,方法是丢弃您所在区域之外的所有片段。但这将非常低效(并且会阻止使用早期 Z 测试),因此您应该小心。这可能与模板测试相结合以限制 x 和 y,并且仅在着色器中对 z 进行测试。

【讨论】:

感谢您的回答,不过前一分钟已经想通了。但我会调查 gl_clipDistance 的事情。 顺便说一句,我读到有些人的 gfx 卡上只能有一个剪辑平面。你知道这是否常见吗?如果我什至不能制作六个适用于大多数 gfx 卡的剪辑平面,那感觉就像一个糟糕的解决方案。还有其他方法吗?是否可以使用圆圈进行剪辑(值得一问,也许你知道)?比如,相机在一个球体的中间,而球体外面的东西没有被绘制出来? @user2445741:例如,OpenGL 规范保证至少 6 个用户可定义的剪切平面。根据 GLSL3.3 规范,gl_ClipDistance[] 数组的最小大小至少为 8。

以上是关于OpenGL - 在 3D 空间中裁剪的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL 裁剪

在opengl中重叠矩形并在底部裁剪

如何在opengl的3d空间中旋转单个形状?

opengl中3d空间平面上的程序网格

OpenGL - 将变换应用于 3D 空间中的多边形

3D 空间中的 OpenGL 2D 文本 [C++/GLM] 矩阵乘法