为什么optix中的相机视图与OpenGL不同?

时间:2016-04-20 13:54:55

标签: c++ opengl nvidia optix

我正在努力通过Nvidia Optix样本拍摄3D模型。我修改了Optix SDK progressivePhotonMap以达到我的目标。 我在progressovePhotonMap代码和OpenGL代码中具有相同的摄像机位置,相同的摄像机方向和相同的视野(FOV)。 但是,相机的视图彼此差异很大,如下所示。

输出图片:

enter image description here

左侧是progressivePhotonMap的输出图片,另一侧是OpenGL输出。你可以看到左下方的电源点(用两条红线的交点表示)不在两张图片的同一位置。

我知道Optix是基于OpenGL编写的,所以我很困惑为什么这两张图片(相机视图)在相同的相机参数中不一样。

以下是我对原因的看法:

1.可能问题是接近和远的参数,因为在GlutDisplay.cpp中显示帧,gluPerspective()是无用的。我不能给出near和far参数。(即使在ppm.cpp中)那么如何以及在哪里可以添加这两个参数?

2.也许optix投影平面不在近平面?在OpenGL中,我们可以将近平面视为投影平面,但不能在optix中看到?

3.也许optix中3D模型的呈现与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();

在4/21 16:11更新 Reoutput images

我重新输出图片并找到hfov(水平FOV)可能是原因,似乎在两张图片中我的屏幕中窗口的高度相同。据我所知,hfov和vfov在OpenGL中的gluPerspective中是相同的。所以我认为hfov是我的optix代码中这两个相机视图不同的原因。

但是,我仍然不知道如何修改ppm.cpp中的hfov。我一直认为我给InitialCameraData的FOV可以表示hfov和vfov。如果这个想法错了,我应该在哪里修改hfov?我只能调整vfov参数作为源代码显示。任何熟悉progressivePhotonMap示例的人都可以告诉我在哪里修改hfov吗? 谢谢你的回复!

2 个答案:

答案 0 :(得分:0)

主要区别/问题是在Optix中,我没有看到投影矩阵。最好的情况是,我看到Optix在设置摄像机信息的同时设置了视野,但缺少宽高比参数让我很烦恼,特别是因为看得太近,Optix图像,椅子看起来大大扭曲了在水平轴上,这在OpenGL渲染中不是问题(正确提供有关宽高比的信息)。

我要观察的另一件事是你应该检查Optix如何期望提供Field of View参数。 GLU期望它在Degrees中,并将其视为y-Field-Of-View。我不知道Optix如何期待它,但许多API都希望相对于x轴提供视野。

答案 1 :(得分:0)

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 变量包含已归一化的当前像素坐标,这些值用于在两行之后计算射线方向。如果要修复GPU代码,应在此处查看。否则,FOV是隐式的,取决于您缩放U和V向量的方式。