8

我正在尝试构建一个适当的可破坏地形,仅用于研究目的。好吧,一切都很顺利,但分辨率还不够让我满意。我已经看过很多人们如何实现 MC 算法的示例,但据我所知,其中大多数使用函数对最终网格进行三角剖分,这不适合我。

我将尝试简要解释我是如何构建我的地形的,也许你们中的一些人会给我建议如何改进或提高最终地形的分辨率。

1) 预先计算 MC 三角形。

我正在为每个案例(0-255)运行简单的循环遍历 MC 查找表并计算愤怒的三角形:[0,0,0] - [1,1,1]。这里没有问题。

2) 地形

我有地形类,它存储我的体素。一般来说,它看起来像这样:

int size = 32;//Size of each axis.
unsigned char *voxels = new unsigned char[(size * size * size)/8];

因此,每个轴的长度为 32 个单位,但是,我存储每个位的体素信息。意思是如果位打开(1),有一些东西,应该有一些东西。

我有几个功能:

TurnOn(x,y,z);
TurnOff(x,y,z);

打开或关闭体素的位置。(有助于使用位)。

一旦分配了地形,我就会运行 perlin 噪声,并打开或关闭位。

我的地形类还有一个功能,从 x,y,z 位置提取 Marching Cubes 案例编号 (0-255):

unsigned char GetCaseNumber(x,y,z);

通过确定该体素的邻居是打开还是关闭。这里没有问题。

3) 渲染部分

我正在循环每个轴,提取案例编号,然后按案例获取预先计算的三角形,转换为 x、y、z 坐标,并绘制这些三角形。这里没有问题。

所以结果看起来像这样:

地形

但正如您所看到的,在任何单个位置,分辨率都无法与例如此相比:( 来源:angelfire.comMC

我在 MC 示例中看到人们正在使用一种叫做“iso values”的东西,我不明白。任何关于如何改进我的工作的建议,或者什么是 iso 值,以及如何在统一的网格中实现它都会非常可爱。

4

1 回答 1

10

问题是你的体素是一个二进制掩码(只是打开或关闭)。

这对于“默认”行进立方体算法非常有用,但这确实意味着您在网格中获得了锐利的边缘。

平滑示例可能是从平滑标量数据生成的。

想象一下,如果您的数据在 0 和 1.0 之间平稳变化,并且您将阈值设置为 0.5。现在,在您检测到给定立方体的配置后,您可以查看生成的所有顶点。

假设您在两个体素之间的边上有一个顶点,一个值为 0.4,另一个值为 0.7。然后,您将顶点移动到在 0.4 和 0.7 之间插值时恰好得到 0.5(阈值)的位置。所以它会更接近 0.4 顶点。

这样,每个顶点都恰好在插值iso 表面上,您将生成更平滑的三角形。

但它确实要求您的输入体素是标量的(并且变化平滑)。如果你的体素是双层的(都是 0 或 1),这将产生与你之前得到的相同的三角形。

另一个想法(不是您问题的答案,但可能有用):

为了获得更平滑的渲染,没有数学上的正确性,计算每个顶点的平均法线向量,并为连接到它的每个三角形使用该法线可能是值得的。这将隐藏锋利的边缘。

于 2012-01-04T20:05:11.167 回答