如何防止视口拉伸/变形?


13

基本上,我想知道当视口/窗口大小改变时如何消除渲染图像的变形或拉伸。

下图举例说明了我正在谈论的变形/拉伸:

原始图像(方形窗口)

无失真

变形/拉伸图像(矩形窗口)

失真

理想情况下,第二个图像应在不进行水平拉伸的情况下显示球体,并向用户显示更多场景,以说明更大的窗口大小。

如何才能做到这一点?

我正在使用OpenGL渲染图像,并且通过调用使用了透视投影:

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60, window.width/window.height, 0.01f, 100.0f)

纵横比width/height与我遇到的所有文档/教程一致,因此我并不认为它是错误的。但是,我怀疑它正在影响拉伸问题。


经过思考

老实说,随着我对这个问题的思考越来越多,我相信解决方案涉及到弯曲(y方向上的视场)角度与纵横比之间的直接比例关系。

透视投影

使用上面的图像作为参考,如果宽度增大(导致水平拉伸),则必须增加fovy角度以引起垂直拉伸,从而“固定”渲染图像的比例,这似乎是很合理的。

同样,宽度的减小要求减小凹角。

更新:

因此,在进一步研究之后,我决定更改设置视锥的方法,如下所示:

gluPerspective(60 * (float)window.width/window.height, (float)window.width/window.height, 0.01f, 100.0f)

我的期望是正确的,这解决了比例问题。但是,它没有达到我想要的结果。当窗口宽度增加时,渲染的图像变小(但球体确实是圆形的)。相反,球体根本不应该改变大小。仅显示的场景量应更改。

Answers:


14

实际上,原始问题是从解决方案中剔除1个问题。

原始码

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60, window.width/window.height, 0.01f, 100.0f)

固定码

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(60, (float)window.width/window.height, 0.01f, 100.0f)

问题在于window.widthwindow.height是整数,这导致长宽比是整数除法的结果。

将尺寸之一转换为浮点数会导致结果改用浮点除法。

由于宽高比现在是正确的,因此不再有原始帖子中所述的拉伸。

编辑:原始帖子(和答案)中的代码只是调用GPU的伪代码;用于输出上述图像的实际程序是用Java编写的。对于那些不使用Java的人,我还没有研究过是否以相同的方式实现整数/浮点除法。无论如何,解决方案都是要确保正确计算出宽高比。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.