我的 Coding Adventure 体素地形(三)
体素地形常见的面生成方案有 Marching Cubes, Surface Nets, Dual Contouring
这里只是简单介绍一下~
Marching Cubes(移动立方体) 应该是最著名的等值面提取算法,历史悠久, 也比较容易实现
原理大致就是把空间分割成体素网格, 每个单元格就是是一个立方体,判断每条边的两个顶点是处于表面外还是表面内, 当一条边的一个顶点在内,一个在外的时候, 在这条边上就存在一个分界点
图中 v0 处处于表面内,其他全部顶点都在表面外,所以和 v0 相邻的三条边上存在分界点,构成了一个面8个顶点的不同内外状态会产生不同的组合
图中是过滤掉对称形态之后的15种不同组合拼合体素网格中存在的面,就可以得到生成的形状
mc的算法无法还原尖锐的特征,所以最后生成的形状总是有些圆润的
Surface Nets(表面网)
Minecraft 那种方块表面很容易生成, surface nets 就是想办法将尖锐的顶点位移使表面平滑,算法不那么固定,可以是将顶点逼近周围临近单元格位置的平均值,也可以是想办法逼近等值面等
surface nets 的目的就是平滑...所以结果也是圆润的
Dual Contouring(对偶轮廓)
DC算法生成的顶点的位置在体素块的内部, 用一组 Hermite Data 来评估顶点位置和顶点法线
当需要采样的面穿过体素块时, 面会和体素块的某些边相交
Hermite Data 记录了: 相交的边, 相交的位置, 交点处面的法线
使用QEF(quadratic error function) 来计算顶点位置和法线, 不过计算的位置有时会超出单元格,这时候可以使用单元格的中心位置
相比 Marching Cubes 总是在边上生成顶点 ,Dual Contouring 可以在网格内部评估顶点位置, 可以保留尖锐的特征每条和被采样的面有交点的边, 有4个相邻的体素块, 这4个体素块中的顶点, 构成一个4边形(两个三角面), 面的方向(正反)可以由这条边的两个顶点哪个在被采样的面内,哪个在外决定
迭代体素网格就可以生成完整的 Mesh
最后我选用了 Dual Contouring, 因为生成的形状质量最好, 而且容易实现lod和处理接缝问题
看着挺唬人的, 其实用在地形上, 效果倒不会差别这么大