OpenGL渲染流程

OpenGL渲染流程

渲染框架

之前学习管线的时候,我们知道OpenGL的渲染流程是有固定次序的。那么先了解下渲染框架:

渲染框架

认识OpenGL客户端和服务端的概念

这里的客户端和服务端都是对OpenGL而言。客户端将数据和渲染指令发送给服务端。

  • 客户端是运行在CPU上的程序代码和OpenGL API的调用以及数据的传递。
  • 服务端是OpenGL接收客户端的数据和指令后对GPU的调用。服务端对数据的处理流程大致上流程就是顶点着色器(Vertex Shader)->图元装配(Primitive Assembly)->片元着色器(Fragment Shader)->渲染(Render)

着色器

着色器是使用GLSL编写的程序。GLSL看起来与C语言非常类似,实际上GLSL语言的程序甚至是以我们熟悉的main函数开始的。这些着色器必须从源代码中编译和链接到-起(这一点仍然和C、C++程序非常类似)才能使用。最终准备就绪的着色器程序随后在第一阶段构成顶点着色器,在第二阶段构成片段着色器。请注意,我们目前讨论的是简化的方式。实际上还有一种几何着色器可以(选择性地)安排在两者之间,就像用来将数据来回传递的所有类型的反馈机制一样。还有一些传递片段的处理特性,诸如混合、模板和深度测试。

顶点着色器处理从客户机输入的数据,应用变换,或者进行其他类型的数学运算来计算光照效果、位移、颜色值,等等。为了渲染一个共有3个顶点的三角形,顶点着色器将执行3次,也就是为每个顶点执行一次。在目前的硬件上有多个执行单元同时运行,这就意味着所有这3个顶点都可以同时进行处理。今天的图形处理器属于大规模并行计算机。不要将它们和CPU相比而被时钟速度蒙蔽,它们比图形操作要快上几个数量级。

现在,3个顶点都做好了光栅化的准备。图元组合( Primitive Assembly )框图意在说明3个顶点已经组合在一起,而三角形已经逐个片段地进行了光栅化。每个片段都通过执行片段着色器而进行了填充,片段着色器会输出我们将在屏幕上看到的最终颜色值。再强调一次,今天的硬件是大规模并行运算的,同时执行上百个甚至更多的这种片段程序并不困难。

在OpenGL核心框架中,并没有提供任何内建渲染管线,在提交一个几何图形进行渲染之前, 必须制定一个着色器。我们可以使用的存储着色器。这些存储着色器由GLTools 的C++类GLShaderManager进行管理,它们能够满足进行通常渲染的基本要求。

单位( ldentity)着色器

单位( ldentity )着色器只是简单地使用默认的笛卡尔坐标系(在所有坐标轴上的坐标范围都是1.0~1.0)。所有片段都应用同一种颜色,几何图形为实心和未渲染的。这种着色器只使用一个属性GLT_ATTRIBUTE_VERTEX。vColor参数包含了要求的颜色。

GLShaderManager::UseStockShader (GLT_SHADER_IDENTITY, GLfloat vColor[4]);

平面着色器

平面( Flat)着色器将统一着色器进行了扩展,允许为几何图形变换指定一个4x4变换矩阵。典型情况下这是一种左乘模型视图矩阵和投影矩阵,经常被称作“模型视图投影矩阵”。这种着色器只使用一个属性GLT_ATTRIBUTE__VERTEX

GLShaderManager::UseStockShader(GLT_SHADER_FLAT, GLfloat mvp[16],GLfloat
vCo1or[4]) ;

上色( Shaded)着色器

这种着色器唯一的Uniform 值就是在几何图形中应用的变换矩阵。GLT_ATTRIBUTE_VERTEX
GLT_ATTRIBUTE_COLOR在这种着色器中都会使用。颜色值将被平滑地插入顶点之间(称为平滑着色)。

GLShaderManager::UseStockShader(GLT_SHADER_SHADED, GLfloat mvp[16]);

默认光源着色器

这种着色器创造出一种错觉,类似于由位于观察者位置的单漫射光所产生的效果。从本质上讲,这种着色器使对象产生阴影和光照的效果。这里需要模型视图矩阵、投影矩阵和作为基本色的颜色值等Uniform值。所需的属性有GLT_ATTRIBUTE_VERTEXGLT_ATTRIBUTE_NORMAL。大多数光照着色器都需要正规矩阵( normal matrix )作为Uniform值。

GLShaderManager::UseStockShader(GLT_SHADER_DEFAULT_LIGHT, GLfloat mvMatrix[16], GLfloat pMatrix[16], GLfloat vColor[4]);

点光源着色器

点光源着色器和默认光源着色器很相似,但是光源位置可能是特定的。这种着色器接受4个Uniform值,即模型视图矩阵、投影矩阵、视点坐标系中的光源位置和对象的基本漫反射颜色。所需的属性有GLT_ATTRIBUTE_VERTEXGLT_ATTRIBUTE_NORMAL

GLShaderManager::UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, GLfloat mvMatrix[16], GLfloat pMatrix[16], GLfloat vLightPos[3], GLfloat vColor[4]);

纹理替换矩阵

着色器通过给定的模型视图投影矩阵,使用绑定到nTextureUnit指定的纹理单元的纹理对几何图形进行变换。片段颜色是直接从纹理样本中直接获取的。所需的属性有GLT_ATTRIBUTE_VERTEXGLT_ATTRIBUTE_NORMAL

GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_REPLACE, GLfloat mvpMatrix[16], GLint nTextureUnit);

纹理调整着色器

这种着色器将一个基本色乘以一个取自纹理单元nTextureUnit 的纹理。所需的属性有
GLT_ATTRIBUTE_VERTEXGLT_AT TRIBUTE_TEXTUREO

GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_MODULATE, GLfloat mvpMatrix[16], GLfloat vColor, GLint nTextureUnit);

纹理光源着色器

这种着色器将一个纹理通过漫反射照明计算进行调整(相乘),光线在视觉空间中的位置是给定的。这种着色器接受5个Uniform值,即模型视图矩阵、投影矩阵、视觉空间中的光源位置、几何图形的基本色和将要使用的纹理单元。所需的属性有GLT_ATTRIBUTE_VERTEXGLT_ATTRIBUTE_NORMALGLT_ATTRIBUTE_TEXTUREO

GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, GLfloat mvMatrix, GLfloat pMatrix[16], GLfloat vLightPos[3],
GLfloat vBaseColor[4],GLint nTextureUnit);

当然我们必须首先为这些着色器提供数据,否则什么也做不成。有3种向OpenGL着色器传递渲染数据方法可供程序员选择,即属性、uniform值和纹理。

客户端向服务端传输数据的三种管道

  • attributes(属性)
    • 传输一些经常变动的数据。属性值可以是浮点型、整数或布尔数据。属性总是以思维向量的形式进行内部存储的,即使我们不会用到所有4个分量。比如顶点坐标、颜色值、位移、纹理坐标、光照法线。
    • 属性会从本地客户机内存中复制存储在图形硬件中(这种情况的可能性最大)的一个缓冲区上。这些属性只供顶点着色器使用,对于片段着色器来说没什么意义。在可编程着色器中可以通过GLSL代码间接的传给片元着色器。
  • uniform(统一值)
    • 比较统一、固定、通用的数据,uniform变量既可以是标量类型,也可以是矢量类型。我们也可以使用uniform矩阵。比如旋转矩阵(顶点着色器中使用),颜色转换矩阵(片元着色器中使用)。
    • 可以传给顶点着色器和片元着色器。
  • textureData(纹理数据)
    • 纹理通道就是纹理数据了。一般来说纹理数据无需传给顶点着色器。
    • 可以传给顶点着色器和片元着色器,一般只有片元着色器会用到。
  • out(输出)
    • 输出数据是作为一个阶段着色器的输出定义的,而在后续阶段的着色器则是作为输入(in)定义的。
    • 输出类型的数据可以简单地从一个阶段传递到下一个阶段,也可以以不同的方式插入。客户端的代码接触不到这些内部变量,但是它们在顶点着色器和片段着色器中(还可能包括可选的几何着色器)都进行了声明。
    • 顶点着色器为输出变量分配一个值,这个值是常量,也可以在图元被光栅化时插入到顶点之间。片段着色器对应的同名输入值接受这个常量或插入值。

图形文件渲染过程

  • 在我们的场景中,我们主要考虑一个三维坐标空间。图形管线被拆解为主要的两部分。
    • 第一部分是前端(front end),处理顶点和图元,最后把它们组成为点、线和三角形传递给光栅器。这个过程被称为图元组装(primitive assembly)。
    • 光栅器处理之后,几何图形已经被转变成大量的独立的像素。这些都是交给后端的(back end)的,它包括深度(depth)测试和模板(sencil)测试,片段着色(fragment shading),混合(blending)以及更新输出图像。
渲染流程
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 225,226评论 6 524
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 96,509评论 3 405
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 172,523评论 0 370
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,181评论 1 302
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,189评论 6 401
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,642评论 1 316
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,993评论 3 431
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,977评论 0 280
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,527评论 1 326
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,547评论 3 347
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,661评论 1 355
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,250评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,991评论 3 340
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,422评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,571评论 1 277
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,241评论 3 382
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,737评论 2 366

推荐阅读更多精彩内容