我正在尝试构建一个适当的可破坏地形,仅用于研究目的。 好吧,一切都很顺利,但解决方案并不能令我满意。 我已经看到了很多人们如何实现MC算法的例子,但其中大部分都是 据我所知,使用函数来对最终网格进行三角测量,而不是 适合我。
我将简要地解释一下我是如何构建我的地形的,也许是某人 你会给我一些建议,如何改善或提高最终地形的分辨率。
我正在针对每种情况(0-255)运行MC查找表的简单循环并计算三角形 愤怒:[0,0,0] - [1,1,1]。 这里没问题。
我有地形类,它存储我的体素。 一般来说,它看起来像这样:
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);
通过确定该体素的邻居是打开还是关闭。 这里没问题。
我循环每个轴,提取案例编号,然后按案例获得预先计算的三角形, 转换为x,y,z坐标,并绘制这些三角形。 没问题。
所以结果如下:
但正如您所看到的,在任何一个位置,分辨率都无法与此类似: MC http://www.angelfire.com/linux/myp/MCAdvanced/mcnormal.gif
我在MC的例子中看到人们正在使用一种叫做“iso值”的东西,我不明白。 任何建议如何改进我的工作,或什么是iso值,以及如何在统一网格中实现它将是非常可爱的。
答案 0 :(得分:7)
问题是你的体素是一个二元模板(只是打开或关闭)。
这对于“默认”行进立方体算法非常有用,但它确实意味着您在网格中获得了锐利的边缘。
平滑的例子可能是由平滑的标量数据生成的。
想象一下,如果您的数据在0到1.0之间平滑变化,并且您将阈值设置为0.5。现在,在检测到给定多维数据集的配置后,您将查看生成的所有顶点。
说,在两个体素之间的边缘上有一个顶点,一个值为0.4,另一个值为0.7。然后将顶点移动到在0.4和0.7之间插值时准确得到0.5(阈值)的位置。所以它将更接近0.4顶点。
这样,每个顶点都在插值 iso表面上,您将生成更平滑的三角形。
但它确实要求您的输入体素是标量(并且平滑变化)。如果你的体素是双层的(全部为0或1),这将生成与之前相同的三角形。
另一个想法(不是你的问题的答案,但可能有用):
为了获得更平滑的渲染,没有数学正确性,可能值得为每个顶点计算平均法向量,并对连接到它的每个三角形使用该法线。这将隐藏锋利的边缘。