3

我有一个程序,我需要在其中应用二维纹理(简单图像)到使用 Marching-cubes 算法生成的表面。我可以访问几何图形并且可以相对轻松地添加纹理坐标,但是生成坐标的最佳方法是躲避我。

体积中的每个点代表一个数据单元,每个数据单元可能具有不同的属性。为了简化事情,我正在考虑将它们分类为“类型”并为每种类型分配一个纹理(或单个大型纹理图集的一部分)。

我的问题是我不知道如何生成适当的坐标。我可以将类型纹理的位置存储在类型类中并使用它,但是接缝会被严重拉伸(如果两个相邻点使用图集的不同部分)。如果可能的话,我想在接缝处混合纹理,但我不确定这样做的最佳方式。混合是可选的,但我需要以某种方式对顶点进行纹理处理。可以将几何图形拆分为每种类型的部分,或者复制顶点以用于纹理化目的,但这是不可取的。

如果可能,我想避免使用着色器,但如有必要,我可以使用顶点和/或片段着色器来进行纹理混合。如果我确实使用着色器,那么告诉它是纹理还是要采样的部分的最有效方法是什么?似乎通过参数传递类型是最简单的方法,但可能很慢。

我的体积相对较小,每个维度有 8-16 个点(我将它们保持较小以加快生成速度,但在给定时间屏幕上有很多)。我简要地考虑过使等值面成为体积分辨率的两倍,因此每个点都有更多的顶点(理论上是 8 个),这可以简化纹理。不过,这似乎不会让混合变得更容易。

为了构建表面,我使用了OpenGL 的可视化库及其行进立方体和体积系统。我的几何生成很好,只需要弄清楚如何纹理它。

有没有办法有效地做到这一点,如果有的话怎么办?如果没有,是否有人知道处理体积纹理的更好方法?

编辑:请注意,纹理不仅仅是颜色的渐变。它实际上是一种纹理,通常带有图案。因此,映射它的困难,梯度将是微不足道的。

编辑 2:为了帮助澄清问题,我将添加一些示例。他们可能只是混淆了事情,所以如果可以的话,把所有事情都考虑在确定的事实之上,这些都只是帮助。

我的几何图形总是在立方体中(在立方体中加载、生成和保存)。如果形状影响可能的解决方案,就是这样。

我需要将由图案和/或颜色(取决于点的“类型”的独特的)组成的纹理应用到几何体,其技术类似于为地形完成的飞溅(但这不是地形,所以我不'不知道是否可以使用相同的技术)。

着色器是一种快速简便的解决方案,尽管我想尽可能避免使用它们,正如我之前提到的。可用于固定功能管道的东西更可取,主要是为了稍微增加兼容性和开发时间。因为它只是一个小的增加,如果需要,我将使用着色器和多通道渲染。

不确定是否需要任何其他澄清,但我会根据需要更新问题。

4

4 回答 4

2

关于问题的纹理组合部分:

您是否研究过 3d 纹理?当我们谈论行进立方体时,我可能应该立即说我明确地不是在谈论体积纹理。相反,您将所有 2d 纹理堆叠成 3d 纹理。然后,您将每个纹理坐标编码为二维位置,并将其引用的纹理作为第三个坐标。如果您的纹理通常属于从一种类型的模式过渡到另一种模式的类型,那么它的效果最好,您必须通过中介。

一个明显的使用示例是将纹理映射到简单的高度图——您可能在顶部有雪纹理,在其下方有岩石纹理,在其下方有草纹理,在底部有水纹理。如果引用水的顶点在引用雪的顶点旁边,那么几何填充过渡到岩石和草地纹理是可以接受的。

另一种方法是使用添加剂混合在多个通道中进行。对于每个纹理,绘制使用该纹理的每个面,并绘制一个渐变到透明,延伸到从一个纹理切换到另一个纹理的任何面。

您可能希望通过完整的绘制来准备深度缓冲区(所有颜色掩码都设置为拒绝对颜色缓冲区的更改),然后切换到 GL_EQUAL 深度测试并在禁用写入深度缓冲区的情况下再次绘制。通过完全相同的变换绘制完全相同的几何图形应该产生完全相同的深度值,而不管准确性和精度的问题。如果您有问题,请使用 glPolygonOffset。

在坐标部分:

流行和简单的映射是圆柱形、盒子和球形。将您的形状概念化为圆柱体、长方体或球体,从表面点到纹理位置的映射定义明确。然后对于形状中的每个顶点,从它开始并遵循法线,直到碰到边界几何。然后抓取边界几何上该位置的纹理位置。

我想有一个潜在的问题是法线在行进立方体后往往不聪明,但我敢打赌你比我更了解这个问题。

于 2010-11-03T21:48:05.143 回答
1

这是一个困难而有趣的问题。

最简单的方法是通过使用 3D 纹理贴图完全避免该问题,特别是如果您只想将一些随机表面细节添加到等值面几何体中。在着色器中实现的基于 Perlin 噪声的程序纹理对此非常有效。

困难的方法是研究用于保形纹理映射(也称为保形表面参数化)的各种算法,其目的是在 2D 纹理空间和 3D 几何体的表面之间产生某种意义上的最优(失真最小)的映射。这篇论文有一些很好的图片。请注意,几何的拓扑非常重要;很容易生成保形映射以将纹理映射到像大脑这样的封闭表面上,对于需要引入切割/撕裂/连接的更高属对象来说要复杂得多。

于 2010-11-04T00:46:37.797 回答
0

您可能想尝试在 Blender 之类的工具中制作网格的 UV 贴图,看看他们是如何做到的。如果我理解你的问题,你有一个 3D 字段,它定义了一个实体体积以及一个(连续的)颜色。您已经从体积创建了一个网格,现在您需要将网格 UV 映射到一个 2D 纹理,其中纹素是从连续颜色空间中提取的。在一个工具中,您可以在 3D 网格中定义“接缝”,您可以将其切开,以便将整个网格平放以制作 UV 贴图。接缝处的纹理可能存在锯齿,因此当您渲染网格时,这些接缝处的网格也会不连续(即三角形条不能穿过接缝,因为它是纹理中的不连续性)。

我不知道任何使网格变平的正式方法,但您可以想象沿着接缝切割它,然后将整个东西视为一个弹簧/约束系统,然后将其放在平坦的表面上。我只想以艰难的方式解决问题。;-)

于 2010-11-03T20:19:46.320 回答
0

由于纹理问题和我的一些约束,我选择编写不同的算法来构建几何图形并在生成曲面时直接在其中处理纹理。它不如行进立方体平滑,但允许我以适合我的项目的方式应用 texcoords(并且速度更快)。

对于任何对纹理行进立方体或只是混合纹理感兴趣的人,Tommy 的回答是一种非常有趣的技术,并且 timday 发布的链接是用于纹理化网格的极好资源。感谢他们两位的回答,希望他们可以对其他人有用。:)

于 2010-11-07T19:03:00.537 回答