Получение диффузного материала правильной формы кода процессора для GPU шейдера - PullRequest
0 голосов
/ 26 сентября 2019

Я пытаюсь распаковать эту функцию из raytracing in one weekend

vec3 color(const ray& r, hitable *world)
{
   hit_record rec;
   if(world->hit(r,0.0, MAXFLOAT, rec)){
      vec3 target = rec.p + rec.normal + random_in_unit_sphere();
      return 0.5*color( ray(rec.p, target-rec.p), world);
   }
   else{
      vec3 unit_direction = unit_vector(r.direction());
      float t = 0.5*(unit_direction.y() + 1.0);
      return (1.0-t)*vec3(1.0,1.0,1.0) + t*vec3(0.5,0.7,1.0);
   }
}

Я понимаю, что она отправит луч и отскочит его, пока он ничего не ударит.
Так что у меня естьпопытаться развернуть эту рекурсивную функцию в шейдере GLSL.

vec3 color(ray r, hitableList list)
{
    hitRecord rec;
    vec3 unitDirection;
    float t;
    while(hit(r, 0.0, FLT_MAX, rec, list))
    {
        vec3 target = rec.p + rec.normal;
        r = ray(rec.p, target-rec.p);
    }
    unitDirection = normalize(direction(r));
    t = 0.5* (unitDirection.y + 1.);
    return (1.-t)*vec3(1.)+t*vec3(0.5,0.7,1.);
}

обычно он должен выводить диффузный сигнал так:
Actual diffuse material on cpu

но я получаю только отражающий материал, подобный этому:
Attempt one of the GPU diffuse material

обратите внимание, материал является Сильно отражающим и может отражать другие сферы в сцене.
Я просмотрел код и что-то подсказало мне, что это мой неправильный подходэтого tail recursive fonction.
Также я не возвращаю 0.5 * return 0.5 * color(...) Я понятия не имею, как это сделать.

ОБНОВЛЕНИЕ

Благодаря удивлению Jarod42 теперь реализован фактор 0.5 *, который решает проблему того, что материал не "должным образом" подвергается воздействию света.
Но теперь рассеянный материал все еще не генерируется, я получаю полностью отражающий металлический материал.
Attempt two of the diffuse material

1 Ответ

1 голос
/ 26 сентября 2019

Чтобы использовать коэффициент 0.5, вы можете сделать что-то вроде:

vec3 color(ray r, hitableList list)
{
    hitRecord rec;
    vec3 unitDirection;
    float t;
    float factor = 1.f;

    while(hit(r, 0.0, FLT_MAX, rec, list))
    {
        vec3 target = rec.p + rec.normal;
        r = ray(rec.p, target-rec.p);
        factor *= 0.5f;
    }
    unitDirection = normalize(direction(r));
    t = 0.5* (unitDirection.y + 1.);
    return factor * ((1.-t)*vec3(1.)+t*vec3(0.5,0.7,1.));
}
...