问题描述
我正在处理一张大型地图,并且存在深度精度问题(z战斗),因此我使用了此post中提到的双重摄像头技巧。这是我非常基本的设置:
我按如下方式创建两个摄像机(摄像机类使用glm :: perspective):
// constructor: Camera3D(fov,aspect_ratio,near plane,far plane)
n_camera = Camera3D(60,screen_width / screen_height,0.1f,1000.0f);
f_camera = Camera3D(60,1000.0f,1000000.0f);
然后我将渲染如下:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// far pass:
f_camera.Bind(); // DrawScene will use the far camera
DrawScene();
// near pass:
glClear(GL_DEPTH_BUFFER_BIT);
n_camera.Bind(); // DrawScene will use the near camera
DrawScene();
问题在于,近距相机和远距相机之间的连接断开很小(即,我看到地图的近距和远距之间的缝隙很小)。
据我了解,近摄镜头的视锥和远摄镜头的视锥共同构成一个大的连续视锥,看起来就像我的相机从0.1f变为1000000.0f。但是事实并非如此,因为我们看到了这一差距。
这意味着我必须需要一些附加的逻辑才能为远距摄像机计算不同的视野或近平面值。我不知道如何得出该值的计算。有什么想法吗?
解决方法
正如@httpdigest所说,这是一个深度范围问题。两个渲染调用都渲染到深度范围的相同部分。我在khronos openGL社区中找到了这个question,它使用glDepthRange显示了一个代码段。我遵循了类似的设置:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// far pass:
glDepthRange(0.9f,1.0f);
f_camera.Bind(); // DrawScene will use the far camera
DrawScene();
// near pass:
glDepthRange(0.0f,0.9f);
glClear(GL_DEPTH_BUFFER_BIT);
n_camera.Bind(); // DrawScene will use the near camera
DrawScene();
这完全解决了该问题。之所以可行,是因为远距离通过并不需要很多深度精度,但这确实使近平面的精度降低了0.1,因此它对近距离摄影机产生了不良影响,因为某些三角形使z争斗了。我通过将近摄镜头的近平面增加到0.5来解决此问题。