Learn OpenGL(一)图形渲染管线(Pipeline)

        在OpenGL中任何事物都在3D空间中, 但是屏幕和窗口是一个2D像素阵列, 所以OpenGL的大部分工作都是关于如何把3D坐标转变为适应你屏幕的2D像素。 3D坐标转为2D坐标的处理过程是由OpenGL的图形渲染管线(Pipeline, 大多译为管线, 实际上指的是一堆原始图形数据途经一个输送管道, 期间经过各种变化处理最终出现在屏幕的过程)管理的。 图形渲染管线可以被划分为两个主要部分:

  • 第一个部分把你的3D坐标转换为2D坐标
  • 第二部分是把2D坐标转变为实际的有颜色的像素

注:
2D坐标和像素也是不同的, 2D坐标是在2D空间中的一个点的非常精确的表达, 2D像素是这个点的近似值, 它受到你的屏幕/窗口解析度的


      图形渲染管线接收一组3D坐标, 然后把它们转变为你屏幕上的有色2D像素。 图形渲染管线可以被划分为几个阶段, 每个阶段需要把前一个阶段的输出作为输入。 所有这些阶段都是高度专门化的(它们有一个特定的函数), 它们能简单地并行执行。 由于它们的并行执行特性, 当今大多数显卡都有成千上万的小处理核心, 在GPU上为每一个(渲染管线)阶段运行各自的小程
序, 从而在图形渲染管线中快速处理你的数据。 这些小程序叫做 着色器(Shader)
      有些着色器允许开发者自己配置, 我们可以用自己写的着色器替换默认的。 这样我们就可以更细致地控制图形渲染管线中的特定部分了, 因为它们运行在GPU上, 所以它们会节约宝贵的CPU时间。 OpenGL着色器是用OpenGL着色器语言(OpenGL Shading Language, GLSL)写成的, 我们在下一节会花更多时间研究它。在下面, 你会看到一个图形渲染管线的每个阶段的抽象表达。 要注意蓝色部分代表的是我们可以自定义的着色器。
 

Learn OpenGL(一)图形渲染管线(Pipeline)_第1张图片


 图形渲染管线包含很多部分, 每个都是将你的顶点数据转变为最后渲染出来的像素这个大过程中的一个特定阶段。 我们会概括性地解释渲染管线的每个部分, 从而使你对图形渲染管线的工作方式有个大概了解。我们以数组的形式传递3个3D坐标作为图形渲染管线的输入, 它用来表示一个三角形, 这个数组叫做顶点数据(Vertex Data); 这里顶点数据是一些顶点的集合。 一个顶点是一个3D坐标的集合(也就是x、 y、 z数据)。 而顶点数据是用顶点属性(Vertex Attributes)表示的, 它可以包含任何我们希望用的数据, 但是简单起见, 我们还是假定每个顶点只由一个3D位置(译注1)和几个颜色值组成的吧。


注:
为了让OpenGL知道我们的坐标和颜色值构成的到底是什么, OpenGL需要你去提示你希望这些数据所表示的是什么类型。


图形渲染管线的第一个部分是顶点着色器(Vertex Shader), 它把一个单独的顶点作为输入。顶点着色器主要的目的是把3D坐标转为另一种3D坐标(看下文), 同时顶点着色器允许我们对顶点属性进行一些基本处理。

基本图形装配(Primitive Assembly)阶段把顶点着色器的表示为基本图形的所有顶点作为输入(如果选择的是 GL_POINTS , 那么就是一个单独顶点), 把所有点组装为特定的基本图形的形状; 上面例子是一个三角形。


基本图形装配阶段的输出会传递给几何着色器(Geometry Shader)。 几何着色器把基本图形形式的一系列顶点的集合作为输入, 它可以通过产生新顶点构造出新的(或是其他的)基本图形来生成其他形状。 例子中, 它生成了另一个三角形。


细分着色器(Tessellation Shaders)拥有把给定基本图形细分为更多小基本图形的能力。 这样我们就能在物体更接近玩家的时候通过创建更多的三角形的方式创建出更加平滑的视觉效果。

细分着色器的输出会进入光栅化(Rasterization也译为像素化)阶段, 这里它会把基本图形映射为屏幕上相应的像素, 生成供片段着色器(Fragment Shader)使用的片段(Fragment)。 在片段着色器运行之前, 会执行裁切(Clipping)。 裁切会丢弃超出你的视图以外的那些像素, 来提升执行效率。

注:
OpenGL中的一个fragment是OpenGL渲染一个独立像素所需的所有数据。


      片段着色器的主要目的是计算一个像素的最终颜色, 这也是OpenGL高级效果产生的地方。 通常, 片段着色器包含用来计算像素最终颜色的3D场景的一些数据(比如光照、 阴影、 光的颜色等等)。
      在所有相应颜色值确定以后, 最终它会传到另一个阶段, 我们叫做alpha测试和混合(Blending)阶段。 这个阶段检测像素的相应的深度(和Stencil)值(见下文), 使用这些, 来检查这个像素是否在另一个物体的前面或后面, 如此做到相应取舍。 这个阶段也会检查alpha值(alpha值是一个物体的透明度值)和物体之间的混合(Blend)。 所以, 即使在片段着色器中计算出来了一个像素所输出的颜色, 最后的像素颜色在渲染多个三角形的时候也可能完全不同。
      图形渲染管线非常复杂, 它包含很多要配置的部分。 然而, 对于大多数场合, 我们必须做的只是顶点和片段着色器。 几何着色器和细分着色器是可选的, 通常使用默认的着色器就行了。
      在现代OpenGL中, 我们必须定义至少一个顶点着色器和一个片段着色器(因为GPU中没有默认的顶点/片段着色器)。 出于这个原因, 开始学习现代OpenGL的时候非常困难, 因为在你能够渲染自己的第一个三角形之前需要一大堆知识。 

你可能感兴趣的:(Opengl)