0

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

输出图像:

在此处输入图像描述

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

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

这是我认为的原因:

1.可能是near和far参数的问题,因为在GlutDisplay.cpp中显示帧,gluPerspective()没用。我不能给出近和远参数。(即使在 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 重新输出图像

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

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

4

2 回答 2

0

主要区别/问题是在 Optix 中,我没有看到投影矩阵。充其量,我看到 Optix 在设置相机信息的同时设置了视野,但是缺少纵横比参数让我很困扰,特别是因为更仔细地观察 Optix 图像,椅子似乎被严重扭曲了在水平轴上,这在 OpenGL 渲染中问题不大(它正确地提供了有关纵横比的信息)。

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

于 2016-04-21T14:15:48.227 回答
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变量包含归一化的当前像素坐标,这些值用于在 2 行之后计算光线方向。如果你想修复 GPU 代码,你应该去那里看看。否则,FOV 是隐式的,取决于您如何缩放 U 和 V 矢量。

于 2019-01-11T12:51:45.607 回答