初学者在初学OpenGL时,很多时候会对OpenGL的渲染架构感到困惑,不清楚它是怎么一个渲染流程,常将Arributes直接传递到片元着色器,或者为了将属性直接传递到片元着色器,而通过uniform传递到片元着色器等,这样的操作都是错误的,OpenGL的数据传输都有明确的届定。下面,我们就来看看OpenGL的渲染架构并了解它的数据传输方式和特点。
- 上面就是OpenGL的渲染架构啦,我们在处理任何图形渲染的时候都是依据它,而基于OpenGL 封装的框架都是也都是遵循这个图的规则。
接下来,我们来解析下这张图,探索图形的渲染架构:
一、Client与Server
这里有两个很重要的端,分别是Client和Server,那它们是不是我们平常开发中具有不同职能能力的客户端和服务端,答案是否定的。
- Client:它与我们平常开发所说的前端iOS或者android开发不一样,它是指CPU上所存储的代码,我们叫客户端。比如,我们会用到OpenGL的代码,C代码,C++代码。
- Server:它调用的是GPU芯片,顶点着色器和片元着色器传递颜色,我们会不断的从客户端把数据传到Server,不断的执行起来。
总的来说,Client就是我们编写的程序,而Server是计算机图形硬件厂商所提供的OpenGL的实现。
如果服务端停止工作等待客户端,或者客户端停止工作来等待服务端做好接受更多的命令和准备,我们把这种情况成为管线停滞。
二、Shader
着色器(Shader)是用来实现图像渲染的,用来替代固定渲染管线的可编辑程序。主要有Vertex Shader(顶点着色器) 和 Fragment Shader(片段着色器)两种。
- 顶点着色器是在GPU上运行的小程序。顾名思义,顶点着色器是用来处理顶点数据的。
- 片段着色器就像顶点着色器一样,片段着色器也是运行在GPU上的小程序。顾名思义,用它来处理片段。如图上,顶点着色器处理完顶点数据后,Primitive Assembly将三个为一组的顶点进行图元装配和光栅化,而片断着色器则负责输出每个三角形像素的最终颜色。
基本上来说,它是这样运行的:片段着色器将顶点着色器输出的片段作为输入,片段的顶点属性已被光栅化单元进行了插值处理。
三、Texture Data,Uniforms,Attributes
要实现图形的渲染,需要向着色传递数据,否则,什么都无法实现。
另外,我们称通道为传递数据的一种方式。
通常来说,Texture Data,Uniforms,Attributes(ins)数据都会传到顶点着色器,但是顶点着色器并不会处理太多关于纹理的计算,纹理数据更多的是片段着色器来处理。下面,我们来细讲下三种数据:
-
Attributes(属性)
1、Attributes常为需要改变的数据,比如:颜色数据,顶点数据,纹理坐标,光照法线;
2、可以直接传递到顶点着色器,间接传递到片元着色器,不能为了将属性直接传递到片元着色器而通过uniform传递到片元着色器;
3、属性值可以是浮点数、整数、布尔数据。 -
Uniforms(统一)
1、Uniforms值是比较统一的,不需要发生太多改变;
2、可以直接传递到顶点着色器和片元着色器;
3、uniforms可以是浮点数、整数、布尔数据。
eg:图形的旋转怎么实现?我们通过 每个顶点 * 变换矩阵。而这个变换矩阵不会发生太多改变,那我们称这个矩阵为uniforms值,所以uniforms也可以是矩阵。
- Texture Data(纹理数据)
在顶点着色器、片段着色器中都可以对纹理数据进行采样和筛选。通常来说,片段着色器对一个纹理值进行采样,然后在一个三角形表面应用渲染纹理数据。然而,纹理数据,不仅仅表现在图形,很多时候,图形文件格式都是以无符号字节(每个颜色通道8位)形式对颜色分量进行存储的。常用的有颜色填充和纹理填充。
eg:什么时候会用到纹理呢?比如滤镜,滤镜实际上是对图片本身做处理的,它是在读取的时候,去改变纹理的颜色值。
- Out
输出数据是作为一个阶段着色器的输出定义的,而后续阶段的着色器则作为输入定义。
1、输出数据可以简单的从一个阶段传递到下一个阶段,也可以用不同的方式插入。客户端的代码接触不到这些内部变量,通常我们的OpenGL开发接触不到。
以上就是OpenGL渲染架构的解析啦。
本文部分内容参考CC老师的简书:https://www.jianshu.com/p/36413e468bfe