2012-04-04 59 views
4

有人可以帮助我在Ray Tracer中进行景深实现吗?如何在Ray Tracer中实现景深?

我正在使用一个简单的针孔相机模型,如下所示。我需要知道如何使用针孔相机模型生成DOF效果? (图片由wikipedia拍摄)在做工精细

enter image description here

我的基本的射线追踪。

我有眼在(0,0,0,1),在(DX,DY,1.0F,0.0F)其中

浮子DX =(X *(1.0/Imgwidth))方向 - 0.5;
float dy =(y *(1.0/Imgheight)) - 0.5;

现在无处不读,他们正在谈论采样应该放置在图像平面和场景之间的镜头。例如如下图所示(图片来源于维基百科):

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

如果有人能帮上忙,那就太棒了!

谢谢

回答

10

有3种方法来做到这一点:

  1. 物理纠正自由度需要多次渲染的场景。相机具有景深,因为它们不是真正的针孔模型。相反,他们有一个光圈,允许光线在一定的直径内。这相当于拍摄针孔照相机并在该光圈内拍摄大量照片并对其进行平均处理。因此,基本上,您需要在您的焦点周围多次旋转相机,渲染整个场景,将输出颜色累积在缓冲区中,并将所有值除以渲染数量。

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

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

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

+0

这与在我的相机(或眼睛)位置周围取少量采样点并不相似。然后从所有这些位置渲染我的场景。通过在场景中的某个地方定义一个焦点,从每个采样点发送一个光线到图像平面中每个像素的焦点。 – sinner 2012-04-04 14:03:53

+0

嗯,是的,这实际上是相同的 - 当然,您可以在每个像素的基础上累积颜色,而不是累积整个场景的渲染。 – IneQuation 2012-04-04 14:10:28

+0

我的意思是: 是不是采取相似: - 我的相机(或眼睛)位置周围的样本点很少。 - 然后通过从图像平面中的每个像素向每个采样点发送一个光线到焦点,从所有这些位置渲染场景。 对不起,但如果你可以解释眼睛的位置,图像平面,焦平面和场景,它会让我很容易理解。 – sinner 2012-04-04 14:13:44

2

这里是我写的代码生成自由度。

void generateDOFfromEye(Image& img, const Camera& camera, Scene scene, float focusPoint) 
{ 
    float pixelWidth = 1.0f/(float) img.width; 
    float pixelHeight = 1.0f/(float) img.height; 

    for (int y = 0; y < img.height; ++y) 
     { 
     for (int x = 0; x < img.width; ++x) 
      { 
      Color output(0,0,0,0); 
      img(x, y) = Color(0,0,0,0); 

      //Center of the current pixel 
      float px = (x * pixelWidth) - 0.5; 
      float py = (y * pixelHeight) - 0.5; 

      Ray cameraSpaceRay = Ray(Vector(0,0,0,1), Vector(px, py, 1.0f, 0.0f)); 

      Ray ray = camera.Transform() * cameraSpaceRay; 

      int depth = 0; 
      int focaldistance = 2502; 
      Color blend(0,0,0,0); 



      //Stratified Sampling i.e. Random sampling (with 16 samples) inside each pixel to add DOF 
       for(int i = 0; i < 16; i++) 
       { 
       //random values between [-1,1] 
       float rw = (static_cast<float>(rand() % RAND_MAX)/RAND_MAX) * 2.0f - 1.0f; 
       float rh = (static_cast<float>(rand() % RAND_MAX)/RAND_MAX) * 2.0f - 1.0f; 
       // Since eye position is (0,0,0,1) I generate samples around that point with a 3x3 aperture size window. 
       float dx = ((rw) * 3 * pixelWidth) - 0.5; 
       float dy = ((rh) * 3 * pixelHeight) - 0.5; 

       //Now here I compute point P in the scene where I want to focus my scene 
       Vector P = Vector(0,0,0,1) + focusPoint * ray.Direction(); 
       Vector dir = P - Vector(dx, dy, 0.0f, 1.0f); 


       ray = Ray(Vector(dx,dy,0.0f,1.0f), dir); 
       ray = camera.Transform() * ray; 

       //Calling the phong shader to render the scene 
       blend += phongShader(scene, ray, depth, output); 

       } 
      blend /= 16.0f; 

      img(x, y) += blend; 
      } 
     } 
} 

现在我在代码中看不到任何错误。但我得到的结果是只为focuspoint > 500价值模糊图像,如下图所示: enter image description here

如果你能告诉什么是错的这个代码,那么这将是非常有益的:) 谢谢!

+1

这不应该成为问题的一部分吗? – 2017-06-08 01:28:25