Несоответствие генерации лучей

Я написал код, который генерирует луч от «глаза» камеры к плоскости обзора на некотором расстоянии от глаза камеры:

R3Ray ConstructRayThroughPixel(...)
{
  R3Point p;

  double increments_x = (lr.X() - ul.X())/(double)width;
  double increments_y = (ul.Y() - lr.Y())/(double)height;
  p.SetX( ul.X() + ((double)i_pos+0.5)*increments_x );
  p.SetY( lr.Y() + ((double)j_pos+0.5)*increments_y );
  p.SetZ( lr.Z() );

  R3Vector v = p-camera_pos;

  R3Ray new_ray(camera_pos,v);
  return new_ray;
}

ul — это верхний левый угол плоскости просмотра, а lr — нижний левый угол плоскости просмотра. Они определяются следующим образом:

  R3Point org = scene->camera.eye + scene->camera.towards * radius;
  R3Vector dx = scene->camera.right * radius * tan(scene->camera.xfov);
  R3Vector dy = scene->camera.up * radius * tan(scene->camera.yfov);
  R3Point lr = org + dx - dy;
  R3Point ul = org - dx + dy;

Здесь org — центр плоскости обзора, radius — расстояние между плоскостью обзора и глазком камеры, dx и dy — смещения в направлениях x и y от центра плоскости обзора.

Функция ConstructRayThroughPixel(...) отлично работает для камеры, глаз которой находится в (0,0,0). Однако, когда камера находится в другом положении, для изображения создаются не все необходимые лучи.

Любые предложения, что может пойти не так? Может быть, что-то не так с моими уравнениями?

Спасибо за помощь.


person Myx    schedule 27.03.2010    source источник
comment
Я не думаю, что вам нужен тег векторной графики. Векторная графика обычно относится к формату файла, который хранит данные в форме, которая означает рисование линии от (x1, y1) до (x2, y2) с толщиной t и цветом c. тогда как вы будете хранить данные попиксельно, нет?   -  person dmckee --- ex-moderator kitten    schedule 27.03.2010
comment
ну, я использую формат файла сцены для отображения моей графики, в которой хранятся данные в форме, аналогичной описанной вами, но мой вопрос не имеет к этому никакого отношения. Я неправильно понял, что означает векторная графика -.-   -  person Myx    schedule 27.03.2010


Ответы (2)


Вот придирка, которая может не иметь никакого отношения к вашей проблеме:

Когда вы делаете это:

R3Vector dx = scene->camera.right * radius * tan(scene->camera.xfov);
R3Vector dy = scene->camera.up * radius * tan(scene->camera.yfov);

Я предполагаю, что векторы right и up нормализованы, верно? В этом случае вам нужно sin, а не tan. Конечно, если углы fov малы, это не будет иметь большого значения.

person dmckee --- ex-moderator kitten    schedule 27.03.2010
comment
Я внес изменения, и это не имело большого значения. Что происходит, так это то, что лучи отбрасываются, но не весь диапазон лучей. Итак, я предполагаю, что сопоставление выполнено неправильно, потому что несколько лучей отбрасываются на один и тот же пиксель или результирующее значение отбрасываемого пикселя очень близко к соседнему, поэтому весь диапазон пикселей не реконструируется полностью (т. е. нет ровно одного луча для пикселя в позиции плоскости просмотра (i,j)) - person Myx; 27.03.2010
comment
Это похоже на проблему, с которой вы сталкиваетесь при переходе от целочисленной математики к математике с плавающей запятой и обратно, но я не вижу никаких признаков этого в опубликованном вами коде. Вы пытались выполнить код для простого случая, когда вы получаете ошибку (в отладчике или вручную). Иногда это самый простой путь, утомительный или нет. - person dmckee --- ex-moderator kitten; 27.03.2010
comment
Я надеялся, что это будет моим последним средством. Из-за того, что он работает со сценами, камера которых находится в (0,0,0), но не работает со сценами, камера которых находится в каком-то другом положении, я подумал, что в моей логике была какая-то ошибка при вычислении X и Y. координаты сгенерированной точки на плоскости просмотра. - person Myx; 27.03.2010
comment
есть ли способ прямой интерполяции между верхним левым углом плоскости просмотра и нижним левым углом плоскости просмотра с учетом координаты пикселя (i,j) без отдельного вычисления компонента X и компонента Y? - person Myx; 29.03.2010

Причина, по которой мой код не работал, заключалась в том, что я обрабатывал значения x, y, z отдельно. Это неправильно, поскольку камера может быть направлена ​​в любом направлении, и, таким образом, если бы она была направлена ​​вниз по оси x, координаты x были бы одинаковыми, что давало бы increments из 0 (что неверно). Вместо этого следует выполнить интерполяцию угловых точек (где точки имеют координаты x, y, z). См. ответ в соответствующем сообщении: 3D-координата 2D-точки заданная камера и плоскость обзора

person Myx    schedule 01.04.2010