分布式光线追踪器的基本思想

Basic idea of a distributed ray tracer

我想做的是改进我的实际光线追踪器以创建分布式光线追踪器。我一直在互联网上徘徊,关于它的实现我能找到的只是一些简短的东西,比如:

-用光线分布代替单条光线 - 射出分布在一个区间内的多条射线 - 通过每个像素发射多条光线并随机改变每条光线

我的问题是:"distribution" 是什么意思?如何改变通过像素的光线分布?在我的普通 Ray Tracer 中,我为每个像素拍摄一条光线。对于 "distribution" 条光线,我可以理解我应该拍摄多条光线而不是一条。但与此同时,我通过坐标 (x,y) 的像素发射光线。

for (int x = 0; x < WINDOW_WIDTH; x++)
{
    for (int y = 0; y < WINDOW_HEIGHT; y++)
    {
        Vec3<float> rayDir = camera->pixelToWorld(x, y) - camera->position;
    }
}

那么,我怎样才能 "vary each ray randomly" 呢?谢谢

有很多不同的方法可以做到这一点,这在某种程度上取决于您在当前光线追踪器实现中所做的工作。

我的方法是将问题分解为基于工作的模型。换句话说,您创建了一个作业队列,供每个工作人员处理,其中工作人员可以是线程或单独的机器。

所有工作节点都是平等的,这意味着他们可以做的工作类型没有区别。这允许您根据需要添加任意数量的工作节点(注意:在您开始变得负数之前,您可以添加的数量会有限制 returns)。

这样做的另一个好处是,您可以根据可用资源进行扩展——也许为了测试,您只需在本地计算机上使用几个线程,但是当您准备好制作 "production" 图像时,您可能想要使用额外的机器。此外,在此设置中应该可以使用单个工作线程进行渲染。

每个工作节点都需要访问场景,因此这是要发送的第一个数据块。然后他们就开始从工作队列中拉出。请务必注意,您需要以安全的方式执行此操作——只应允许一名工人申请工作。

while(active)
{
    fetch next job from job queue
    if no job is available
    {
       sleep(1)
       continue
    }

    process job
}

您需要决定的是 "job" 的含义。是单射线吗?是单条光线及其所有后续反弹吗?是一批射线吗?此负载平衡决定将取决于您的光线追踪器。单条射线可能不够用,但它是一个很好的起点。事实上,您可能应该从每个像素只有一条光线开始,然后为每条光线做一个作业。这将为您提供一个良好的基线,让您在开始工作后就可以开始。

祝你好运!

分布式光线追踪有多种用途,可用于:

(1) 抗锯齿

(2) 景深效果

(3) 运动模糊效果

对于 (1),想法只是在每个像素中发射一束光线,而不是单条光线。每条光线将通过随机 dx 和 dy(dx 和 dy 将小于像素的大小)稍微抖动 一点点 的像素中心投射。

对于(2)来说,稍微复杂一点,但大致是一样的思路:每条光线都是从观察者开始,穿过像素中心的一条线(可能会抖动,如果你做(1),但现在让我们暂时忘记它)。这一次,这是你抖动的观察者位置,你会在垂直于屏幕的方向上稍微抖动观察者的位置。同样,通过对每个像素中的许多光线的贡献进行平均,背景将比前景更多 "blurred",因为光线在背景中的偏离更大。

对于(3)来说,也是一样的思路,只不过这次是抖动的运动物体的位置。

注意:还有 (4):具有光泽效果的复杂 materials(他们需要了解一点 material,BRDF = 双向反射分布函数的概念)。