OpenGL ES 2.0 渲染管线

OpenGl是一个跨平台的3D图形API标准,OpenGL ES是其适用于便携或嵌入式设备的版本。本文介绍OpenGL ES 2.0的渲染管线。

OpenGL ES 2.0 渲染管线

OpenGL ES 2.0 的渲染管线如下图所示,其中深色的方格代表OpenGL ES 2.0渲染管线中的可编程部分。

alt text

顶点着色器 Vertex Shader

顶点着色器实现了一系列操作顶点的编程方法。顶点着色器的输入包括以下几部分:

  • Attributes :由顶点数组提供的逐顶点的数据
  • Uniforms :顶点着色器使用的常量数据
  • Samplers :一种特定种类的uniform,表示顶点着色器使用的纹理。在顶点着色器中,Samplers是可选项
  • Shader program :顶点着色器的源代码或可执行程序,描述了对顶点进行的操作

顶点着色器的输出称为varying变量,在初始的栅格化阶段,varying变量的值将针对生成的每一个片段进行计算,并作为输入传递给片段着色器。使用插值的方法从顶点varying变量值得到片段的varying变量值。顶点着色器的输入输出参考下表:

alt text

顶点着色器被可用来实现传统的基于顶点的操作,例如位移矩阵、计算光照方程、逐顶点生成颜色、生成和变化纹理坐标等。同时,由于顶点着色器由应用程序指定,它还可以实现一些自定义的顶点变换。

图元装配 Primitive Assembly

在渲染管线中,顶点着色器之后的阶段是图元装配。图元是在OpenGL ES中可直接使用绘制命令绘出的几何体。这些绘图命令定义了一系列描述图元几何和图元类型的顶点attribute。每个顶点都由一些顶点attribute来描述。这些attribute包含有顶点着色器用来计算位置的信息及其它的传递给片段着色器的信息如颜色和纹理坐标。
在图元装配阶段,着色的顶点被装配成可绘制的几何图元,如三角形、直线或点。对于每一种图元,必须判断该图元是否位于截头锥体内(截头锥体是屏幕上可见的3D空间区域)。如果该图元没有完全在截头锥体内,该图元将被截头锥体剪掉一部分;如果图元完全位于截头锥体外部,则该图元将被直接丢弃。被截头锥体剪切之后,顶点的位置坐标将被转化到屏幕坐标系。还可以根据图元的面朝向前或后使用剔除操作以丢弃一部分图元。在剪切与剔除之后,图元就做好了准备进入栅格化阶段。

栅格化 Rasterization

图元(三角形、直线或点)在栅格化阶段被绘制。栅格化是将图元转化为二维片段的过程。二维片段由片段着色器来处理,代表的是绘制在屏幕上的像素点。栅格化的过程参见下图。

alt text

片段着色器 Fragment Shader

片段着色器实现了一系列操作片段的编程方法。片段着色器作用于在栅格化阶段生成的每一个片段上,并使用以下的输入:

  • Varying: 由顶点着色器输出,并且使用插值方法生成对应于每一个片段的变量值
  • Uniforms: 片段着色器使用的常量数据
  • Samplers: 一种特定种类的uniform,表示片段着色器使用的纹理
  • Shader program: 片段着色器的源代码或可执行程序,描述了对片段进行的操作

片段着色器可以丢弃片段或根据gl_FragColor生成颜色值。栅格化阶段产生的颜色、深度、模板和屏幕坐标位置(xw,yw)等信息将成为管线逐片段操作阶段的输入量。

alt text

逐片段操作

片段着色器的后一个阶段是逐片段操作。栅格化生成的位于屏幕坐标 (xw, yw) 的片段只能修改帧缓冲(framebuffer)内位于 (xw, yw) 的片段,如下图所表述:

alt text

逐片段操作阶段对每个片段完成以下的功能或测试:

  • 像素点所有权测试: 这项测试是判断帧缓冲中位于 (xw, yw)的像素点是否被OpenGL ES所占有。 像素点所有权测试可使操作系统控制帧缓冲中的哪些像素点属于当前的OpenGL ES上下文环境。举例说明:如果一个窗口显示的OpenGL ES帧缓冲被另一个窗口所遮挡,则系统会判定被遮挡的像素点不被OpenGL ES上下文环境所占有,因此会不显示这些像素点
  • 剪切测试: 剪切测试判断坐标 (xw, yw)是否位于剪切矩形的内部,剪切矩形是OpenGL ES状态的一部分。位于剪切矩形外部的像素点将被丢弃
  • 模板(stencil)和深度测试: 使用模板和深度值判断片段是否要被舍弃
  • 混合: 混合过程将合并新生成的片段颜色值与帧缓冲中位于(xw, yw)已存储的颜色值
  • 抖动: 抖动会最小化在帧缓冲中由颜色值存储精度限制而引起的问题

在逐片段操作的最后,片段或是被丢弃,或是将片段颜色值、深度和模板值写入帧缓冲中位于 (xw, yw)的位置。而是否使用掩码(mask)决定了片段的颜色、深度和模板值如何写入。掩码可以更好地控制颜色、深度和模板值写入适当的缓冲区中。例如,可以设置用于颜色缓冲区的掩码,以达到禁止红色颜色值写入颜色缓冲的目的。

除此之外,OpenGL ES 2.0还提供了从帧缓冲中读取像素点的接口,可读回的仅包括像素点的颜色,不包括深度和模板值。

REFERENCE

OpenGL ES 2.0 ProgrammingGuide
https://www.khronos.org/opengles/2_X/