Marching Cubes,体素,需要一些建议

时间:2012-01-04 19:41:37

标签: c++ math opengl terrain marching-cubes

我正在尝试构建一个适当的可破坏地形,仅用于研究目的。 好吧,一切都很顺利,但解决方案并不能令我满意。 我已经看到了很多人们如何实现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坐标,并绘制这些三角形。    没问题。

所以结果如下:

terrain

但正如您所看到的,在任何一个位置,分辨率都无法与此类似: MC http://www.angelfire.com/linux/myp/MCAdvanced/mcnormal.gif

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

1 个答案:

答案 0 :(得分:7)

问题是你的体素是一个二元模板(只是打开或关闭)。

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

平滑的例子可能是由平滑的标量数据生成的。

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

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

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

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

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

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