如何裁剪任意形状的纹理? [英] How to clip texture with arbitrary shape?

查看:209
本文介绍了如何裁剪任意形状的纹理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在渲染复杂的3d对象.这是一个带有球形物体的简单示例:

接下来,我将剪切平面应用于这些对象,并在该平面上渲染纹理,给人的印象是您在查看对象的内部,就好像它已被切片一样.例如:

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

我想要的是能够以某种方式剪切纹理,以使其永远不会伸出表面的边界.此外,我也不想简单地按比例缩小纹理,因为尽管这可能会阻止其向外粘贴,但会在纹理边缘和表面边缘之间形成内部间隙.我宁愿纹理太大,并修剪它,以使其与表面边缘齐平.

我在这里:

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

我一直在阅读模板缓冲区.一种方法可能是将相交线变成2d形状并将其绘制到模板缓冲区中.然后在绘制纹理时应用它. (尽管我认为这很麻烦,因为形状可能很复杂.)

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

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

解决方案

如果要剪切凸对象并知道剪切点的坐标,则可以自己创建多边形帽"-只需使用GL_TRIANGLE_FAN以适当的顺序绘制剪切点,就是这样.不适用于非凸对象-需要三角剖分算法.您可以使用 glu镶嵌器来对多边形进行三角剖分,但这可能会很棘手/困难.

如果可以通过公式定义裁剪区域,则可以编写一个着色器,该着色器将精确裁剪特定距离(即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个(?)剪辑平面.如果您需要的还不止这些,那么您将需要高级技术-模具,派生相交线,着色器或三角剖分.

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

使用模板缓冲区绘制填充的凹多边形

I am rendering complex 3d objects. Here is a simple example with a sphere-like object:

Next I am applying a clipping plane to these objects and rendering a texture on this plane, giving the impression you are looking at the inside of the object, as if it was sliced. For example:

The problem is the jagged edge of the texture. It will stick out passed the boundary of the surface. Here's another angle where you can see it sticking out. The surface and the texture both derive from the same source data, but the surface is smoothed and has a higher resolution than the texture.

What I want is to be able to somehow clip the texture, so that it never sticks out past the boundary of the surface. Also, I don't want to simply scale down the texture, since although this might prevent it from sticking outside, it would create interior gaps between the texture edge and the surface edge. I would rather the texture be a little too big and have it clipped so that it sits flush against the edge of the surface.

Here's where I am:

I figured the first step would be to define the intersection of the plane and the surface. So now I have that, as an ordered list of line segments. However, I'm not sure how to proceed with this info (or if this is even the best approach).

I've been reading up on stencil buffers. One approach might be to turn the intersection line into a 2d shape and draw this into a stencil buffer. Then apply this when drawing the texture. (Although I think it's a lot of work since the shapes can be complicated.)

I am wondering if I can somehow use the already drawn surface (in conjunction with a stencil buffer or some other technique) to somehow clip the texture -- without having to go through the extra trouble of deriving the intersection line, etc.

What's the best approach here? (Any online examples you can point me to would also be really helpful.)

解决方案

If you're clipping convex objects and know coordinates of clipped points, you can create polygonal "cap" yourself - just draw clipped points in proper order using GL_TRIANGLE_FAN, and that's it. Won't work with non-convex object - that would require triangulation algorithm. You could use glu tesselators to triangulate polygons, but that can be tricky/difficult.

If clipped area can be defined by formula, you can write a shader that'll precisely clip pixels over certain distance (i.e. if x^2+x^2+z^2 > r^2 do not draw pixel).

You could also draw back-facing faces with a shader that would draw every back facing pixel as if it were on on clip-plane using simple raytracing. That's complicated, and might be overkill in your case. Dead Rising used similar technique in their game engine.

Also you can use stencil buffer.

Draw back-facing faces first with GL_INCR (glStencilOp(GL_KEEP, GL_INCR, GL_INCR)), then draw front-facing surfaces with GL_DECR (glStencilOp(GL_KEEP, GL_DECR, GL_DECR)). Then draw texture only where stencil is non-zero. (glStencilFunc(GL_GREATER, 0, 0xff); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);). If you have many overlapping shapes, however, you'll need to take special care of them.

--edit--

However, I'm not sure how to proceed with this info (or if this is even the best approach).

Draw it as a triangle fan. For convex objects, that's all you need. For non-convex objects that won't work.

ve been reading up on stencil buffers. One approach might be to turn the intersection line into a 2d shape

No, it won't work like that. Region you want to fill with texture should hold certain stencil value. That's how stencil clipping works.

to somehow clip the texture

In OpenGL you have 6(?) clip planes. If you need more than that, you'll need advanced techniques - stencil, deriving intersection line, shaders, or triangulation.

Any online examples you can point me to would also be really helpful

Drawing Filled, Concave Polygons Using the Stencil Buffer

这篇关于如何裁剪任意形状的纹理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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