OpenGL图形图像渲染流程

渲染 Rendering

将图形/图像数据转换成2D空间图像的操作叫做渲染。

顶点数组 VertexArray 和 顶点缓冲区 VertexBuffer

顶点指的是我们在绘制⼀一个图形时,它的顶点位置数据。这个数据可以直接存储在计算机内存的数组中或者缓存到GPU的内存中。

现实中绘画往往是先勾勒图像的骨架,然后再往⻣架里面填充颜色,这对于OpenGL绘制图形也是一样的。

顶点数据就是要画的图像的⻣架,和现实中不同的是,OpenGL中的图像都是由图元组成。在OpenGL ES中,有3种类型的图元:点、线、三⻆角形。那这些顶点数据最终是存储在哪里?

开发者可以选择设定函数指针,在调⽤绘制⽅法的时候,直接由内存传⼊顶点数据,这部分数据之前是存储在内存当中的,被称为顶点数组。然而性能更好的做法是,使用OpenGL分配一块显存,将顶点数据预先传⼊到显存当中,这部分的显存,就被称为顶点缓冲区。

管线

OpenGL渲染图形,会按顺序的经过一个个任务处理。就像装配产品的流水线一样,OpenGL渲染图形的每个任务也类似流水线般执行,并且任务之间有先后顺序。

管线是一个抽象的概念,之所以称之为管线是因为显卡在处理理数据的时候也是按照⼀个固定的顺序来的,⽽且严格按照这个顺序。就像水从一根管⼦的一端流到另一端,这个顺序不能打破。

固定管线

固定管线把渲染的过程,光照过程都封装到了OpenGL里边了,代码执行流程都写死了,不需要也不允许你自己去定义顶点渲染和片元(像素)渲染的具体逻辑,比如光照、漫反射、环境光 、高光计算都写死到了OpenGL里,你不能改变渲染流程,只需要开发者在CPU代码端输入渲染所需要的参数并指定特定的开关,就能完成不同的渲染。

下图是固定渲染管线的流程图,OpenGL内部从取到数据开始,会经历下列的步骤最终形成可显示的画面。图中橘色的部分在可编程渲染管线中会被替换成可编程的顶点渲染部分(Vertex Shader)和片元(像素)渲染部分(Fragment Shader)。

固定渲染管线的流程图

但是由于OpenGL的使⽤场景非常丰富,固定管线无法满足每⼀个渲染任务。因此将相关部分开放成可编程的,即引入了可编程管线

可编程管线

可编程管线:OpenGL在1.5版本以后加入了着色器(Shader)脚本语言,很多流程不再内置,必须由开发者自行实现渲染流程, 包括光照处理都需要在外部自己写,否则无法绘制出最终的画面。

开发者可以根据自己的具体需要来编写顶点渲染和片元(像素)渲染中的具体逻辑,可最大程度的简化渲染管线的逻辑以提高渲染效率,也可自己实现特定的算法和逻辑来渲染出固定管线无法渲染的效果。具有很高的可定制性,但同时也对开发者提出了更高的要求。

下面OpenGL可编程管线流程图,其中展示的橘色部分就是必须由开发者自行编程的部分,顶点渲染部分(VertexShader)用于处理模型的形状给后续的步骤输出一个用于填充色彩的像素区域,片元(像素)渲染部分(Fragment Shader)用于在模型的每个面上(经过顶点渲染处理过的面)逐像素填充色彩。

16734189183037.jpg

OpenGLES 2.0及其以上的版本则为可编程渲染管线的版本。目前具体的OpenGLES版有:

  • OpenGLES 2.0
  • OpenGLES 3.0
  • OpenGLES 3.1

着色器 Shader

着色器(Shader)是运行在GPU上的程序。这些程序为图形渲染管线的某个特定部分而运行。从基本意义上来说,着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序,因为它们之间不能相互通信;它们之间唯一的沟通方式只有通过输入和输出。

不同渲染阶段的着色器,有着不同的名字,根据渲染阶段不同常见的着色器主要有顶点着⾊器(VertexShader),片元着⾊器 (FragmentShader)/像素着⾊器(PixelShader),⼏何着⾊器 (GeometryShader),曲⾯细分着⾊器(TessellationShader)等。

片元着⾊器和像素着⾊器只是在OpenGL和DX中的不同叫法⽽已。可惜的是,直到 OpenGLES 3.0,依然只⽀持顶点着⾊器和⽚元着⾊器这两个最基础的着⾊器。

顶点着色器 VertexShader

顶点着⾊器是OpenGL中用于计算顶点属性的程序,用来处理图形每个顶点变换(旋转/平移/投影等)。顶点着⾊器器是逐个顶点进行运算,也就是说每个顶点数据都会执⾏一次顶点着色器,当然这个过程是并行的,并且顶点着⾊器运算过程中无法访问其他顶点的数据。

典型的需要计算的顶点属性主要包括顶点坐标变换、逐顶点光照运算等。顶点坐标由⾃身坐标系转换到归⼀化坐标系的运算,就是在这里发⽣生的。

⽚元着色器 FragmentShader

⽚元着⾊器是OpenGL中⽤用于计算片元(像素)颜色的程序。片元着⾊器是逐个像素运算,也就是说每个像素都会执行一次⽚元着⾊器,当然执行过程也是并行的。

⽚元着色器一般⽤来处理图形中每个像素点颜⾊的计算和填充。

GLSL——OpenGL Shading Language

OpenGL着⾊器语言(OpenGL Shading Language)是⽤来在OpenGL中着⾊器编程的语⾔。

光栅化 Rasterization

光栅化是把顶点数据转换为⽚元的过程,具有将图形转化为一个个栅格组成的图象的作⽤,特点是每个元素对应帧缓冲区中的一个像素。

光栅化其实是一种将⼏何图元变为二维图像的过程,该过程包含了两部分的工作:

  • 决定窗⼝坐标中的哪些整型栅格区域被基本图元占用;
  • 分配⼀个颜色值和一个深度值到各个区域。

纹理 Texture

纹理可以理解为位图图片。在渲染图形时需要在其编码填充图⽚为了使得场景更加逼真,⽽这⾥使⽤的图⽚,就是常说的纹理。

混合 Blending

在测试阶段之后,如果像素依然没有被剔除,那么像素的颜⾊色将会和帧缓 冲区中颜⾊色附着上的颜⾊色进⾏行行混合,混合的算法可以通过OpenGL的函数进行指定。但是OpenGL提供的混合算法是有限的,如果需要更加复杂的混合算法,可以通过像素着⾊器进行实现,当然性能会比原⽣生的混合算法差一些.

渲染流程

OpenGL渲染流程如下图所示:

渲染流程

参考:
《[GLES] 固定管线与可编程管线的差别》
https://www.jianshu.com/p/756006001031

《OpenGL 的固定管线和可编程管线的本质区别以及unity里的区别》
https://blog.csdn.net/kongji1234/article/details/123295092

分类: 音视频开发 标签: OpenGL着色器Shader管线缓冲区

评论

暂无评论数据

暂无评论数据

目录