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

Jef*_*ers 8 c++ opengl math 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];
Run Code Online (Sandbox Code Playgroud)

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

我有几个功能:

TurnOn(x,y,z);
TurnOff(x,y,z);
Run Code Online (Sandbox Code Playgroud)

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

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

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

unsigned char GetCaseNumber(x,y,z);
Run Code Online (Sandbox Code Playgroud)

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

3)渲染部分

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

所以结果看起来像这样:

地形

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

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

小智 9

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

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

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

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

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

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

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

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

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