四、OpenGL渲染流程(图片从文件渲染到屏幕上的解析过程)

管线

管线这个术语描述了OpenGL渲染的整个过程。OpenGL采用CS模型:C是CPU,S是GPU,C给S的输入是Vertex信息和Texture信息,S输出的是显示器上显示的图像。

管线
openGL渲染流程
openGL渲染管线架构图(图片转载自https://www.jianshu.com/p/c0e71b4c1bf4)

客户端是存储在CPU中的,驱动程序将渲染命令与数据组合起来发送给存储在GPU中的服务器执行。
二者是异步的。客户端不断的将数据和命令组合在一起送入缓冲区,缓冲区再发送到服务器执行。

接下来我们逐步进行探究

1.顶点数组对象或顶点缓冲区(VBO/VAO)

顶点数组对象是CPU提供给GPU的顶点信息,包括了顶点的位置、颜色(只是顶点的颜色,和纹理的颜色无关)、纹理坐标(用于纹理贴图)等顶点信息。
attrubutes属性只能传入顶点着色器,不能直接传递到片元着色器,只能通过GLSL代码间接传递。
顶点数据
纹理坐标
光照法线
颜色数据
uniforms值可以传入顶点着色器、片元着色器。

2.顶点着色器(VertexShader)

画画的时候我们经常有这么一个过程:先打线稿,再上色。着色器就是用来做这个工作的。
顶点着色器是告诉电脑如何打线稿的——如何处理顶点、法线等的数据的小程序。

顶点着色器是一个可编程单元,功能为执行顶点的变换、光照、材质的应用与计算等顶点的相关操作。工作过程为首先将原始的顶点几何信息及其他属性传送到顶点着色器中,经过自己开发的顶点着色器处理后产生纹理坐标、颜色、点位置等后继流程需要的各项顶点属性信息,然后将其传递给图元装配阶段。
顶点着色器的输入主要为待处理顶点相应的attribute变量、uniform变量、采样器以及临时变量或纹理数据;输出主要为经过顶点着色器生成的varying变量及一些内建输出变量。
顶点着色器的输入数据由下面组成:

  • Attributes: 使用顶点数组封装每个顶点的数据,一般用于每个顶点都各不相同的变量,如顶点位置、颜色等。
  • Uniforms:顶点着色器使用的常量数据,不能被着色器修改,一般用于对同一组顶点组成的单个3D物体中所有顶点都相同的变量,如当前光源的位置。
  • Texture Data:这个 是可选的,表示顶点着色器使用的纹理。

我们可以通过attrubutes获取到顶点数据,通过uniforms获取到mvp矩阵,再进行运算得到最终的顶点坐标。

gl_Position = M_pro * M_view * M_model * V_local

3.图元装配(PrimitiveAssembly)

顶点着色器下一个阶段是图元装配,图元(prmitive)是三角形、直线或者点精灵等几何对象。这个阶段,把顶点着色器输出的顶点组合成图元。
这个阶段主要有两个任务:

  • 图元组装:是指顶点数据根据设置的绘制方式被组合成完整的图元,例如:点绘制方式下仅需要一个单独的顶点,每个顶点为一个图元;线段绘制方式则需要两个顶点,每两个顶点构成一个图元。
  • 图元处理:这阶段最重要的是裁剪,对于每个图元,必须确定它是否位于视椎体内(三维空间显示在屏幕上的可见区域),如果图元部分在视椎体内,需要进行裁剪,如果图元全部在视椎体外,则丢弃图元。裁剪之后,顶点坐标变成了屏幕坐标。背面剔除操作也会执行,它根据图元是正面还是背面,如果是背面则丢弃图元,经过裁剪和背面剔除操作,就进入下一个阶段:光栅化。

基本图元

基本图元
  • GL_POINTS 每个顶点在屏幕上都是单独点
    GL_LINES 每⼀对顶点定义⼀个线段
    GL_LINE_STRIP 一个从第⼀个顶点依次经过每⼀个后续顶点而绘制的线条
    GL_LINE_LOOP 和GL_LINE_STRIP相同,但是最后⼀个顶点和第⼀个顶点连接起来了
    GL_TRIANGLES 每3个顶点定义⼀个新的三角形
    GL_TRIANGLE_STRIP 共⽤一个条带(strip)上的顶点的一组三⻆形
    GL_TRIANGLE_FAN 以⼀个圆点为中⼼呈扇形排列,共⽤相邻顶点的⼀组三⻆形

4.光栅化

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

通俗解释:
首先,光栅化(Rasterize/rasteriztion)。这个词儿Adobe官方翻译成栅格化或者像素化。没错,就是把矢量图形转化成像素点儿的过程。我们屏幕上显示的画面都是由像素组成,而三维物体都是点线面构成的。要让点线面,变成能在屏幕上显示的像素,就需要Rasterize这个过程。就是从矢量的点线面的描述,变成像素的描述。如下图,这是一个放大了1200%的屏幕,前面是告诉计算机我有一个圆形,后面就是计算机把圆形转换成可以显示的像素点。这个过程就是Rasterize。


光栅化

5.片元着色器

是告诉电脑如何上色的——如何处理光、阴影、遮挡、环境等等对物体表面的影响,最终生成一副图像的小程序。

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

  • 顶点着色器输出的varying变量经过光栅化插值计算后产生的作用于每个片元的值。
  • Uniforms:片元着色器使用的常量数据。
  • Texture Data:表示片元着色器使用的纹理数据。

片段着色器为片段(像素)上的操作实现了通用的可编程方法,光栅化输出的每个片段都执行一遍片段着色器,对光栅化阶段生成每个片段执行这个着色器,生成一个或多个(多重渲染)颜色值作为输出。


片元着色器
纹理

像素数据。片元着色器中,可以通过纹理坐标获取到对应的颜色值。如果对得到的颜色值进行处理,就可以得到“滤镜”效果。

顶点的着色器和片元着色器之间的区别: 顶点着色(包括细分和几何着色)决定了一个图元应该位于屏幕的什么位置,而片元着色使用这些信息来决定某个片元的颜色应该是什么。

着色器的渲染:
顶点着色器(必要)
细分着色器(可选)
几何着色器(可选)
片元着色器(必要)

6.逐片段操作

在此阶段,每个片段上执行如下功能:

逐片段操作

(1)pixelOwnershipTest(像素归属测试):
这个用来确定帧缓冲区中位置(x,y)的像素是不是归当前上下文所有。例如,如果一个显示帧缓冲区窗口被另一个窗口所遮蔽,则窗口系统可以确定被遮蔽的像素不属于此opengl的上下文,从而不显示这些像素。
(2)ScissorTest(剪裁测试):
如果该片段位于剪裁区域外,则被抛弃
(3)StencilTest and DepthTest(模板和深度测试):
深度测试比较好理解,若片段着色器返回的深度小于缓冲区中的深度,则舍弃。模板测试没有用过,不清楚具体功能,猜测功能应该和名字一样,模板形状内可通过。
(4)Blending(混合):
将新生成的片段颜色值与保存在帧缓冲区的颜色值组合起来,产生新的RGBA。
(5)dithering(抖动):
不知道这个是神马作用?
最后把产生的片段放到帧缓冲区(前缓冲区或后缓冲区或FBO)中,若不是FBO,则屏幕绘制缓冲区中的片段,产生屏幕上的像素。

7.固定管线

固定管线是没有shader参与的OpenGL绘制管线,OpenGL3.0已经废除了这个功能。

后注:

有些概念仍然不够通俗易懂,下面我们再深入理解一下:

渲染管线其实说白就是流水线,和我们平时看到的工厂流水线差不多一个意思。就是说上个工序加工过的东西会送到下个阶段进行再次加工。比如顶点着色器处理顶点数据后,会送到光栅化阶段!
那什么是光栅化呢?首先我们需要明白一个概念,就是计算机只能处理离散的数据,而我们现实世界都是连续的,所以如何将我们输入的连续数据进行离散化呢?答案就是光栅化!其实光栅化就是个离散化的过程,现在一般都是硬件来处理的,效率很高!
我们通过光栅化得到了离散的片段或像素后,那到底该像素显示什么颜色呢?答案就是用着色器来控制像素的颜色!着色器可以理解为上色,好比你画画,你需要给画图上各种颜色,着色器道理也是一样的!只不过它可以用来控制GPU的着色效果,实现屏幕上各种酷炫的效果!

学习参考:
细说图形学渲染管线
OpenGL渲染流程
OpenGL基础渲染
OpenGL渲染流程图解析

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,752评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,100评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,244评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,099评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,210评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,307评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,346评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,133评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,546评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,849评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,019评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,702评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,331评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,030评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,260评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,871评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,898评论 2 351