Трассировка лучей: проблемы с выводом теневых лучей - PullRequest
0 голосов
/ 25 ноября 2018

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

К сожалению, у него нет ответа, который помогвсе, так что, надеюсь, это вызовет лучшую дискуссию.Используя 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 часов на эту проблему в одиночку;Будем признательны любому совету.

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

1 Ответ

0 голосов
/ 26 ноября 2018

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

...