想象一下,你正置身于一个桌子面前,你站在桌子的一端,目光穿过桌面,从你的角度来看,桌面呈现出一种倾斜的视觉效果,因为你是从侧面以一定的角度向下观察,而不是像鸟儿一样从空中俯瞰。
OpenGL在渲染二维图形方面表现出色,但当我们引入第三维度时,整个场景就会变得更加生动和立体。在本篇中,我们将探索如何利用OpenGL进入三维世界,体验从桌子的一侧向对端望去的视角。
本篇的学习计划如下:
- 首先,我们将掌握OpenGL中的透视除法概念,了解如何利用W分量在二维屏幕上创造出三维的视觉效果。
- 理解W分量后,我们将学习设置透视投影,以便能够看到桌子的三维形态。
我们将在上一篇的项目上继续,开始我们的三维之旅。
三维的艺术
在艺术史上,艺术家们已经掌握了一种将二维平面转化为三维空间幻象的技艺,这种技艺被称为线性投影。通过在假想的消失点汇聚平行线,他们创造出了一种深度和立体的视觉效果。
想象一下站在铁轨旁,当你望向远方,铁轨似乎逐渐靠近,最终在地平线上汇聚于一点。这种视觉上的汇聚现象,正是线性投影效果的生动体现。随着距离的增加,铁轨上的枕木看起来越来越小,它们的尺寸与观察者之间的距离成反比。
在接下来的内容中,我们将深入探讨OpenGL是如何实现这种三维投影的。通过观察右图中的枕木宽度随距离递减的变化,我们可以更好地理解这种技术是如何在计算机图形学中被应用的。让我们继续学习OpenGL看如何将这种视觉效果转化为实现。
着色器到屏幕坐标转换
我们已经对归一化设备坐标有了基本的了解,并且知道为了在屏幕上正确显示顶点,其x、y和z坐标值必须位于[-1, 1]的范围内。接下来,让我们通过下面的流程图来回顾一下,顶点着色器中的原始gl_Position坐标是如何经过一系列变换,最终映射到屏幕坐标的。
这个转换过程包括两个主要的变换步骤,并且涉及到三个不同的坐标空间。
1.剪裁空间
当顶点着色器输出顶点位置到gl_Position时,OpenGL要求这个位置必须位于剪裁空间内。在剪裁空间中,顶点的X、Y和Z坐标值必须位于-W和W之间。例如,如果顶点的W分量是1,那么X、Y和Z坐标的值必须在-1到1的范围内。超出这个范围的顶点将不会被渲染到屏幕上。透视除法的逻辑依赖于这个W分量,因为它通过除以W分量来调整坐标,确保顶点在屏幕上的透视效果得以正确表现。
一旦我们理解了透视除法,它依赖于顶点的W分量的原因就会变得清晰。
2.透视除法
在OpenGL中,顶点位置在成为归一化设备坐标(NDC)之前,会经过一个称为透视除法的步骤。透视除法的作用是将顶点的x、y和z分量除以其W分量,这样处理后的坐标,无论渲染区域的实际大小和形状如何,其x、y和z分量的值都将位于[-1, 1]的范围内。
透视除法是创建三维视觉效果的关键。通过将gl_Position的x、y和z分量除以W分量,远处的物体在视觉上被拉近,仿佛它们都汇聚于一个消失点。这种技术模仿了艺术家们几个世纪以来使用的视觉欺骗技巧。
例如,考虑两个顶点,它们在三维空间中具有相同的x、y和z坐标,但W分量不同。假设这两个顶点的坐标分别是(1, 1, 1, 1)和(1, 1, 1, 2)。在进行透视除法后,这些坐标的前三个分量分别除以它们的W分量,结果变为(1, 1, 1)和(0.5, 0.5, 0.5)。归一化设备坐标最终变为(1, 1, 1)和(0.5, 0.5, 0.5),其中W值较大的顶点在视觉上更接近屏幕中心。
在OpenGL中,这种三维效果是线性的,并且沿着直线完成,这与现实生活中的复杂视觉效果(如鱼眼镜头产生的效果)不同,这种线性投影只是合理的近似。
同质化坐标
因为透视除法,剪裁空间中的坐标经常也被称为同质化坐标(homogenous coordinates)。这种坐标系统是由August Ferdinand Möbius在1827年引入的。同质化坐标之所以被称为“同质化”,是因为不同的坐标值可以通过相同的比例因子转换到NDC中的相同点。
例如,考虑以下一组点,它们在剪裁空间中具有不同的坐标值:
(1, 1, 1, 1)
(2, 2, 2, 2)
(3, 3, 3, 3)
(4, 4, 4, 4)
(5, 5, 5, 5)
尽管这些点在剪裁空间中的坐标各不相同,但通过透视除法,即将每个坐标值除以其W分量,它们都可以被转换到NDC中的同一个点(1, 1, 1)。
除以w的优势
为什么在OpenGL中,我们不仅仅简单地除以z坐标,而是使用一个额外的W分量来进行透视除法。
首先,让我们考虑一个简单的例子。假设我们有两个点,它们的坐标分别是(1,1,1)和(1,1,2)。如果我们按照直观的想法,仅仅将x和y坐标除以z坐标,我们会得到两个归一化的二维坐标(1,1)和(0.5,0.5)。这个方法看似有效,但OpenGL选择了一个更灵活的方法。
引入W分量,也就是同质化坐标,我们不仅能够实现归一化,还能在不同的投影模式之间灵活切换。这样做的好处是,我们可以将投