姬長信(Redy)

OpenGL 渲染流程及坐标转换

渲染流程图

渲染流程解析

得益于OpenGL是基于C的集合,可以有很强的跨平台性,以及OpenGL规范中没有窗口层,可以在iOS上无缝对接(iOS12已废弃OpenGL ES),可以在程序中使用OpenGL生成2D、3D图像渲染在屏幕上或者复制回内存里。

从功能角度来看,调用API驱动服务端解析数据、渲染返回结果,这个过程中OpenGL的API集合充当了客户端的角色,而OpenGL底层的着色器和转换充当了服务器端的角色。

从顶点着色器传递数据给 Primitive Assembly后将会把顶点数据转换成图元,并且对图元进行一些处理,正背面剔除发生在此阶段,参考官方文档。处理数据后传递给片元着色器进行处理着色渲染得到结果。

三种通道的数据传递

从图中我们知道有三种通道可以传递数据给着色器处理并正确的渲染出来。那这三种有什么区别呢?

Attribute

通常传递一些经常改变的数值,比如说顶点坐标,纹理坐标、颜色值、光照法线等数据。属性值只能传递给顶点着色器,不能直接传递给片元着色器,需要通过转换间接传递。

Uniform

这种数据比较统一,一般传递不怎么会变化的数据,比如说渲染矩阵等。该通道可以直接传递给顶点着色器和片元着色器。

Texture

纹理就是图片,就是传递图片数据,渲染使用纹理时一像素从纹理中对应的像素进行填充。该通道可以直接传递给顶点着色器和片元着色器。

OpenGL坐标系

视口

视口和视图窗口的大小默认是相等的,也可以单独设置视口的大小,但是一般不这么做。

OpenGL投影方式

有两种投影方式:透视投影和正投影。

透视投影:是为了获取3D视觉效果而在二位坐标系中展示的一种方法,也成透视图。

正投影:平行投射线平行于投影面

OpenGL坐标系转换

  • 在OpenGL中,物体坐标系、世界坐标系、相机坐标系都属于右手系,但是在规范化设备坐标系属于左手系,所以笼统的说OpenGL的坐标系是右手系是不正确的。
  • 而且规范化坐标系的取值在[-1,1]之间,超出将不显示。
  • 在OpenGL来说,一般有五种空间(坐标系):
    • 局部空间 (物体空间)
    • 世界空间
    • 相机空间(观察空间、视觉空间)
    • 裁切空间
    • 屏幕空间
  • 物体从本身的物体坐标系转换到屏幕坐标系会经过几个坐标系的转换,可以参考下面的坐标转换图。
  • 模型变换是为了将通过顶点属性或3D建模创建的模型可以在实际场景中调整大小以及平移旋转至合适的位置。
  • 视变换是根据一个虚拟的相机视觉来描述物体在世界空间的位置,因为我们知道物体从不同的角度去看会发现得到的画面是不一样的。

OpenGL 着色器渲染过程图