Почему обзор камеры в optix отличается от просмотра в OpenGL?
Я работаю над съемкой в 3D-модели по образцу Nvidia Optix. Я изменил Optix SDKgressivePhotonMap, чтобы достичь своей цели. У меня та же позиция камеры, то же направление камеры и то же поле зрения (FOV) в моем коде progressovePhotonMap и OpenGL. Однако вид камеры сильно отличается друг от друга, как показано ниже.
Выходное изображение:
С левой стороны выводится изображение из progressPhotonMap, с другой стороны выводится OpenGL. Вы можете видеть, что левая нижняя точка питания (обозначенная пересечением двух красных линий) не находится на одной и той же позиции на двух изображениях.
Я знаю, что Optix написан на основе OpenGL, поэтому я очень озадачен, почему эти два изображения (вид с камеры) не совпадают с одним и тем же параметром камеры.
Вот моя мысль о причине:
1. Возможно, проблема в параметре ближнего и дальнего, поскольку отображение кадров в GlutDisplay.cpp, gluPerspective() бесполезно. Я не могу дать ближний и дальний параметр.(Даже в ppm.cpp) Так как и где я могу добавить эти два параметра?
2. Может быть, проекционная плоскость optix не на ближней плоскости? В OpenGL мы можем видеть ближнюю плоскость как плоскость проекции, но не в optix?
3.Может ли презентация 3D модели в optix просто отличаться от OpenGL??? (Я обнаружил, что эти две картинки имеют разные искажения друг с другом) Так что я не могу избежать этой ситуации?
Я проследил весь проект и не нашел ничего полезного, кто-нибудь может мне помочь или дать какую-нибудь идею / совет относительно того, почему такая ситуация происходит? Я буду очень признателен за любой ответ. Спасибо!
Существует небольшой исходный код, надеюсь, он будет полезен.
В OpenGL:
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluPerspective(FOV,(GLdouble)windWidth / (GLdouble)windHeight , NEAR, FAR);
gluLookAt(camera_pos[0],camera_pos[1],camera_pos[2],
look_at_target[0],look_at_target[1],look_at_target[2],
up_vector[0], up_vector[1], up_vector[2]);
В optix:
InitialCameraData init_camera;
init_camera = InitialCameraData( make_float3( camera_pos[0], camera_pos[1],camera_pos[2]),make_float3(look_at_target[0],look_at_target[1],look_at_target[2]),make_float3( 0.0f, 1.0f, 0.0f )/*up*/,FOV );
GLUTDisplay::setCamera(init_camera);
signalCameraChanged();
обновление в 21.04 16:11 Reoutput изображений
Я повторно выводю изображения и нахожу hfov(горизонтальное поле зрения), возможно, причина, по-видимому, на двух изображениях высота окна одинакова на моем экране. Насколько мне известно, hfov и vfov одинаковы в gluPerspective в OpenGL. Поэтому я думаю, что hfov является причиной, почему эти два вида камеры отличаются в моем коде optix.
Тем не менее, я до сих пор не знаю, как изменить hfov в ppm.cpp. Я всегда думаю, что FOV, который я даю InitialCameraData, можно указать hfov и vfov. Если эта идея не так, где я должен изменить hfov? Я могу настроить только параметр vfov в качестве исходного кода. Может ли кто-нибудь, кто знаком с образцом прогрессивного PhotonMap, сказать мне, где я могу изменить hfov? Спасибо за любой ответ!
1 ответ
Основное различие / проблема в том, что в Optix я не вижу матрицу проекции. В лучшем случае я вижу, что Optix устанавливает поле обзора одновременно с настройкой информации о камере, но отсутствие параметра Aspect Ratio беспокоит меня, тем более что при более внимательном рассмотрении изображения Optix кресло выглядит сильно искаженным по горизонтальной оси, что представляет меньшую проблему при рендеринге OpenGL (который правильно предоставляет информацию о соотношении сторон).
Еще одна вещь, которую я бы заметил, это то, что вы должны проверить, как Optix ожидает, что будет предоставлен параметр Field of View. GLU ожидает это в градусах и рассматривает это как поле y-поля зрения. Я не знаю, как Optix ожидает этого, но многие API ожидают, что поле зрения будет предоставлено относительно оси X.
В Optix нет камеры, это просто каркас трассировки лучей. Это ваше приложение "снимает" лучи камеры, другими словами, именно вы должны кодировать поведение камеры.
В частности, в примере с прогрессивным фотонным картированием (PPM) есть файл ppm_rtpass.cu. Функция съемки лучей:
RT_PROGRAM void rtpass_camera()
{
float2 screen = make_float2( rtpass_output_buffer.size() );
/*
uint seed = image_rnd_seeds[index]; // If we start writing into this buffer here we will
float2 sample = make_float2( rnd(seed.x), rnd(seed.y) ); // need to make it an INPUT_OUTPUT buffer. For now it
image_rnd_seeds[index] = seed; // is just INPUT
*/
float2 sample = make_float2( 0.5f, 0.5f );
float2 d = ( make_float2(launch_index) + sample ) / screen * 2.0f - 1.0f;
float3 ray_origin = rtpass_eye;
float3 ray_direction = normalize(d.x*rtpass_U + d.y*rtpass_V + rtpass_W);
optix::Ray ray(ray_origin, ray_direction, rtpass_ray_type, scene_epsilon);
HitPRD prd;
// rec.ray_dir = ray_direction; // set in rtpass_closest_hit
prd.attenuation = make_float3( 1.0f );
prd.ray_depth = 0u;
rtTrace( top_object, ray, prd );
}
переменная float2 d содержит нормализованные координаты текущего пикселя, эти значения используются для вычисления направления луча на 2 строки позже. Вот где вы должны посмотреть, если вы хотите исправить код GPU. В противном случае FOV является неявным и зависит от того, как вы масштабируете свои векторы U и V.