Трассировка лучей: тени от нескольких источников света

[Edit] Как это обычно бывает в программировании, я понял это вскоре после публикации! смотрите мой ответ, если вам интересно 🙂

Я работаю над трассировкой лучей в C ++ и хотел кое-что помочь. У меня есть 2 источника света в моей сцене, точечный источник света и направленный источник света, и несколько сфер (вместе с плоскостью, действующей как «пол»).

Если я запускаю трассировщик лучей при наличии одного из источников света (но другой источник света отсутствует), он создает тени, как и ожидалось (см. Изображения ниже).

Направленные светлые тени изображения

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;
}

Если тень обнаружена, точке присваивается только рассеянный свет, в противном случае — окружающий + рассеянный (я еще не дошел до добавления зеркального отражения).

Любые предложения будут великолепны!

0

Решение

Ложные тревоги!
Я понял!!

перед каждым циклом списка объектов я добавил:

obj = obj_list;

сбросить на первый объект, это решило проблему 🙂

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]