2012-04-04 3 views
4

Ray Tracer의 피사계 심도 구현을 도와 줄 수 있습니까? 아래와 같이레이 트레이서에서 피사계 심도를 구현하는 방법은 무엇입니까?

I 간단한 핀홀 카메라 모델을 사용하고있다. 핀홀 카메라 모델을 사용하여 DOF 효과를 생성하는 방법을 알아야합니까? 미세 가공에

enter image description here

내 기본 선 트레이서 (wikipedia 화상으로부터 취해진 다).

난 (DX, DY, 1.0F, 0.0f로)

플로트 DX = (X *의 (1.0/Imgwidth))에서 방향 (0,0,0,1)에서 눈을 가지고 - 0.5;
float dy = (y * (1.0/Imgheight)) - 0.5;

이제 어디서나 그들은 이미지 평면과 장면 사이에 배치해야하는 렌즈를 샘플링하는 것에 대해 이야기하고 있습니다. (예를 들어, 위키 피 디아에서 가져온 이미지) 아래와 같이 :

광선이 하나 개의 점 위치 (카메라 또는 눈)에서 오는 경우 나 이미지 평면의 앞에 렌즈를 소개 할 수 있는가?

누군가가 큰 것보다 도움이 될 수 있다면!

은 감사합니다

답변

10

이 작업을 수행하는 3 가지 방법이 있습니다 :

  1. , 물리 올바른 DOF 여러 장면의 렌더링 필요가. 카메라는 핀홀 모델이 아니기 때문에 심도가 있습니다. 대신, 그들은 특정 직경 이내에서 빛을 허용 조리개 있습니다. 이는 핀홀 카메라를 사용하고 그 구경 내에서 많은 사진을 찍어 평균화하는 것과 같습니다.

    그래서 기본적으로, 당신은, 당신의 초점 점을 중심으로 카메라를 살짝 여러 번 회전 전체 장면을 렌더링 할 필요가 버퍼에 출력 색상을 축적 그리고 렌더 숫자로 모든 값을 나눕니다.

  2. 간단한 후 처리 효과

    은 - 다음 장면의 색상뿐만 아니라 깊이뿐만 아니라 렌더링 흐림 효과의 강도를 제어하려면이 깊이를 사용합니다. 이 기법은 다른 흐림 수준의 객체간에 완벽한 전환을 얻으려면 몇 가지 트릭이 필요합니다.

  3. 더 복잡한 후 처리 효과 - 원래 장면의 화소마다 개구 형상 입자를 렌더링하기 위해 사용 후 이전과 같이 깊이 버퍼를 생성. 흐림 효과 강도처럼 입자 크기를 조절하려면 깊이를 사용하십시오.

(1)이 가장 값 비싼 기법입니다. (2)가 가장 저렴하고 (3) 매우 까다 롭지 만 비용 효과가 좋은 균형을 제공합니다.

+0

내 카메라 (또는 눈) 위치 주변에 샘플 지점을 몇 개 찍는 것과 비슷하지 않습니까? 그런 다음이 모든 장면에서 내 장면을 렌더링합니다. 장면의 어딘가에 초점 포인트를 정의하여 이미지면의 각 픽셀에 대해 각 샘플 지점에서 초점에있는 지점까지 광선을 전송합니다. – sinner

+0

음, 예, 실제로는 동일합니다. 물론 전체 장면의 렌더를 누적하는 대신 픽셀 단위로 색상을 누적 할 수 있습니다. – IneQuation

+0

내 말은 : 취향과 비슷하지 않습니다 : - 내 카메라 (또는 눈) 위치 주변에 약간의 샘플 포인트가 있습니다. - 그런 다음 각 샘플 지점에서 이미지면의 각 픽셀을 통해 초점 지점으로 광선을 보내서이 모든 위치에서 내 장면을 렌더링합니다. 미안하지만 눈 위치, 이미지 평면, 초점 평면 및 장면의 관점에서 설명 할 수 있다면 꽤 쉽게 이해할 수 있습니다. – sinner

2

다음은 내가 DOF를 생성하기 위해 작성한 코드입니다.

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

질문의 일부가 아니어야합니까? –