2017-02-24 80 views
0

[编辑]正如编程中的典型情况,我在发布后不久就想出了它!看到我的答案,如果你有兴趣:)光线追踪:来自多个灯光的阴影

我正在使用C++光线跟踪器,并希望得到一些帮助。我的场景中有两盏灯,一盏点灯和一盏定向灯,还有一堆球体(以及一架飞机作为“地板”)。

如果我运行任一光线存在的光线跟踪器(但其他光线不存在),它会使阴影如预期般(见下图)。

Directional light shadows image

Point 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光源归因于该点,否则环境+漫射归因于(我还没有围绕添加镜面反射)。

任何建议将是伟大的!

+0

(链路用于与两个灯的输出[HTTPS:// PUU。 sh/ui6Ka/e81edc5f6e.jpg] - 因为SO只会让我在问题中发布2个链接) – NOSHEDMANTIS

回答

0

虚惊一场! 我想通了!

每个对象列表循环之前我加入:

obj = obj_list; 

复位到第一个目的,这解决了这个问题:)