c++ - 如何在 Ray Tracer 中实现景深?

标签 c++ raytracing depth

有人可以帮我在 Ray Tracer 中实现景深吗?

我正在使用一个简单的针孔相机模型,如下所示。我需要知道我们如何使用针孔相机模型生成 DOF 效果? (图片来自wikipedia)

enter image description here

我的基本光线追踪器工作正常。

我的眼睛在 (0,0,0,1),方向在 (dx, dy, 1.0f, 0.0f),其中

float dx = (x * (1.0 / Imgwidth) ) - 0.5;
float dy = (y * (1.0 / Imgheight) ) - 0.5;

现在,无论我读到什么,他们都在谈论对应该放置在图像平面和场景之间的镜头进行采样。例如如下所示(图片来自维基百科):

如果光线来自一个单点位置(相机或眼睛),我如何在图像平面前面引入一个镜头?

如果有人能提供帮助那就太好了!

谢谢

最佳答案

有 3 种方法可以做到这一点:

  1. 物理上正确的 DOF 需要对场景进行多次渲染。相机具有景深,因为它们并不是真正的针孔模型。相反,它们有一个孔径,允许光线在一定直径范围内进入。这相当于使用针孔相机并在该孔径内拍摄大量照片并取平均。

    所以基本上,您需要围绕焦点稍微旋转相机多次,渲染整个场景,在缓冲区中累积输出颜色,然后将所有值除以渲染次数。

  2. 一个简单的后期处理效果 - 不仅渲染场景颜色,还渲染它的深度,然后使用这个深度来控制模糊效果强度。请注意,此技术需要一些技巧才能在不同模糊级别的对象之间实现无缝过渡。

  3. 更复杂的后期处理效果 - 像以前一样创建一个深度缓冲区,然后使用它为原始场景的每个像素渲染一个光圈形状的粒子。使用深度来控制粒子大小,就像使用它来控制模糊效果强度一样。

(1) 给出最好的结果,但是是最昂贵的技术; (2) 最便宜,(3) 比较棘手,但提供了良好的成本效益平衡。

关于c++ - 如何在 Ray Tracer 中实现景深?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10012219/

相关文章:

c++ - 编译三角形交集代码?

perl - 当使用 Perl 的 File::Find 时,限制搜索深度的快速简便方法是什么?

c++ - 从 C++ 文件写入数据(点云库)

c++ - 将 std::string 转换为 C 函数的 char* 时要注意什么?

c++ - 下面的程序在 C++ 中如何工作?

c++ FILE结构参数含义

c++ - 单击窗口 x 轴的末端时,鼠标单击会导致 OpenGL 中的光线创建不正确吗?

c++ - C++ 中基于前向的光线追踪器

opengl-es - 如何模拟GL_DEPTH_CLAMP_NV?

c++ - 为什么此 clang 代码无法使用带有 -std=c++20 的 clang 10 进行编译