相对论光线追踪和球面纹理

时间:2016-01-27 15:14:46

标签: c++ rendering gpu

问题

我需要一些关于哪些技术和编程环境用于我的具体问题的建议。

问题

如果空间中有一个重物,其上面有一个静态表面,那么Schwarzschild的半径是多少,那么位于太空中的人怎么会看到它的表面(照明会被忽略)?例如,人们可能会想象一个中子星 请参阅:https://en.wikipedia.org/wiki/Neutron_star,我的程序应该会生成与网站上的图片类似(但更详细)的图片。

请注意,该程序应该能够在每秒渲染几帧并且在FPS中自由观看和移动“喜欢”。

我想用NON-Euclidean相对论空间中的光线追踪来解决这个问题 要做到这一点,我需要解决约1000个独立的微分方程,它们确定射线会撞到地面的位置。

ODE是u''+ u = 3Ru ^ 2/2,u和u'的初始条件,R是常数。一旦你离开定义的边界,它就会终止。所以解决这个问题不会太复杂。

之后我会为每个像素做一些例程:

  • 转换为相对于某个方向的拼写坐标(如果是分支,则为
  • 应用一些特殊的相对论角度校正(可能是一些没有分支的简单功能)
  • 通过应用微分方程定义的插值函数,将角度的一部分转换为曲面上的角度。没有碰到表面的像素现在应该是黑色的。
  • 将角度转换回某些规范的球体坐标(无分支)。
  • 不确定这一点:对于表面图形,最初计算了一个精确的Delaunay三角剖分,并且对于每条光线,通过加权相应三角形角的颜色来确定颜色。但如果有人想出更好的主意,我会很高兴。

我很感激C / C ++ / C#like environment

问题:

  • 什么样的框架适合我的问题?
    open GL似乎专注于欧几里德射线追踪,这在这种设置中毫无用处 CUDA会限制我使用Nvidea gpus
    可以打开cl是正确的吗?
  • 描述的操作是否可在GPU上执行?
    我特别担心从各种处理器并行访问插值函数数据。对于我来说,在Delaunay三角测量中并行定位(O(log(#vertices)和分支)大量光线似乎也是一个问题。开放式问题
  • 您是否有更好的想法来表示表面上的图形并确定某个位置应该具有什么颜色?
  • 计算GPU上的差分方程是否值得一试?它们通过runge kutta方法求解,并在任意时间后终止。

关于我的知识水平:

我是数学学生,上面的问题涉及我的Bac。论文。
我有一些C ++的经验,并且已经在C#和Gtk中学习过GUI。编码不是我的日常活动,但我没有标准的麻烦 一旦我的论文结束,我将分享结果。

1 个答案:

答案 0 :(得分:1)

以下是我对所提问题的建议:

这是非常好的,你的ODE是独立的(适合并行执行),你可以使用固定步骤集成(没有线程分歧),因为这使你的问题非常适合GPU。

这里可能有用的库之一是boost :: odeint,它提供了最流行的ODE集成商(包括Runge-Kutta)的实现。它还支持GPU加速计算,但是在这种情况下,您必须使用device_vector作为状态类型,并且必须使用thrust :: for_each转换作为您的等式(在您的情况下可能很难实现)。似乎推力库不仅支持Nvidia GPU,但我不确定。

如果推力库函数不适合您的问题,您可以使用CUDA或OpenCL提供自己的Runge-Kutta实现(不是很复杂)和您的ODE定义。如果你决定使用CUDA,并且你能够使用具有3.5或更高计算能力的设备,你可以利用所谓的“动态并行”,它允许你调用内核函数(在CUDA中,这是一个运行的函数)在GPU上)来自另一个内核函数,它有效地允许您从另一个线程创建一些线程。例如,您可以使用5个线程(5点Runge-Kutta)调用RungeKutta方法,并且可以从每个线程调用1000个线程进行ODE计算(每个线程计算一个等式)。现代GPU通常具有超过10个SM(流式多处理器),并且每个SM能够处理2048个线程,因此您可以执行每个集成步骤,只需一个计算分割超过5000个线程。如果您决定使用OpenCL,我不确定此功能。

你的下一步(坐标变换等)看起来非常适合于thrust :: for_each函数,但如果事实证明它们不是,你可以再次使用CUDA / OpenCL接口。

至于最终的图形表示,我不能给你任何建议,但我想你可以简单地使用任何图形库(包括OpenGL),只需手动将像素放在它们的位置。

最后,在您的项目中,表现非常重要。请记住使用一些探查器(例如Nvidia visual profiler)来调查您的代码并找出哪个部分最慢。您还应该编写单元测试,不仅要测试代码中的潜在错误,还要单独测试项目每个部分的性能。

当然,您可以在C ++中执行此操作。