OpenGL渲染流程图解析

首先看下OpenGL渲染管线的架构图如下:

OpenGL渲染架构图.jpeg

客户端和服务端

根据架构图所示,我们的渲染管线分为上下两部分,上面部分是客户端,下面部分是服务端。

  • 客户端是存储在CPU存储器中的,并且在应用程序中执行,或者在主系统内存的驱动程序中执行。驱动程序会将渲染命令和数组组合起来,发送给服务器执行!(在一台典型的个人计算机上,服务器就是实际上就是图形加速卡上的硬件和内存)
  • 服务器 和 客户机在功能上也是异步的。 它们是各自独立的软件块或硬件块。我们是希望它们2个端都尽量在不停的工作。客户端不断的把数据块和命令块组合在一起输送到缓冲区,然后缓冲区就会发送到服务器执行。
  • 如果服务器停止工作等待客户机,或者客户机停止工作来等待服务器做好接受更多的命令和准备,我们把这种情况成为管线停滞。

1、客户端

客户端可以向服务端传递三种数据:Attributes、Uniforms、Texture Data。
其中Attributes只可以传递给顶点着色器,Uniforms和Texture Data可以传递给顶点着色器和片元着色器。

Attributes (属性)

就是对每一个顶点都要作改变的数据元素。实际上,顶点位置本身就是一个属性。属性值可以是浮点数、整数、布尔数据。

  • 属性总是以四维向量的形式进行内部存储的,即使我们不会使用所有的 4个分量。一个顶点位置可能存储(x,y,z),将占有4个分量中的3个。实际上如果是在平面情况下:只要在xy平面上就能绘制,那么Z分量就会⾃动设置为0;
  • 属性还可以是:纹理坐标、颜⾊色值、光照计算表面法线;
  • 属性会从本地客户机内存中复制存储在图形硬件中的⼀个缓冲区上。这些属性只提供给顶点着⾊器使用,对于片元着⾊器没有太大意义。
  • 声明:这些属性对每个顶点都要做改变,但并不意味着它们的值不能重复。通常情况下,它们都是不一样的,但有可能整个数组都是同一值的情况。

Uniforms(统一值)

通过设置Uniform 变量就紧接着发送一个图元批次处理命令。Uniform 变量实际上可以无限次的使用. 设置一个应用于整个表面的单个颜色值,还可以设置一个时间值。在每次渲染某种类型的顶点动画时修改它。

  • 这里的uniform 变量每个批次改变一次,而不是每个顶点改变一次。
  • uniform变量最常见的应用是在顶点渲染中设置变换矩阵
  • 与属性相同点:可以是浮点值、整数、布尔值
  • 与属性不同点:顶点着色器和片元着色器都可以使用uniform变量。uniform 变量还可以是
    标量类型、矢量类型、uniform矩阵。

Texture Data(纹理数据)

Texture Data:对纹理进行采样和筛选。纹理数据的作用不仅仅是表现图形。很多图形文件格式都是以无符号字节形式对颜色分量进行存储的,但我们仍然可以设置浮点纹理。这就是说,任何大型浮点数据块(例如消耗资源很大的函数的大型查询表)都可以通过这种方式传递给着色器。

  • 在顶点着⾊器、⽚元着⾊器中都可以对纹理数据进行采样和筛选
  • 典型的应⽤场景:⽚元着⾊器对⼀个纹理值进行采样,然后在⼀个三⻆形表⾯面应用渲染纹理数据
  • 纹理数据,不仅仅表现在图形,很多图形⽂件格式都是以⽆符号字节 (每个颜⾊通道8位)形式对颜色分量进⾏存储的

2、服务端

服务端为GPU硬件部分,主要由Vertex Shader、Primitive Assembly、Fragment Shader组成。

VertexShader(顶点着色器)

  • 顶点着色器是一个可编程的处理单元,功能为执行顶点的变换,光照,材质的应用于计算等顶点的相关操作。工作过程为首先将原始的顶点几何信息及其他属性传送到顶点着色器中,经过自己开发的顶点着色器处理后产生纹理坐标,颜色,点位置等后继流程需要的各项顶点属性信息,然后将其传递给图元装配阶段。
  • 顶点着色器的输入数据由下面组成:-- Attributes:使用顶点数组封装每个顶点的数据,一般用于每个顶点都各不相同的变量,如顶点位置、颜色等。
    -- Uniforms:顶点着色器使用的常量数据,不能被着色器修改,一般用于对同一组顶点组成的单个3D物体中所有顶点都相同的变量,如当前光源的位置。
    -- Texture Data:这个是可选的,表示顶点着色器使用的纹理。

PrimitiveAssembly(图元装配)

  • 顶点着色器之后,渲染管线的下一个阶段是图元装配,图元是一个能用OpenGL绘图命令绘制的几何体,绘图命令指定了一组顶点属性,描述了图元的集合形状和图元类型。顶点着色器使用这些顶点属性计算顶点的位置,颜色以及纹理坐标,这样才能传到片元着色器。
    -这个阶段主要有两个任务,一个是图元组装,另一个是图元处理。
  • 经过裁剪和背面剔除操作后,就进入渲染流水线的下一个阶段:光栅化。

Rasterization(光栅化)

光栅化是将图元转化为一组二维片段的过程,然后,这些片段由片段着色器处理(片段着色器的输入)。这些二维片段代表着可在屏幕上绘制的像素。用于从分配给每个图元顶点的顶点着色器输出生成每个片段值的机制称作插值(Interpolation)。这句不是人话的话解释了一个问题,就是从cpu提供的分散的顶点信息是如何变成屏幕上密集的像素的,图元装配后顶点可以理解成变为图形,光栅化时可以根据图形的形状,插值出那个图形区域的像素(纹理坐标v_texCoord、颜色等信息)。注意,此时的像素并不是屏幕上的像素,是不带有颜色的。接下来的片段着色器完成上色的工作。

FragmentShader(片元着色器)

片元着色器是用于处理片元值及相关数据的可编程单元,其可以执行纹理的采样,颜色的汇总,计算雾颜色等操作。片元着色器主要功能为通过重复执行(每片元一次)将3D物体中的图元光栅化后产生的每个片元的颜色等属性计算出来送入后继阶段;

总结:以上就是对OpenGL渲染管线流程的解析说明,我们在编程的手,多看看,记住这个图就可以进行编程了。

你可能感兴趣的:(OpenGL渲染流程图解析)