如何剪裁任意形状的纹理?

时间:2013-09-26 14:44:48

标签: opengl 3d

我正在渲染复杂的3d对象。这是一个类似球体的对象的简单示例:

enter image description here

接下来,我将裁剪平面应用于这些对象并在此平面上渲染纹理,给出您正在查看对象内部的印象,就像它被切片一样。例如:

enter image description here

问题是纹理的锯齿状边缘。它会伸出表面的边界。这是另一个角度,你可以看到它突然出现。曲面和纹理都来自相同的源数据,但曲面是平滑的,并且具有比纹理更高的分辨率。

enter image description here

我想要的是能够以某种方式剪切纹理,以便它永远不会超出表面的边界。此外,我不想简单地缩小纹理,因为虽然这可能会阻止它粘在外面,但它会在纹理边缘和表面边缘之间产生内部间隙。我宁愿纹理有点太大而且剪裁它以使与表面边缘齐平

我在这里:

我认为第一步是定义平面和曲面的交点。所以现在我把它作为一个有序的线段列表。但是,我不确定如何继续这些信息(或者如果这是最好的方法)。

我一直在阅读模板缓冲区。一种方法可能是将交叉线转换为2d形状并将其绘制到模板缓冲区中。然后在绘制纹理时应用此选项。 (虽然我觉得这很重要,因为形状很复杂。)

我想知道我是否可以某种方式使用已绘制的表面(与模板缓冲区或其他技术结合)以某种方式剪辑纹理 - 而不必经历额外的麻烦导出交叉线等

这里最好的方法是什么? (您可以指出的任何在线示例也会非常有帮助。)

1 个答案:

答案 0 :(得分:3)

如果您正在剪切凸面物体并知道修剪点的坐标,您可以自己创建多边形“上限” - 只需使用GL_TRIANGLE_FAN以正确的顺序绘制剪切点,就是这样。不适用于非凸对象 - 这将需要三角测量算法。您可以使用glu tesselators对多边形进行三角测量,但这可能很棘手/困难。

如果剪裁区域可以通过公式定义,您可以编写一个着色器,它可以精确地剪切某个距离上的像素(即if x^2+x^2+z^2 > r^2 do not draw pixel)。

您还可以使用着色器绘制背面,该着色器将使用简单的光线跟踪绘制每个背面像素,就好像它在剪裁平面上一样。这很复杂,在你的情况下可能有点过分。 Dead Rising在他们的游戏引擎中使用了类似的技术。

您也可以使用模板缓冲区。

首先使用GL_INCR(glStencilOp(GL_KEEP, GL_INCR, GL_INCR))绘制背面,然后使用GL_DECR(glStencilOp(GL_KEEP, GL_DECR, GL_DECR))绘制正面曲面。然后仅在模板非零的情况下绘制纹理。 (glStencilFunc(GL_GREATER, 0, 0xff); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);)。但是,如果你有许多重叠的形状,你需要特别注意它们。

- 编辑 -

  

但是,我不知道如何继续这些信息(或者这是最好的方法)。

将其绘制为三角扇。对于凸起物体,这就是你所需要的。对于不起作用的非凸对象。

  

一直在读取模板缓冲区。一种方法可能是将交叉线转换为2d形状

不,它不会那样工作。要用纹理填充的区域应该具有某些模板值。这就是模板裁剪的工作原理。

  

以某种方式剪辑纹理

在OpenGL中,您有6个(?)剪裁平面。如果你需要更多,你需要先进的技术 - 模板,导出交叉线,着色器或三角测量。

  

您可以指出的任何在线示例也非常有帮助

Drawing Filled, Concave Polygons Using the Stencil Buffer

相关问题