光线跟踪器中景深实现的参考?

时间:2012-11-23 16:41:49

标签: game-physics raytracing

我有一个基本的光线跟踪器,我想实现景深。请你 推荐我可以使用的资源,书籍和代码?

由于

1 个答案:

答案 0 :(得分:16)

我从本页的一些信息中得出结论:http://cg.skeelogy.com/depth-of-field-using-raytracing/,特别是底部附近的图表。我认为我做的与它的显示方式有所不同,但这个概念非常简单。

我可以解释发生了什么以及如何实现它的一般概念(我试着简明扼要)。光线从所有方向(一般来说)反射出任何给定点,因此它实际上不是在渲染点和你的眼睛之间的单一光线,它是一个光锥离开渲染点和向眼睛扩展。您的眼睛/相机的镜头将倾向于弯曲这些光线,使锥体停止扩张并再次开始收缩。为了使事物完全聚焦,锥体应收缩到视网膜/框架上的一个点,但这只能在距离镜片一个特定距离处起作用:由焦平面指示的距离"在引用的页面中(虽然我认为它应该是一个以眼睛为中心的球体,而不是一个平面)。

对于焦平面前方的任何物体,光锥将更加弯曲:它将聚焦到视网膜/框架前方的一个点,然后再次开始扩展,所以当它到达框架时,它不再是一个点,而是一个圆圈。类似地,对于焦平面后面的点,锥体将弯曲得更少,并且当它到达框架时还不会收敛到一个点。在这两种情况下,效果都是单个点是场景最终被涂抹在多个像素上。

为了实现,您可以将这个想法转变为它的头部:不是将场景中的每个点渲染到几个像素,而是可以将几个附近点渲染到单个像素,这当然是什么真的会发生,因为"涂抹了"相邻点的光圈最终会重叠,因此每个光圈都会产生一个像素。

所以我的实施方式如下:

首先,定义光圈:眼睛上的平面区域中心,与视网膜/框架平行。光圈越大,DOF效果越明显。光圈通常只是圆形,在这种情况下,它很容易通过半径来定义。其他形状可能会导致不同的灯光效果。

还要定义焦距#34;。我并不认为它实际上是正确的术语,但它与眼睛的距离完全是焦点。

渲染每个像素:

  1. 首先将一条正常的光线从眼睛通过像素投射到场景中。但是,您只需要找到与眼睛的距离等于所选焦距的光线上的点,而不是将其与场景中的对象相交。将此点称为像素的焦点。
  2. 现在在光圈上选择一个随机起点。对于圆形光圈,它非常简单,您可以选择随机极角和随机半径(不大于光圈的半径)。你希望在整个光圈上均匀分布,不要试图将它偏向中心或任何东西。
  3. 通过焦点从光圈上的选定点投射光线。请注意,它不一定会通过相同的像素,这没关系。
  4. 以通常的方式渲染此光线(例如,路径追踪,或只是找到最近的交点等)。
  5. 重复步骤2,3和4一些次数,每次在光圈上使用不同的随机起点,但始终将其投射通过焦点。总结所有光线的渲染颜色值,并将其用作此像素的值(通常情况下,如果需要,除以恒定的衰减系数)。
  6. 每个像素使用的光线越多,质量就越好。我每个像素使用大约150条光线来获得不错的但不是很好的质量。你可以看到效果很少(比如50或60条光线)​​,但是更少的光线会在图像中产生颗粒感,特别是对于非常失焦的东西。您需要的光线数量也取决于光圈尺寸:较小的光圈不会需要尽可能多的光线,但您不会获得尽可能多的模糊效果。

    显然,你通过这样做大大增加了你的工作量,实质上是将它乘以每个像素的光线数量,所以如果你在光线跟踪器中有任何优化,那么现在是时候了。做到这一点。如果您碰巧有多个处理器,那么好消息是,一旦找到像素的焦点,就会出现令人尴尬的平行。

    多一点解释

    下面的图片可以让您了解发生了什么,以及为什么它与眼睛或相机中真正发生的情况相同。它显示了两个正在渲染的像素,一个像素用红色表示,另一个像素用蓝色表示。虚线从眼睛穿过每个像素延伸到焦点"平面"是你在开始时投射的光线,以确定像素的焦点。半透明锥体指示可以随机选择以呈现每个像素的完整光线组(像素-1的红色圆锥,像素2的蓝色圆锥)。请注意,由于所有光线都通过焦点,因此每个光锥会聚到恰好在焦点处的点。

    锥体的重叠区域表示场景中可能最终被渲染到像素-1和像素-2的点:换句话说,被抹掉。由于每个圆锥是焦点"平面上的一个点,因此这里的圆锥之间没有重叠,因此此距离处的点仅渲染到单个像素:它们完全对焦。同时,你越远离焦点飞机" (向前或向后),锥体展开的越多,因此锥体在任何给定点处都会重叠。因此,非常接近或非常远的点将倾向于渲染到大量不同的像素,因此它们将非常失焦。

    Model of DOF implementation for raytracing.