C++ 分布式光线跟踪器的基本思想

C++ 分布式光线跟踪器的基本思想,c++,sampling,raytracing,C++,Sampling,Raytracing,我想做的是改进我的实际光线跟踪器,创建一个分布式光线跟踪器。我一直在互联网上闲逛,我所能找到的关于它的实现的只是一些简短的东西,比如: -用光线分布替换单个光线 -在一段时间内发射多条射线 -通过每个像素拍摄多条光线,并随机改变每条光线 我的问题是:“分配”是什么意思?如何改变穿过像素的光线分布?在我的普通光线跟踪器中,我每像素拍摄一条光线。对于光线的“分布”,我可以理解我应该拍摄多条光线,而不是只拍摄一条。但与此同时,我用坐标(x,y)通过像素拍摄光线 for(int x=0;x位置; } }

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

-用光线分布替换单个光线 -在一段时间内发射多条射线 -通过每个像素拍摄多条光线,并随机改变每条光线

我的问题是:“分配”是什么意思?如何改变穿过像素的光线分布?在我的普通光线跟踪器中,我每像素拍摄一条光线。对于光线的“分布”,我可以理解我应该拍摄多条光线,而不是只拍摄一条。但与此同时,我用坐标(x,y)通过像素拍摄光线

for(int x=0;x像素世界(x,y)-摄影机->位置;
}
}

那么,我如何“随机改变每条光线”?谢谢。

有很多不同的方法可以做到这一点,这在某种程度上取决于您当前的光线跟踪器实现中使用了什么

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

所有工作节点都是相等的,这意味着它们可以执行的作业类型没有差异。这允许您添加任意数量的工作节点(注意:在开始获得负回报之前,您可以添加的工作节点数量将有一个限制)

这样做的另一个好处是,您可以根据可用资源进行扩展——可能为了测试,您只需在本地计算机上使用几个线程,但是当您准备制作“生产”映像时,您可能需要使用其他计算机。此外,在此设置中,使用单个辅助线程进行渲染也可以

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

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

    process job
}
你需要决定的是“工作”需要什么。是一条光线吗?是否为单个光线及其所有后续反弹?是一批射线吗?此负载平衡决策将取决于您的光线跟踪器。一条光线可能还不够,但这是一个很好的起点。事实上,您可能应该从每像素一条光线开始,然后每一条光线做一个作业。这将给你一个很好的基线,一旦你有工作开始


祝你好运

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

(1) 抗锯齿

(2) 景深效应

(3) 运动模糊效果

对于第(1)条,其想法是在每个像素中发射一束光线,而不是一条光线。每一条光线都将穿过像素的中心,并被随机的dx和dy稍微抖动(dx和dy将小于像素的大小)

对于(2),它稍微复杂一些,但基本上是相同的想法:每一条光线都是从观察者开始并穿过像素中心的直线(如果你这样做(1),可能会抖动,但现在让我们暂时忘记它)。这一次,这是您正在抖动的观察者位置,您将在与屏幕正交的方向上稍微抖动观察者的位置。同样,通过平均每个像素中的光线数量,背景将比前景更加“模糊”,因为光线在背景中的偏移更大

对于(3),这是相同的想法,但这一次是抖动的移动对象的位置


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

我的做法(承认很久以前)将输出的pixmap行划分为N个大小大致相同的部分,并将每个子部分分发给N个渲染工作者中的一个。这就足够开始了;那么一旦这起作用,问题是一些工人会比其他人完成得更快;在这种情况下,已完成的工人可以联系尚未完成的工人并提供帮助;然后,仍在工作的工人可以将(他尚未完成的行的一半)交给请求的工人。重复,直到所有行都被渲染,然后重新组装图像。好的,完美!这让我对我必须做的事情有了更清晰的认识。如果可能的话,还有几个问题:1)如何找到像素的大小?例如,我的图像大小为512x512。如果我需要像你说的那样抖动一点,我需要像素的大小。2) 可以射入像素的“好”射线数是多少?只是想有个主意。在我看来,它可以是4或100例如。。所以只是想知道“通常”会产生什么样的结果。谢谢1) 如果将视点指定为:,则得到一个点(位置)和三个向量(注视、向右和向上)。如果位置位于原点,则图像平面沿注视方向与原点相切(角度),这给出了将坐标(X,Y)的像素映射到3D的公式:(X,Y,z)=原点+切线(角度)*注视+(X/宽度-0.5+抖动)*右+(Y/高度-0.5+抖动)*向上,如果jitterX和jitterY是介于0和1.2之间的随机浮点数,通常为10到100(但运行时间显然与此成正比),请使用试错法进行调整。现在就清楚了!谢谢!
while(active)
{
    fetch next job from job queue
    if no job is available
    {
       sleep(1)
       continue
    }

    process job
}