2017-02-24 1 views
0

[편집] 일반적인 프로그래밍과 마찬가지로 게시 직후에 알아 냈습니다! 관심이 있다면 내 대답을 참조하십시오 :)광선 추적 : 여러 빛의 그림자

저는 C++에서 레이 트레이서를 연구 중이며 뭔가 도움이 필요했습니다. 내 장면에는 2 개의 라이트, 포인트 라이트 및 방향성 라이트, 그리고 일련의 구체 ("바닥"역할을하는 비행기와 함께)가 있습니다.

광선 추적기를 현재 표시등 중 하나 (그러나 다른 표시등이없는)로 실행하면 예상대로 그림자가 생깁니다 (아래 이미지 참조).

Point light shadows image

의 문제점은 내가 모두 조명 현재 내 레이 추적을 실행할 때, 빛 그림자는 표시 만 포인트, 나는 빛이 장면이기 때문 "에"입니다 말할 수 있습니다

Directional light shadows image

밝은 :

가 감지 그림자 아래에 내 코드를 참조하십시오 그림자가 감지

bool Scene::shadowtrace(Ray &ray, double t) 
{ 
    Object *obj = obj_list; 
    Light *lt = light_list; 
    Vector v1, v2; // hit -> light vector 
    Hit hit; 

    Vertex intersect = (ray.position(t)); 
    intersect.plus(ray.D, -0.001); // offset intersection ever so slightly away from object, to avoid self-shadowing 
    v1.set(0.0, 0.0, 0.0); 
    v2.set(0.0, 0.0, 0.0); // initialise 

    while (lt != (Light *)0) 
    { 
     Ray shadowRay; 
     shadowRay.P = (intersect); 

     Vertex lightPos = Vertex(0.0, 0.0, 0.0, 0.0); 
     lt->getPosition(lightPos); // sets value of lightPos 

     if (lightPos.x > T_LIMIT) // If set absurdly high, we're dealing with a directional light 
     { 
      lt->getDirection(v1); // sets v1 to light direction (reversed) 
      v1.normalise(); 
      shadowRay.D = v1; // set hit-to-light vector as shadowray direction 

      while (obj != (Object *)0) 
      { 
       if (obj->intersect(shadowRay, &hit) == true) 
       { 
        if (!((hit.t * hit.t) < 0.001)) // Self-shadow if very very small t number 
        { 
         return true; // ray hits an onject, and the object occurs before the light 
        } 
       } 
       obj = obj->next(); 
      } 
     } 
     else // otherwise, it's a point light :) 
     { 
      v1 = (lightPos.minus(intersect)); // find vector from intersection to light 
      v2 = v1; // keep un-normalised version for preventing mis-shadowing from objects behind the light source 
      v1.normalise(); 
      shadowRay.D = v1; // set ray direction to hit-to-light vector 

      while (obj != (Object *)0) 
      { 
       if (obj->intersect(shadowRay, &hit) == true) 
       { 
        if (!((hit.t * hit.t) > (v2.lengthSq()))) // Check hit.t against magnitude of (un-normalised) intersection-to-light vector 
         if (!((hit.t * hit.t) < 0.001)) // Self-shadow if very very small t number 
         { // Used hit.t^2 to avoid having to SQRT the length. Is acceptable for comparisons 
          return true; // ray hits an onject, and the object occurs before the light 
         } 

       } 

       obj = obj->next(); 
      } 
     } 

     lt = lt->next(); 
    } 

    return false; 
} 

경우에만 AMB를 ient 라이트는 포인트에 기인합니다. 그렇지 않으면 ambient + diffuse가 발생합니다 (아직 반사를 추가하지 못했습니다).

어떤 제안이 좋을까요?

+0

(링크 해결 [HTTPS : // PUU. sh/ui6Ka/e81edc5f6e.jpg] - SO 만이 질문에 2 개의 링크를 게시 할 수 있기 때문에) – NOSHEDMANTIS

답변

0

가짜 경보입니다! 나는 그것을 알아 냈다 !!

각 오브젝트리스트 루프 전에 첨가 :

obj = obj_list; 

첫번째 오브젝트 재설정이 문제 : 두 조명 출력용

관련 문제