OpenGL-入门

通俗来讲,OpenGL是一个图形库,提供了一系列操作图形图像的API。因为OpenGL只是一个规范,具体的实现一般是由显卡提供。类似的图形库还有Windows平台的DirectX、iOS平台的Metal以及新一代的Vulkan

图形渲染管线

图形渲染管线也叫做渲染流水线,指的是将输入的原始图形数据经过渲染管线处理,输出一帧想要的图像的过程。

在OpenGL中,任何事物都在3D空间中,而屏幕和窗口却是2D像素数组,所以图形渲染管线主要是在将输入的3D坐标转换成2D坐标,再将2D坐标转换成实际有颜色的像素。(将输入的3D坐标画在3D坐标系中,然后根据视锥范围截取一个2D平面,将截取的平面转换为平面坐标显示)

2D坐标精确的表示一个点在2D空间的位置;而像素是这个点的近似值,像素的显示受到屏幕分辨率的限制

着色器是运行在GPU上的小程序,这些小程序在图形渲染管线的某个特定部分运行,着色器是一个非常独立的程序,是一种把输入转化为输出的程序,着色器与着色器之间无法通信。蓝色部分代表是可以自定义的着色器。
OpenGL渲染管线

顶点着色器(Vertex Shader)

图形渲染管线的第一部分是顶点着色器,着色器可以看成是一个纯函数,输入的所有顶点,都会依次执行该函数,在该函数中对输入的顶点进行处理,然后输出新的顶点位置。

图元装配(Primitive Assembly)

所谓图元就是几何形状,OpenGL支持的图元有三种:点、线、三角形。而图元装配就是根据定义的图元类型将顶点着色器输出的顶点渲染成单独的图元,然后会图元进行裁剪、透视分割、视口变换。

裁剪:图元根据视锥体进行裁剪。根据视锥体的六个平面进行裁剪,超出视锥体之外的图元都将被裁剪抛弃(并不会真正裁剪,只是标记,x、y、z的绝对值大于1则表示不在视锥体内,会被裁剪)。裁剪后得到的坐标体系为(x,y,z,w),其中w用来在透视分割是处理远近效果。

透视投影-视锥体

正交投影-视锥体

透视分割:将裁剪后的坐标转换为规范化设备坐标。在该转换中会使用w坐标来进行处理,正交投影中w为1,而透视投影中w会根据远近值来生成,越远值越大。透视分割就是讲x、y、z坐标分别除以w,得到新的x、y、z坐标,由于坐标值都是小于w的,所以最终得到的值都是位于[-1,1]之间,这也就是所谓的规范化设备坐标。而对于透视投影来说,w的值越远越大,所以转换后,越远的坐标,转换后值越小,就会形成近大远小的效果。

视口变换:将设备坐标转换为窗口坐标,每个坐标都关联屏幕上的一个点。

几何着色器(Geometry Shader)

几何着色器把图元装配的输出的一系列顶点的集合作为输入,通过产生新顶点构造出新的图元来生成其它形状。

光栅化(Rasterization)

光栅化接收几何着色器的输出作为输入,把图元映射为最终屏幕上相应的像素,生成对应的片段,每个片段代表着一个指定的像素位置,这些片段就是片段着色器中使用的片段,在片段着色器运行之前会执行裁切,裁切会丢弃超出视图以外的所有像素,用来提升执行效率。

片段包含渲染一个像素所需的所有数据

片段着色器(Fragment Shader)

片段着色器的主要目的是计算每个像素应该输出什么颜色,在片段着色器中可以接收到顶点着色器输出的变量。

测试与混合(Tests And Blending)

检测片段对应的深度值,用来判断这个像素是其它物体的前面还是后面,决定是否丢弃,这个阶段也会检查alpha值,并对物体进行混合。