Трассировка лучей: искажение сферы из-за движения камеры

Я строю Ray Tracer с нуля. Мой вопрос:
Когда я меняю координаты камеры, Сфера меняется на эллипс. Я не понимаю, почему это происходит.

Вот несколько изображений, чтобы показать артефакты:

Sphere: 1 1 -1 1.0 (Center, radius)
Camera: 0 0 5 0 0 0 0 1 0 45.0 1.0 (eyepos, lookat, up, foy, aspect)

введите камеру 0 0 5 0 0 0 0 1 0 45,0 1,0

Но когда я изменил координату камеры, сфера выглядит искаженной, как показано ниже:

Camera: -2 -2 2 0 0 0 0 1 0 45.0 1.0

введите описание изображения здесь

Я не понимаю, что не так. Если кто-то может помочь, это было бы здорово!

Я установил свой imagePlane следующим образом:

   //Computing u,v,w axes coordinates of Camera as follows:

{
Vector a = Normalize(eye - lookat);  //Camera_eye - Camera_lookAt
Vector b = up;    //Camera Up Vector
m_w = a;
m_u = b.cross(m_w);
m_u.normalize();
m_v = m_w.cross(m_u);
}

После этого я вычисляю направления для каждого пикселя из положения камеры (глаза), как указано ниже:

//Then Computing direction as follows:

int half_w = m_width * 0.5;
int half_h = m_height * 0.5;

double half_fy = fovy() * 0.5;
double angle = tan( ( M_PI * half_fy) / (double)180.0 );

for(int k=0; k<pixels.size(); k++){
double j = pixels[k].x();       //width
double i = pixels[k].y();       //height

double XX = aspect() * angle * ( (j - half_w ) / (double)half_w );
double YY  =           angle * ( (half_h - i ) / (double)half_h );

Vector dir = (m_u * XX + m_v * YY) - m_w ;directions.push_back(dir);
}

После этого:

 for each dir:

Ray ray(eye, dir);
int depth = 0;
t_color += Trace(g_primitive, ray, depth);

2

Решение

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

Итак, вышеприведенный код совершенно корректен. Исходя из моих собственных предположений (как упомянуто в комментариях выше), я решил установить параметры моей камеры таким образом.

Проблема, о которой я упоминал выше, заключается в нормальном поведении камеры (как также упоминалось выше в комментариях).

Я получил хорошие результаты сейчас, но есть несколько вещей, которые нужно проверить при кодировании rayTracer:

  1. Обязательно позаботьтесь о преобразовании радиан в градусы (или наоборот) при вычислении FOV и ASPECT RATIO. Я сделал это следующим образом:
     double angle = tan((M_PI * 0.5 * fovy) / 180.0);
double y = angle;
double x = aspect * angle;

2) При расчете пересечений треугольника убедитесь, что перекрестное произведение правильно реализовано.

3) При использовании пересечений различных объектов обязательно найдите пересечение, которое находится на минимальном расстоянии от камеры.

Вот результат, который я получил:
введите описание изображения здесь

Выше очень простая модель (любезно предоставленная UCBerkeley), которую я проследил.

2

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

Это правильное поведение. Возьмите камеру с широкоугольным объективом, поместите сферу около края поля зрения и сделайте снимок. Затем в приложении для фотографий нарисуйте круг поверх фотографии сферы, и вы увидите, что это не круглая проекция.

Этот эффект будет усилен тем фактом, что вы устанавливаете аспект на 1,0, но ваше изображение не квадратное.

Несколько вещей для исправления:

  • Вектор направления (от — до). У вас есть (от — до), поэтому a указывает назад. Вы хотите добавить m_w в конце, а не вычесть его. Кроме того, это исправление повернёт ваши m_u, m_v на 180 градусов, что заставит вас изменить (j — half_w) на (half_w — j).

  • Кроме того, размещение всех пикселей и всех направлений в списках не так эффективно, как просто зацикливание значений x, y.

1

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