c++ - 移动立方体、体素,需要一些建议

标签 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 位置提取行进立方体案例编号 (0-255):

unsigned char GetCaseNumber(x,y,z);

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

3)渲染部分

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

结果是这样的:

terrain

但是正如您所见,在任何一个位置,分辨率都无法与以下示例相媲美: MC
(来源:angelfire.com)

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

最佳答案

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

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

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

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

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

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

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

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

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

关于c++ - 移动立方体、体素,需要一些建议,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8732961/

相关文章:

c++ - cv::TermCriteria 如何在 opencv 中工作?

c++ - 渲染 SketchUp 模型 API

google-maps - 转换 google.maps.Point 中的 (x, y) 像素坐标

c++ - WebGL 和 OpenGL 的性能

c++ - c++ 类中的 static const 和 const 变量在存储方面有区别吗

c++ - 在线程池中组织任务

c++ - 我的功能不会停止返回 -1

java - 具有基本算术和符号表达式的 Antlr4 语法

c++ - 在 constexpr GLenum 数组中存储 OpenGL 颜色附件

c++ - 无法启动 OpenGL 窗口