RayTracing, модель Phong / зеркальное освещение не работает? - PullRequest
1 голос
/ 21 февраля 2020

Я пытался создать глянцевое затенение, используя модель Фонга, но по какой-то причине вместо глянцевого внешнего вида все, что я получаю, это большое белое пятно на передней части сферы. Изначально модель работала для одной сферы, но теперь я обновил код, чтобы я мог рисовать несколько сфер, и модель начала давать сбой, несмотря на применение одного и того же лога c, и я не знаю почему.

одна сфера: диффузная и зеркальная single sphere: diffuse and specular

диффузная, кратная

diffuse, multiple

диффузная + зеркальная, кратная

diffuse+specular, multiple

основная часть

vec color(const ray& r)
{
    vector <sphere> objects;
    vector <Light> lighting;

    objects.push_back(sphere(vec(0,-100.5,-3), 100, vec(0, 1, 0)));
    objects.push_back(sphere(vec(0, 0, -1), 0.5, vec(1, 0, 0)));
    objects.push_back(sphere(vec(0, 1 ,-1), 0.5, vec(1, 0, 1)));
    lighting.push_back(Light(vec(0, 0, -1), vec(0, -1, 0)));

    float infinity = 2000.0;
    sphere* closest = NULL;
    vec background_color( .678, .847, .902);
    vec totalLight(0.0, 0.0, 0.0);
    int pos = 0;
    for(int j = 0; j < objects.size(); j++)
    {
        float t = objects[j].intersect(r);
        if(t > 0.0)
        {
            if(t < 2000.0)
            {
                infinity = t;
                closest = &objects[j];
                pos = j;
            }
        }
    }
    if(infinity == 2000.0)
        return background_color;
    else
    {
        float a = objects[pos].intersect(r);
        vec view_dir = vec(-2, 2, 10) - r.p_at_par(a);
        vec normal = unit_vector((r.p_at_par(a) - closest->centre)/closest->radius);
        vec light = unit_vector(vec(-2, 0, 0) - r.p_at_par(a));
        vec reflection = 2.0*dot(light, normal)*normal - light;
        vec specular = vec(1, 1, 1)*pow(max(0.f, dot(reflection, view_dir)), 256);
        vec diffuse = (closest->color)*max(0.f, dot(normal, light));
        vec total = diffuse + specular;
        return total;

    }
}

как я понимаю, зеркальный = белый * точка (view_dir, L_dir) ^ n * ks и общее освещение = зеркальный + рассеянный + рассеянный.

1 Ответ

0 голосов
/ 15 марта 2020

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

Прежде всего, я не вижу, как вы нормализуете view_dir. Убедитесь, что все векторы нормализованы. Если a и b имеют длину 1, следующее значение истинно

точка (a, b) = || a || . || b || .cos (\ theta) = cos (\ theta)

Также, чтобы помочь в отладке в будущем, вы можете захотеть генерировать ложные цветные изображения. Эти изображения могут помочь вам увидеть, что происходит. Например, вы можете просто отобразить свой плоский цвет, нормали поверхности (от xyz до rgb), количество источников света, влияющих на определенный пиксель, .... Это может помочь вам обнаружить неожиданное поведение.

Надеюсь, это поможет.

...