Трассировка лучей: проблемы с выводом теневых лучей

Прежде, чем это будет помечено как дубликат, у меня есть точно такой же проблема как у человека, задавшего этот вопрос.

К сожалению, у него нет ответа, который вообще помог бы, так что, надеюсь, это вызовет лучшую дискуссию. Задача состоит в том, чтобы с помощью C ++ запрограммировать классический трассировщик лучей. Я использую модель затенения Фонга и могу точно освещать сцены до тех пор, пока мне не понадобится отбрасывать теневые лучи.

Для справки, вот изображение того, что у меня есть до сих пор, не пытаясь использовать тени:

Следуя традиционному алгоритму трассировки лучей, при котором я ищу объект, ближайший к моей камере-обскуре, я вызываю следующую функцию, которая вычисляет результирующий цвет пикселя:

glm::vec3 Scene::illuminate(Ray* primary, Surface* object, glm::vec3 hitPt)
{
    float red, green, blue;
    Material m = object->getMaterial();
    float p = m.phongCoef;
    glm::vec3 kD = m.diffuse;
    glm::vec3 kS = m.specular;
    glm::vec3 kA = m.ambient;
    float iA = m.ambienceIntensity;
    float i = lightSrc.lightIntensity;
    glm::vec3 n = object->getSurfaceNormalAt(hitPt); //normalized before return.
    glm::vec3 viewRay = primary->getDirection();   //normalized class member.

    glm::vec3 lightRay = glm::normalize((lightSrc.getOrigin()) - hitPt); //origin not normalized before here
    glm::vec3 h = glm::normalize(viewRay + lightRay);
    float nDotlightRay = glm::dot(n,lightRay);
    float nDoth = glm::dot(n, h);

    bool inShadow = false;
    Ray shadowRay;
    //hitPt = glm::normalize(hitPt);
    shadowRay.setOrigin(hitPt);
    shadowRay.setDirectionVector(lightRay);
    for (int k = 0; k < objects.size(); ++k) {
        if (objects.at(k)->intersect(shadowRay)) {
            //std::cout<<shadowRay.getDirection().x<<","<< shadowRay.getDirection().y <<","<<shadowRay.getDirection().z<<"\n";
            inShadow = true;
            break;}}

    //plug in to shading model
    if (inShadow)
    {
        red = kA.x*iA;
        green = kA.y*iA ;
        blue = kA.z*iA ;
    }
    else{
        red = kA.x*iA  +  kD.x*i*(fmax(0,nDotlightRay))  +  kS.x*i*(powf((fmax(0, nDoth)),p));
        green = kA.y*iA  +  kD.y*i*(fmax(0,nDotlightRay))  +  kS.y*i*(powf((fmax(0, nDoth)),p));
        blue = kA.z*iA  +  kD.z*i*(fmax(0,nDotlightRay))  +  kS.z*i*(powf((fmax(0, nDoth)),p));
    }

    glm::vec3 pixelColor = glm::vec3(red, green, blue);
    return pixelColor;
}

Я попытался использовать описательные имена переменных / функций, чтобы свести к минимуму объяснения, сопровождающие мой код. glm::vec3 - это просто структура данных из математической библиотеки GLM, которая содержит трехмерный вектор, с которым могут выполняться манипуляции с матрицами / векторами.

Как и в вопросе, который я связал выше, вот как выглядит моя сцена после использования теней.

Положение света для этой сцены (0, 2,5, -7,75) выражено в опорном кадре камеры (который имеет начало координат (0,0,0) и обращен в отрицательном направлении по оси Z). Для другой сцены источник света находится в (4, 6, -1), и для этого результат даже не согласуется с проблемами другой сцены, которую я пытался визуализировать, как вы можете видеть здесь; у него есть только тонкая серая линия в верхней части сцены, никаких теней больше нигде нет? Я совершенно заблудился и потратил около 10 часов только на эту проблему; Будем признательны любому совету.

Пожалуйста, дайте мне знать, есть ли еще какая-либо информация, которую я могу предоставить, например, как я рассчитываю расстояние и точку попадания ?? Я не знаю, стоит ли мне в них разбираться, поскольку затенение работает отлично, или вы, ребята, думаете, что это все еще может вызвать эту проблему? Глубина и тому подобное не должно быть проблемой, поскольку объекты выглядят правильно вплоть до теней?


person assistantToTheRegionalMngr    schedule 25.11.2018    source источник


Ответы (1)


Отвечая на свой вопрос: упомянутые выше артефакты тени были результатом того, что источник луча не учитывался в моих расчетах пересечения. Изначально я не беспокоился, так как опорный кадр моей камеры был на (0,0,0). Но для теневых лучей начало координат не является нулевым вектором, и, таким образом, повторное использование тех же функций проверки пересечений дало результаты, которые были полностью неверными. Использование нормализованных векторов направления также является ключевым моментом, иначе выходные данные не будут иметь смысла, что затруднит определение того, в чем может быть ошибка.

person assistantToTheRegionalMngr    schedule 26.11.2018