Вычисление диффузного значения r,g,b пикселя на трассировщике лучей с использованием Блинна-Фонга

Я пытаюсь рассчитать значение RGB пикселя, используя формулу Блинна-Фонга. Для этого я использую эту функцию:

Material getPixelColor(Ray ray, double min, int index, std::vector<Object*> Objects, std::vector<Object*> lightSources) {

    Vector intersectionPoint = ray.getOrigin() + ray.getDirection() * min;
    Vector n = Objects.at(index)->getNormalAt(intersectionPoint);
    Vector reflectiondirection = ray.getDirection() - n * Vector::dot(ray.getDirection(), n) * 2;
    Ray reflectionRay(intersectionPoint, reflectiondirection);

    // check if ray intersects any other object;
    double minimum = INFINITY;
    int count = 0, indx = -1;
    for (auto const& obj : Objects) {
        double distance = obj->Intersect(reflectionRay);
        if (minimum > distance) {
            minimum = distance;
            indx = count;
        }
        count++;
    }

    Material result(0,0,0);
    if (recurseDepth >= 5 || indx == -1) {
        recurseDepth = 0;
        // Check if object is lit for each light source
        for (auto const& light : lightSources) {
            // Blinn-Phong
            Vector lightDirection = (light->getPosition() - intersectionPoint).normalize();
            double nl = Vector::dot(n, lightDirection);
            nl = nl > 0 ? nl : 0.0;
            result = result + (Objects.at(index)->getMaterial() * light->getMaterial() * nl);
        }
    }
    else{
        recurseDepth++;
        result = result + getPixelColor(reflectionRay, minimum, indx, Objects, lightSources);
    }
    return result;
}

Результат, который я получаю, таков:

Изображение с ошибкой

Вот как это было без затенения: Изображение без заливки

Я пытался найти решение в течение нескольких часов и не могу. Я использую неправильную формулу?


person Thanos T.    schedule 15.07.2020    source источник


Ответы (1)


После долгих исследований я удалил часть, где он получает цвет от других объектов:

Material getPixelColor(Ray ray, double min, int index, std::vector<Object*> Objects, std::vector<Object*> lightSources) {
    Vector intersectionPoint = ray.getOrigin() + ray.getDirection() * min;
    Vector n = Objects.at(index)->getNormalAt(intersectionPoint);

    Material result(0,0,0);
    // Check if object is lit for each light source
    for (auto const& light : lightSources) {
        //create a ray to the light and check if there is an object between the two
        Vector lightDirection = (light->getPosition() - intersectionPoint).normalize();
        Ray lightRay(intersectionPoint, lightDirection);

        bool hit = false;
        for (auto const& obj : Objects) {
            double distance = obj->Intersect(lightRay);
            if (INFINITY > distance && distance > 0.0001) {
                hit = true;
                break;
            }
        }

        if (!hit) {
            // Blinn-Phong
            double nl = Vector::dot(n, lightDirection);

            // clamp nl between 0 and 1
            if (nl > 1.0) {
                nl = 1.0;
            }
            else if (nl < 0.0) {
                nl = 0.0;
            }

            result = result + (Objects.at(index)->getMaterial() * nl);
        }
    }
    return result;
}

И так я получил желаемый результат:

введите здесь описание изображения

person Thanos T.    schedule 15.07.2020