OpenGL中那些晦涩难懂的名词、动词
对于初次接触图形处理学,第一个难关就是要面对大量晦涩难懂的概念,而这些概念也是学习OpenGl的第一道门槛,毕竟这是歪果仁提出的概念,及时翻译过后也会有一些不好理解的地方。本文中我将重点解释一些我自己的理解,如有偏差可以再下方交流指正。
-
GPU
说起图形处理,一定是离不开GPU的,因为我们所做的操作,最终都会由GPU负责展示到监视器上。而这个过程中就离不开计算,计算每一个像素点的颜色信息。所以GPU是计算图像数据的单元。
说起计算,在我的理解里CPU就是专门用于做二进制运算的计算单元、控制单元,可以处理复杂的逻辑和依赖,那为什么还需要GPU呢?
- 现在的显示内容越来越复杂(多边形、3d、光影、甚至是动态的图像内容),仅仅靠CPU及做图像数据的计算,还要做其他工作,设备使用起来就会非常卡顿。
- 基于GPU的特性(图形运算单元):擅长通过并行的方式来进行数学计算,让我想起了为什么要使用GPU来进行比特币的“挖矿”操作了。
所以将逻辑计算交给CPU,将图像运算交给GPU。合理分工,最大程度的提高计算机的性能。 -
通过硬件的角度分析一下两者的不同:CPU中有计算单元、也有控制单元,必然导致并发执行能力会比较弱,抛开多核来讲,cpu的并发其实是通过时间片切换来实现的,并不是真正意义上的并发但是CPU。而GPU中有大量的计算单元,可以真正意义的并发进行数学计算,但是并不擅长处理逻辑和依赖。
-
OpenGL
- 首先要知道的是OpenGL是一种跨平台、跨语言的API规范,也可以简单的理解为一套协议(没有看到网上有这种解读,不知道对不对)。其中规定了可以操作哪些图像、图形API。开发者就可以通过这套API规范在各种平台上操作GPU来实现一些功能。更加严谨的说是GPU必须提前满足OpenGL规范才可以。
- OpenGL本身是规范,但是想要在具体的平台、语言下使用还是需要有对应的API实现的。所以说我们用是OpenGL的实现。
-
OpenGL ES
它是OpenGL的三维图形子子集,主要是为了满足:iphone、ipad等便携式设备的特性。作为子集一定是抛弃了很多无需且低效的API,来满足便携式设备的特点。
-
Metal
是苹果自己开发的一套用来替换OpenGL ES
的API,目的都是为了让GPU来做事情。毕竟是用别人的规范会有很多限制,苹果大大也不会甘愿受制于人。而且在OpenGL ES的基础上做了很多优化,使得3D渲染能力提升了10倍,并且与2018年开始全面使用。
-
状态机
状态机就是保存对象在整个生命周期中的各种状态、所需参数,同样也可以通过状态机来进行状态、参数的修改。
举例
状态机就像是一台微波炉,它有时间、温度、模式等各种参数,当然它也掌握着内部食物的加热、熟没熟等情况。你可以通过微波炉来调解你需要的加热方式、时间,你也可以通过微波炉的面板来知晓选择了哪种加热方式、时间,等食物加热完成后会有提示音来告诉你当前食物已经加热完成。
当然如果你加热完成后没有将各种参数重置,下次加热依旧会使用之前的各种参数。如果你开启后没有关闭,微波炉也会一直处于工作状态。
类比状态机也是一样需要你在开始工作之前,进行各种参数的设定,在任务完成后需要手动关闭它。
-
OpenGl上下文
- 通过资料知道OpenGl上下文是一个巨大的状态机,其中保存着各种OpenGl工作所需的各种参数以及状态。
- 你所写的当前程序是一个窗口,一个窗口对应一个上下文,而最终都要交付给GPU去处理。
- 根据图可以看出上下文可以共享GPU的缓存等资源
graph TD
c(客户端1) --> b(OpenGL上下文1)
e(客户端2) --> d(OpenGL上下文2)
g(客户端3) -->f(OpenGL上下文3)
b --> a[GPU]
d --> a[GPU]
f --> a[GPU]
-
渲染
将可以用于展示的图片、视频、可视化控件,绘制到屏幕上的过程,其中还包含了图片的编码、解码工作。这一系列过程叫做渲染,我理解应该是一个动词。
-
图元
首先需要明确一个概念图元
,在OpenGl中图元包含:点、线、三角形。也就是说我们看到的任何图形都是由这三个基本元素组成的。
-
顶点数组、顶点缓存区
- 我们看到的图形都是通过三种图元组合完成的,而所有图元的顶点之和就是
顶点数据
。 - 将顶点数据保存到内存中,就称为
顶点数组
。 - 将顶点数据保存到GPU的显存中,就称为
顶点缓存区
-
管线
从图片到显示在屏幕上需要一个过程。管线就是规定了整个过程的每一步,并且需要严格遵守。最贴切的比喻就是工厂里的流水线
,很好理解。
这就是OpenGL中一个完成的管线流程。
在最后一步测试与混合
中,实际进行了以下几步的操作。
固定管线
在OpenGL的早期,提供了很多API来帮助开发者快速完成渲染流程。开发者只需要根据API传入对应的参数即可,其实就是在使用一些已经创建好的shader(着色器)
,但是由于应用场景太过单一,适用范围非常有限。
可编程管线
- 通过发现固定管线的问题,继而推出了可编程管线,可以在某些位置进行一些自定义编程操作。
- 其实放开自定义功能的只有管线中的顶点着色器、片元(片段)着色器。相信以后会开放更多。
-
着色器shader
在管线的解释中已经遇到过shader(着色器)
这个概念,每种着色器对应着不同功能模块。
- 顶点着色器:负责对顶点数据进行加工,将顶点信息放入屏幕中
- 图元装配:将所有顶点进行连线
- 几何着色器:将已有图形按照图元分解
- 光栅化:找出所有相关的像素点,把颜色附着上去
- 片元着色器:对每一个像素点进项颜色处理
固定着色器
和固定管线类似,都是提供编程好的API供开发者调用
自定义着色器
就是可以供开发者可以使用GLSL
自定义一些着色器,其实也只有:顶点着色器、片元着色器
顶点着色器
可以自定义开发的着色器,可以将顶点信息进行编程。提现在图像的:位置移动、缩放、旋转、2D <-> 3D之间的坐标转换。
片元着色器
可以自定义开发的着色器,可以对每一个像素点进行编程,比如说图片的锐化度、亮度、饱和度调整等。
-
GLSL(OpenGL Shading Language)
- GLSL其使用C语言作为基础高阶着色语言,避免了使用汇编语言或硬件规格语言的复杂性。
- 使用GLSL对顶点着色器、片元着色器进行自定义编程的编程语言
-
光栅化
就是将几何图形转化为二维图像(位图),包含两个步骤:
1.确定哪些像素点被使用, 将几何图元信息转化为像素信息,最终获得位图。
-
分配一个颜⾊值和⼀个深度值到每个区域(片元着色器)。
所有的格子就是光栅化第一步确定的,然后会分配一个颜色到栅格区。
所有的格子就是光栅化第一步确定的,然后会分配一个颜色到栅格区。
-
纹理(Texture)
纹理可以理解为图⽚。 在渲染图形时需要在顶点围成的区域中填充图⽚,使得场景更加逼真。⽽这⾥使⽤的图⽚,就是常说的纹理。只是在OpenGL,我们更加习惯叫纹理,⽽不是图⽚。
-
混合
根据字面意思理解就是将多种颜色合成一种,而这个合成后的颜色是需要进行计算的。OpenGL中已经提供了一些固定的混合算法,但是平时开发中也会使用自定义片元着色器来完成,但是效率会比固定混合算法差一些。
-
变换矩阵
在OpenGL中想要图形发生平移、缩放、旋转就需要变换矩阵进行计算。
-
投影矩阵
- 在OpenGL中想要3D坐标转换为2D坐标,就需要投影矩阵进行计算。
- 而结果是由
观察者(camera)
的位置、以及图像位置
本身两者共同决定的。所以想要移动一个图像位置,既可以移动观察者、也可以移动图像本身。
-
显示流程
由CPU进行逻辑计算处理->将数据传递给GPU->通过计算单元并行计算后->存入帧缓存区(显存)->由视频控制器将计算好的位图信息读取出来->数模转换(数字信号转为电子信号)->显示器显示