我正在编写一个太空探索应用程序。我决定将光年定为单位,并准确地模拟了恒星之间的距离。经过修补和大量艰苦的工作(主要是学习绳索)之后,我从横穿宇宙的飞船的角度使相机正常工作。

最初,我在研究行星对象之前一直不注意gluPerspective()的zNear参数。由于我的刻度是以光年为单位,所以我很快意识到,由于zNear为1.0f,所以我看不到此类对象。经过实验后,我得出以下数字:

#define POV 45
#define zNear 0.0000001f
#define zFar 100000000.0f
gluPerspective (POV, WinWidth/WinHeight, zNear ,zFar);


这非常有效,因为我能够使我的太阳系航行(位置0,0,0),并向上移动到看起来明亮且纹理贴图的行星附近。但是,其他系统(不在0,0,0位置)很难通过,因为物体以不寻常的方式从摄像机移开。

但是我注意到,在宇宙中航行时开始出现奇怪的视觉故障。如果我沿Y方向旋转180度,我后面的物体将“环绕”并向前显示,它们也将出现在其原始位置。因此,当在太空中扭曲时,大多数恒星正确地视差,但是有些恒星出现并朝相反的方向行进(至少可以这样打扰)。

通过将zNear更改为0.1f,可以立即纠正所有这些故障(但也无法解决太阳系对象)。所以我被卡住了。我也尝试过使用glFrustum,它会产生完全相同的结果。

我使用以下内容查看世界:

glTranslatef(pos_x, pos_y, pos_z);


使用相关的相机代码按要求进行定位。即使禁用相机功能也不会改变任何东西。我什至尝试了gluLookAt()并再次产生相同的结果。

使用极限zNear / zFar值时,gluPerspective()是否有限制?我试图缩小范围,但无济于事。我什至通过缩放所有内容并使用更大的zNear值将世界单位从光年更改为公里,什么也没有。救命!

最佳答案

问题是您想同时解决太多问题。您想要以太阳系的尺度查看事物,同时还要具有半银河的尺度。那根本不可能。不适用于实时渲染器。

浮点精度只有这么多。而且,由于zNear难以置信地接近,您基本上已经破坏了深度缓冲区,以防距离相机的距离超过0.0001。

您需要做的是根据距离绘制事物。使用一个深度范围(例如0到0.8),使用一个透视矩阵绘制附近的物体(在太阳系的尺度内)。然后,使用不同的透视矩阵和不同的深度范围(0.8到1)绘制更远的对象。这实际上是您使这项工作唯一的方法。

另外,您可能需要使用双精度数学来计算CPU上对象的矩阵,然后将它们转换回单精度以供OpenGL使用。

关于opengl - OpenGL-gluPerspective/glFrustum-zNear和zFar问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7338296/

10-10 19:29