射线投射以避免绘制看不见的面孔

时间:2015-04-17 22:59:38

标签: java opengl opencl lwjgl raycasting

我正在创建一个体素引擎。除了一些简单的单一噪声集成之外,我还创建了块生成,但由于每个四边形的所有面都被绘制出来,即使是你看不到的那些,它也非常滞后。

根据我的理解,这通常涉及使用光线投射,其中我理解基本理论:你从相机中绘制几条光线并检查碰撞,如果没有发现碰撞,那么面部不在视野内,因此不应该被渲染。虽然我理解它的理论我还没有能够实现它,因为缺乏先验知识和我在互联网上找不到的东西,即他们提供代码而不是知识。

我可以想象我需要采取的步骤如下:

  1. 学习OpenCL(虽然我之前没有使用过它,但是我可以通过使用'内核'来更好地利用你的图形卡,我在心理上将它与OpenGL'着色器'联系起来)。
  2. 学习Ray cast背后的理论和数学。我也听说过射线追踪,我相信它有不同的用途。
  3. 了解如何使用此信息不渲染隐藏的面孔。假设我得到一个有效的实现,我怎么去告诉OpenGL不要渲染隐藏的面孔?立方体是一个对象,据我所知,没有办法只在顶点中操作OpenGL中对象的面。 OpenCL如何与OpenGL通信? OpenCL不是图形API,因此无法绘制光线。
  4. 有人能指出我正确的方向吗?我也相信有纯粹的OpenGL实现,但我想保留OpenCL方面,因为这是一种学习体验。

2 个答案:

答案 0 :(得分:1)

我不建议在开发你的第一款游戏时使用OpenCL或OpenGL,两者都会让你失望,因为每个人都需要不同的心态。 尽管你已经做得很好了。

您提到您当前正在渲染所有要删除隐藏的四边形的四边形。我也为练习编写了一个体素引擎,并遇到了这个问题,花了很多时间思考如何修复它。我的解决方案是不要画出面对另一个体素的面孔 想象一下,彼此相邻的两个体素,两个看不见的面孔,不需要渲染。

但是,如果您与GPU交谈的方法是瓶颈,这将没有任何区别。您将不得不使用缓冲方法,我使用了显示列表,但也可以(但更难)使用VBO。

我还建议将大量体素分组成块,原因有很多。然后,您只需要重新计算更改的块上的可见四边形。

关于光线投射,如果采用我刚刚描述的块系统,计算可见的整个卡盘将更容易。例如,玩家背后的块不需要渲染,只需每个块一个点积计算即可。

答案 1 :(得分:0)

  

学习OpenCL(虽然我之前没有用过它来理解它   允许您通过使用更好地利用您的图形卡   '内核',我在心理上与OpenGL'着色器'相关联。)

Amd app sdk有许多示例/样本,从排序数字到在茶壶上进行3d流体计算。您也可以使用带有opencl的cpu,但可以将多个cpu视为单个设备。此外,Nvidia和jocl以及lwjgl都有样品等待进行崇拜。

  

学习Ray cast背后的理论和数学。我也听说过   光线跟踪,我相信有不同的用途

我只知道如果那些光线投射出新光线,光线投射会成为一种追踪。很多矢量代数,如交叉积,点积,方向矢量归一化,3x3 4x4矩阵乘法等等。高阶递归对于gpu是不好的。尝试使用迭代版本。

  

了解如何使用此信息不渲染隐藏的面孔。

您可以对光线相交的表面图元的距离进行排序,并获得最小距离。如果表面上没有折射,则不应该看到其他人。使用加速结构(有界的bolume层次结构,......)会有所帮助。

  

立方体是一个对象,据我所知,没有办法   仅在顶点中操纵OpenGL中对象的面。

在opencl中生成,将其传递给opengl,比立即模式更快。<​​/ p>

  

OpenCL如何与OpenGL通信? OpenCL不是图形   api所以它无法绘制光线。

使用“共享”属性创建上下文,以便能够使用gl-cl“interop”。这使得opencl-opengl通信的速度与gpu-vram一样快(高端为300 GB / s)。然后在此上下文中使用gl缓冲区作为cl缓冲区,并在cl和gl之间进行适当的同步。(glFinish()compute()clFinish()drawArrays())

如果它不是互操作,则通信将与pci-e带宽一样慢。然后,如果计算数据比率很低,则从cpu生成会变得更快。

如果要播放多个gpus,那么您应该尽可能缩短数据。检查结束,结构对齐。不要忘记定义opencl(设备)端结构,如果主机端有任何一个,并且它们必须是1-1兼容的。