Нерекурсивная функция ray_color из Raytracing в One Weekend в GLSL с использованием вычислительных шейдеров - PullRequest
0 голосов
/ 27 мая 2020

Я пытаюсь написать трассировщик лучей в реальном времени с использованием вычислительных шейдеров в opengl 4.3. Знаю, что это довольно популярный вопрос. Я проверил это и это , но представленная там архитектура не совсем соответствует моему варианту использования.

Я просто пытаюсь преобразовать ray_color функция, представленная в книге П. Ширли здесь в нерекурсивную функцию.

Упомянутая ray_color функция:

color ray_color(const ray& r, const hittable& world, int depth) {
    hit_record rec;

    // If we've exceeded the ray bounce limit, no more light is gathered.
    if (depth <= 0)
        return color(0,0,0);

    if (world.hit(r, 0.001, infinity, rec)) {
        point3 target = rec.p + rec.normal + random_unit_vector();
        return 0.5 * ray_color(ray(rec.p, target - rec.p), world, depth-1);
    }

    vec3 unit_direction = unit_vector(r.direction());
    auto t = 0.5*(unit_direction.y() + 1.0);
    return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5, 0.7, 1.0);
}

Вот моя попытка:


vec3 no_hit_color(in Ray r) {
  vec3 dir = normalize(r.direction);
  float temp = 0.5 * (dir.y + 1.0);
  vec3 cval = vec3(1.0 - temp) + temp * vec3(0.5, 0.7, 1.0);
  return cval;
}

vec3 ray_color(in Ray r, in Scene scene, int depth) {
  //
  Ray r_in;
  r_in.origin = r.origin;
  r_in.direction = r.direction;
  vec3 bcolor = vec3(1);

  while (true) {
    Ray r_out;
    if (depth <= 0) {
      //
      return vec3(0);
    }
    HitRecord rec;
    if (hit_scene(scene, r_in, 0.001, INFINITY, rec)) {
      vec3 target = rec.point + random_in_hemisphere(rec.normal);
      r_in = makeRay(rec.point, target - rec.point);
      depth--;
      bcolor *= 0.5;
    } else {
      bcolor *= no_hit_color(r_in);
      return bcolor;
    }
  }
}

Если я использую значение stati c для глубины с чем-то вроде #define MAX_DEPTH, я думаю, что смогу реализовать алгоритм, создав свой собственный стек, но я хотел бы сохранить глубину как переменная Dynami c, где я могу позволить пользователям настраивать их в соответствии с их вычислительной мощностью. Поэтому я хотел бы реализовать его, если возможно, используя while. Моя версия создает черный фрагмент около нижней части сферы, что не соответствует эталонному изображению.

Обновление 1:

Я немного убежден, что приведенная выше реализация верна, но моя камера Положение, из которого я генерирую лучи, проблематично c.

1 Ответ

0 голосов
/ 28 мая 2020

Я подтвердил, что реализация действительно верна. Вот версия glsl и версия C ++ для использования в будущем. Это должно дать вам направление для реализации более сложных вещей в будущем. * l oop для реализации функции. Обратите внимание, что функция не использует стек вызовов, поэтому ее можно использовать там, где максимальная частота отказов или максимальная глубина, в зависимости от того, что вы предпочитаете, для лучей составляет Dynami c.

...