请选择 进入手机版 | 继续访问电脑版

开源计算机图形学社区(Open Source Computer Graphics Community) |OpenGPU Forum (2007-2013)| OpenGPU Project

 找回密码
 注册
搜索
查看: 1040|回复: 0

体素(Voxel)显示学习中 [复制链接]

Rank: 12Rank: 12Rank: 12

注册时间
2012-7-21
积分
656
发表于 2016-12-23 10:47:18 |显示全部楼层
本帖最后由 quadpixels 于 2016-12-30 10:33 编辑

大家好,我又肥来了
我想知道类似 Minecraft 那样的体素世界是如何显示的。
我现在能有的线索只是“Octree”这个关键词。因为它能够在 GPU 上方便高效地进行处理,所以掌握了应该能够受用很久。
近日的一些探索的过程就顺便记录在这里吧。

12月的前两个星期:从最基本的数据结构 到 CPU 上的 Raycast (是个未完并且抛弃了的坑)
首先看了看《How to make a Voxel Engine》,知道应该把一个大世界分成小的 Chunk 来处理。这样的好处可能是进行视锥剔除时比较方便。
所以就定义了数据结构和用 glutSolidCube() 来画 Chunk 的方法…
同时又经历了一遍复习 OpenGL 的变换流程的过程,知道了怎么将屏幕上鼠标的点击转换成世界坐标系中的射线。
有了射线之后,就完成了用 DDA 的方法遍历一个 Chunk 的方法,以及选取一个体素的方法。
有了这个方法,其实已经就可以 Raycast 一个 Chunk 了!但是还是先把 Octree 做出来罢。
于是就把 Octree 的插入、查找和迭代完成了。都不是最优的,后来发现用于 Raycast 还是很慢。但总之还是完成了。
在做 Raycasting 的时候,左边显示用 OpenGL 画出的画面,右边显示 Raycast 出来的画面。嗯。方块对应的位置都差不多。说明大概位置的计算应该没有问题(虽然速度不怎么样。)
想试试看这个 Octree 最大能够处理多大的数据,就去 gltracy 的 Github 上下载了他的一些 SVO 体素数据。
我的导入是每读到一个体素都通过 Octree 自根结点向下插入一个 Voxel 来做的,所以速度很慢,要几分钟才能导入 1024^3 的数据。所以就最多只尝试了 512^3 的数据。
结果:在 Core 2 T9600 的 CPU 上,如果开 4 个线程,在 640x480 的画面下能达到 3~7 FPS。(依显示的角度不同而不同)(如果拿一个强力的 CPU,比如 i5-4570,能达到 20~30 FPS)
这个性能距离网上的人达成的结果有差距。因为有人用 迅驰 1.66 GHz 达成了 1280x720 画面、1024^3 的体素下 7 FPS 的成绩。所以我的实现中有很多不够快的地方。
后来还尝试了两种更不成熟的优化。第一是将原先递归式的 Octree 遍历换成了非递归的(用一个 std::stack 模拟栈),性能变差了。第二是尝试写出 Ray Packet 的方式,性能又变差了。现在我还不清楚为什么会变差,但是以后有时间一定要再检查一下。
那么,经历这些不成熟的优化之后我感觉目前的这摊东西可能不能满足实时的 Raycast 的需求,那不如先去解决最初的问题:怎么才能显示体素呢?现在看来,在体素世界比较小的情况下 Raycast 比直接用 OpenGL 显示要慢太多了,那不如先暂放弃 Raycast 的想法得了。
其实更值得尝试的优化方法是利用体素原本的特点进行 LOD,但是既然这个 LOD 在用 OpenGL 进行显示时也必然会在某个时候遇到,所以也可以到那时再研究。
用一张 Raycast 的结果纪念目前的状态


12月的后两个星期:改为直接用 OpenGL 显示并加入 SSAO
有了之前在 Raycasting 上撞墙的经历,一些用到 Octree 的地方,就因为先前的经验而变简单了。比如:视锥剔除。
虽然之前的 Raycast 的部分全被暂时放弃了,但是用 Octree 来组织所有的 Chunk 的结构还是保留了下来。所以在显示时也是遍历 Octree 的。
在遍历时做视锥剔除就是很自然的,因为可以直接与 Octree 结点所对应的 AABB 来进行求交。有了视锥剔除,帧率就更加稳定了一点。

然后就想搜罗一些已有的 OpenGL 特效加入进来。
在 Github 上找到了一个 SSAO 的演示,大概明白了其原理。
结果发现它是用 OpenGL 3.3 写成的,用到了 GLSL 3.3。而我到目前为止用的都是 Legacy OpenGL,必须将所有代码都替换成 OpenGL 3.3 的。
替换的过程经历了三天。
那个演示中的投影矩阵和我的不太一样,他的 Y 在 Shader 中与我是相反的。
把这个地方改正了之后,就有了如下的画面。


接下来,我想加入颜色与阴影,以及现有模型的导入(我主要知道的体素工具是 MagicaVoxel,所以打算就先导入 MagicaVoxel 的数据。看起来它的格式是以命令的形式组织而成的格式)

2016-12-27:加了一点点颜色与阴影。做出来的画质还很差,打算找个时间一起修理


2016-12-28:搭了一些 deferred shading 的基本结构(其实也就是 G Buffer) … 不过在这个图里可能看不出来。
现在烦恼的事情是帧速太低了,需要 profile 一下找到速度慢的原因。


未完待续


最近看过此主题的会员

您需要登录后才可以回帖 登录 | 注册

‹‹
我的工具栏

关于我们|手机版|Archiver|开源计算机图形学社区(Open Source Computer Graphics Community) | OpenGPU Project | OpenGPU Forum (2007-2013)

GMT+8, 2017-1-25 09:25 , Processed in 0.083778 second(s), 12 queries .

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部