Как переместить камеру с помощью трассировщика лучей?

В настоящее время я работаю над методами трассировки лучей и думаю, что я проделал довольно хорошую работу; но я еще не закрыл камеру.

До сих пор я использовал фрагмент плоскости для просмотра плоскости, который расположен между (-width/2, height/2, 200) а также (width/2, -height/2, 200) [200 — это просто фиксированное число z, может быть изменено].

Кроме того, я использую камеру в основном на e(0, 0, 1000)и я использую перспективную проекцию.

Я посылаю лучи из точки e в пиксели, и распечатать его в соответствующий пиксель изображения после расчета цвета пикселя.введите описание изображения здесь

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

Мой вопрос начинается отсюда. Пришло время переместить мою камеру, но я не знаю, как сопоставить координаты плоскости 2D-вида с каноническими координатами. Есть ли для этого матрица преобразования?

Я думаю, что метод требует знать трехмерные координаты пикселей на плоскости обзора. Я не уверен, что это правильный метод для использования. Итак, что вы предлагаете?

5

Решение

Есть множество способов сделать это. Вот что я делаю:

  1. Выберите точку для представления местоположения камеры (camera_position).
  2. Выберите вектор, который указывает направление, в котором смотрит камера (camera_direction). (Если вы знаете точку, на которую смотрит камера, вы можете вычислить этот вектор направления, вычитая camera_position с этого момента.) Вы, вероятно, хотите нормализовать (camera_direction), в этом случае это также нормальный вектор плоскости изображения.
  3. Выберите другой нормализованный вектор, который (приблизительно) «вверх» с точки зрения камеры (camera_up).
  4. camera_right = Cross(camera_direction, camera_up)
  5. camera_up = Cross(camera_right, camera_direction) (Это исправляет любое отклонение в выборе «вверх».)

Визуализируйте «центр» плоскости изображения на camera_position + camera_direction, Верхний и правый векторы лежат в плоскости изображения.

Вы можете выбрать прямоугольный участок плоскости изображения, соответствующий вашему экрану. Отношение ширины или высоты этого прямоугольного сечения к длине camera_direction определяет поле зрения. Для увеличения вы можете увеличить camera_direction или уменьшить ширину и высоту. Сделайте обратное, чтобы уменьшить масштаб.

Так, учитывая положение пикселя (i, j)вы хотите (x, y, z) этого пикселя на плоскости изображения. Из этого можно вычесть camera_position получить лучевой вектор (который затем должен быть нормализован).

Ray ComputeCameraRay(int i, int j) {
const float width = 512.0;  // pixels across
const float height = 512.0;  // pixels high
double normalized_i = (i / width) - 0.5;
double normalized_j = (j / height) - 0.5;
Vector3 image_point = normalized_i * camera_right +
normalized_j * camera_up +
camera_position + camera_direction;
Vector3 ray_direction = image_point - camera_position;
return Ray(camera_position, ray_direction);
}

Это должно быть иллюстративно, поэтому оно не оптимизировано.

13

Другие решения

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

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

Учитывая положение глаза, точку в трехмерном пространстве, которая находится в центре экрана, и векторы для «вверх» и «вправо», довольно легко рассчитать трехмерный «луч», который идет от положения глаза и через заданный пиксели.

Ранее я опубликовал пример кода из моего собственного трассировщика лучей на https://stackoverflow.com/a/12892966/6782

2

По вопросам рекламы [email protected]