4

我正在创建一个光线追踪的我的世界风格体素引擎。我将关卡存储在单个 3d 数组中,其中每个值代表体素的类型,例如 0 = 空气,1 = 石头等。稍后体素将需要具有某些属性,例如某些可能是纹理的,并且在放置它们时可能必须执行某些操作。

我想到的第一个也是最明显的解决方案是有一个基础体素类,其中包含 OnPlace 等方法,这些方法将由其他类型派生。但我不确定如何将其链接回地图,我需要一种非常快速(光线追踪如此缓慢)且灵活的方法,但我不知道。有什么建议吗?

4

5 回答 5

3

明显的方法是拥有 3d 对象数组 (of class Voxel) 并使用location = {int x, int y, int z};.

请注意,将引用从“体素”完全退回到位置可能是个好主意,这样您就不需要每个单元格使用唯一的对象。您可以考虑使用享元模式来共享类似“体素”对象的大部分日期,即使您仍然必须保留对地图的引用。

于 2013-05-29T18:56:14.950 回答
3

我认为您需要使用Dictionary。可以给每个类一个 ID,您可以轻松地将其放入公共只读属性中。然后创建一个字典,键是 ID,值是类类型。这样,您可以有效地存储关卡并使用字典(快速但在内存中有些昂贵)来查找每个块应该如何呈现。

当程序启动以创建字典时,您需要使用反射并遍历体素基类的所有子类。

如果您计划支持模组/插件,您需要能够搜索比您自己的程序集更多的内容(最难的部分是获取对其程序集的引用,之后它只是回收的代码)但现在只需从您自己的程序开始。

于 2013-05-29T18:53:31.917 回答
0

我并不完全是您要问的,因为当您说“枚举类”时,我会想到使用反射迭代对象属性;显然这不是你想要做的。

对我来说,听起来您的 3D 数组应该包含对象而不是整数。如果您有一个Voxel所有体素都从您那里继承的基类,则不需要类型说明符。相反,您只需将抽象方法放在基类中,然后在派生类中覆盖它们。一旦你完成了所有这些设置,任何处理数组的代码都应该能够在不知道派生类的类型的情况下与之交互。

应用程序代码应该只将其视为类型数组Voxel。对任何给定的调用方法都Voxel应该执行特定于该类型体素的行为。这就是继承和多态的基本思想。

于 2013-05-29T18:57:27.290 回答
0

好的,您的性能瓶颈不是“选择体素类型”。它是对数百万条光线(每像素至少1 条,但每像素只有 1 条光线无法获得良好的渲染)的交叉和碰撞检测,您需要以 60fps 的速度进行跟踪。

这些天来做这种疯狂的唯一方法是使用 GPU 光线追踪

所以你主要关心的不是“使用什么数据结构”来确定体素类型。它是 GPU 上的高效光线相交代码。

NVIDIA 目前有一个名为Optix的光线追踪引擎。

于 2013-05-29T18:59:56.023 回答
0

很大程度上取决于您需要遍历数据以呈现体素的方式。对于渲染八叉树可能是一个不错的解决方案(或者可能是Kd 树

我建议您首先关注需要什么样的访问(可能通过测试),然后进行优化。

于 2013-05-29T19:04:28.343 回答