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

Posted

技术标签:

【中文标题】如何裁剪任意形状的纹理?【英文标题】:How to clip texture with arbitrary shape? 【发布时间】:2013-09-26 14:44:47 【问题描述】:

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

接下来我对这些对象应用一个剪切平面并在这个平面上渲染一个纹理,给人的印象是你正在查看对象的内部,就好像它被切片了一样。例如:

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

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

我在这里:

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

我一直在阅读模板缓冲区。一种方法可能是将相交线转换为 2d 形状并将其绘制到模板缓冲区中。然后在绘制纹理时应用它。 (虽然我认为这是很多工作,因为形状可能很复杂。)

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

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

【问题讨论】:

【参考方案1】:

如果您正在剪裁凸形对象并且知道剪裁点的坐标,您可以自己创建多边形“帽” - 只需使用 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)) 绘制正面。然后仅在 stencil 非零的地方绘制纹理。 (glStencilFunc(GL_GREATER, 0, 0xff); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);)。但是,如果您有许多重叠的形状,则需要特别注意它们。

--编辑--

但是,我不确定如何处理此信息(或者这是否是最好的方法)。

把它画成三角扇。对于凸面物体,这就是您所需要的。对于不起作用的非凸对象。

一直在阅读模板缓冲区。一种方法可能是将相交线变成二维形状

不,它不会那样工作。您要填充纹理的区域应具有一定的模板值。这就是模板剪辑的工作原理。

以某种方式裁剪纹理

在 OpenGL 中,您有 6(?) 个裁剪平面。如果您需要更多,您将需要高级技术 - 模板、导出相交线、着色器或三角测量。

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

Drawing Filled, Concave Polygons Using the Stencil Buffer

【讨论】:

感谢@SigTerm。我能够使用您描述的方法使其与模板缓冲区一起使用。这个page 也有关于这个技术的更多信息。

以上是关于如何裁剪任意形状的纹理?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 OpenCV 从垫子上裁剪任意形状?

OpenGL GLSL 通过任意形状混合两个纹理

在android中对图像进行手绘裁剪

安卓啥软件可以把图片裁截成任意形状

确定一个点是不是位于任意形状内?

如何求任意形状张量的元素和