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

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

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

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);

person sinner    schedule 06.01.2013    source источник
comment
Вы видели ответ на этот вопрос?   -  person jon-hanson    schedule 08.01.2013
comment
Спасибо Джон-Хэнсон. Я много играл со своей реализацией и обнаружил, что если мой camera's all three xyz corrdinates are non-zero, то он показывает искажение, но если любой из xyz coordinate is zero, то он работает нормально. Я думаю, что это может быть из-за искажения перспективы, но я хотел бы знать, есть ли что-то еще, что может быть причиной этой проблемы.   -  person sinner    schedule 08.01.2013
comment
Спасибо и за ссылку. Я проверил значение параметра FOV, и все в порядке. Я изменил его на 30 и 15 соответственно, но результат все тот же.   -  person sinner    schedule 08.01.2013
comment
Но я до сих пор не могу найти правильный ответ на этот вопрос. Если кто-нибудь знает, было бы здорово!   -  person sinner    schedule 19.01.2013
comment
Попробуйте расширить свою программу для рендеринга массива (также известного как сетка) сфер. Например. 5 слева направо х 5 снизу вверх. Средняя сфера будет в середине обзора. Сделайте радиус сферы меньше половины расстояния между ними. Если вам это не поможет, то выложите фото.   -  person jon-hanson    schedule 19.01.2013
comment
вроде все правильно делал. Такое поведение искажения сферы связано с перспективой. Я скоро отвечу на этот вопрос и добавлю больше примеров, чтобы закрыть эту тему выводом. Большое спасибо @jon-hanson за помощь! :)   -  person sinner    schedule 23.01.2013


Ответы (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), для которой я выполнил трассировку лучей.

person sinner    schedule 01.04.2013

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

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

Несколько вещей, которые нужно исправить:

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

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

person All the Rage    schedule 22.02.2013
comment
Привет Rage, Спасибо за ваши комментарии, но: 1) Vecter — это мой собственный тип данных для математических векторов. 2) Направление преднамеренно задано таким образом, чтобы обеспечить согласованность со спецификациями камеры OpenGL (например, в OpenGL Z -ve вниз по оси), а также для предотвращения переворачивания изображения. 3) И поскольку я считаю, что начало моего изображения (которое в итоге сгенерировано) находится в ВЕРХНЕМ_ЛЕВОМ углу, поэтому его j-half_w и half_h-i - person sinner; 01.04.2013