OpenGL渲染基础架构
导语:
渲染管线(渲染流水线),一般由显示芯片(GPU)内部处理图形信号的并行处理单元组成。这些并行处理单元两两之间互相独立。不同的型号硬件上独立处理单元的数量有很大差别。与CPU串行执行不同,渲染管线中的各个处理单元并行处理,渲染效率可以得到极大地提升。
-
1、渲染管线
image.png
1.1、渲染管线流程图:
1.1.1、基本处理:
该阶段设定3D空间中物体的顶点坐标、顶点对应颜色、顶点的纹理坐标等属性。并且指定绘制方式:点绘制、线绘制、三角形绘制。
1.1.2、顶点缓冲区
这部分功能在程序中是可选的,但是一般情况下,都要使用,不为别的,主要为了提高GPU的IO带宽和性能优化,使用的情况为输入的顶点数据基本没有变化的情况下,在初始化阶段将这些顶点输入到顶点缓冲区,在绘制每一帧时就可以直接从缓冲区里面拿取并使用,再也不用从cpu的存储器中进行拿取。1.1.3、变换和光照
a、顶点变换任务:对3D物体的各个顶点的平移、缩放和旋转的功能。
b、光照计算任务:根据光照的位置、性质、各通道强度,物质材质,来计算物体的各个顶点的光照情况。1.1.4、图元装配
a、图元组装:顶点数据根据设置的绘制方式被结合在一起。
b、图元处理:通过几个几何着色器进行对物体图形的处理,后续再进行详细介绍。1.1.5、光栅化
主要用于决定哪些像素点最后可以渲染的屏幕上。1.1.6、纹理环境和颜色求和
从纹理图中某个纹理坐标位置获取该位置颜色值
根据纹理采样值和光照计算等结果生成片元的最终颜色。1.1.7、Alpha测试
Alpha除了在颜色混合的时候需要用到意外,还有一个用途就是Alpha测试,Alpha测试的原理:当每个像素即将绘制时,如果启动了Alpha测试,OpenGL会检查像素的Alpha值,只有Alpha值满足条件的像素才会绘制(严格的说,满足条件的像素会通过本项测试,进行下一种测试,只有所以测试都通过,才能进行绘制),不满足条件的泽不进行绘制。这个"条件"可以设置成:始终通过,始终不通过,大于设定值则通过,小于设定值则通过,等于设定值则通过、大于等于、小于等于、不等于则通过。可以通过下面的代码来启用或禁用Alpha测试
glEnable(GL_ALPHA_TEST); // 启用Alpha测试 glDisable(GL_ALPHA_TEST); // 禁用Alpha测试
可以通过下面的代码来设置Alpha测试条件为“大于0.5则通过”
glAlphaFunc(GL_GREATER, 0.5f);
该函数的第二个参数表示设定值,用于进行比较。第一个参数是比较方式,除了GL_LESS(小于则通过)外,还可以选择:
GL_ALWAYS(始终通过),
GL_NEVER(始终不通过),
GL_LESS(小于则通过),
GL_LEQUAL(小于等于则通过),
GL_EQUAL(等于则通过),
GL_GEQUAL(大于等于则通过),
GL_NOTEQUAL(不等于则通过)。1.1.8、裁剪测试
裁剪测试用于限制绘制区域,当开启裁剪测试,只有没有被裁剪的窗口内的像素点会绘制,其他像素不在窗口内的则都不会绘制
可以通过下面的代码来启用或禁用剪裁测试:glEnable(GL_SCISSOR_TEST); // 启用剪裁测试 glDisable(GL_SCISSOR_TEST); // 禁用剪裁测试
可以通过下面的代码来指定一个位置在(x, y),宽度为width,高度为height的剪裁窗口
glScissor(x, y, width, height);
1.1.9、深度测试
深度测试,就是对深度缓冲区内的像素深度值与新值进行比较,来判断是否通过测试,这样在渲染图形的时候,无线考虑图形中图形渲染顺序问题。通过glEnable/glDisable函数可以启用或禁用深度测试
glEnable(GL_DEPTH_TEST); // 启用深度测试 glDisable(GL_DEPTH_TEST); // 禁用深度测试
至于通过测试的条件,同样有八种。条件设置是通过glDepthFunc函数完成的,默认值是GL_LESS。
glDepthFunc(GL_LESS);
除了GL_LESS(小于则通过)外,还可以选择:
GL_NEVER,不通过(输入的深度值不取代参考值)
GL_LESS,如果输入的深度值小于参考值,则通过
GL_EQUAL,如果输入的深度值等于参考值,则通过
GL_LEQUAL,如果输入的深度值小于或等于参考值,则通过
GL_GREATER,如果输入的深度值大于参考值,则通过
GL_NOTE_QUAL,如果输入的深度值不等于参考值,则通过
GL_GEQUAL,如果输入的深度值大于或等于参考值,则通过
GL_ALWAYS,总是通过(输入的深度值取代参考值)
- 2、渲染管线
2.1、着色器:
概念:着色器(Shader)是运行在GPU上的小程序。这些小程序为图形渲染管线的某个特定部分而运行。从基本意义上来说,着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序,因为它们之间不能相互通信;它们之间唯一的沟通只有通过输入和输出。
2.1.1 顶点着色器
其工作过程为首先将原始的顶点几何信息及其他属性传送到顶点着色器中,经过自己开发的顶点着色器处理后产生纹理坐标,颜色,点位置等后续流程需要的各项顶点属性信息,然后将其传递给图元装配阶段。
image.png
顶点着色器的输入包括:
着色器程序——描述顶点上执行操作的顶点着色器程序源代码或者可执行文件。
属性变量(attribute)——用顶点数组提供的每个顶点的数据。
统一变量(uniform)——顶点着色器使用的不变数据。
采样器——代表顶点着色器使用纹理的特殊统一变量类型。
顶点着色器的输出包括:
内建输出变量——例如gl_Position,经过变换矩阵变换后的顶点最终位置。
易变变量(varying)——从顶点着色器计算产生并传递给片元着色器的数据变量。
2.1.2 片元着色器
片元着色器是用于处理片元值及其相关数据的可编程单元,其可以执行纹理的采样,颜色的汇总,计算雾颜色等操作,每片元执行一次。片元着色器主要功能为通过重复执行(每片元一次),将3D物体中的图元光栅化后产生的每个片元的颜色等属性计算出来送入后继阶段。
image.png
片元着色器的输入包括:
易变变量(varying)—从顶点着色器传递到片元着色器的易变变量数据。
片元着色器的输出包括:
gl_FragColor ——计算后的片元颜色,一般在片元着色器的最后都会对gl_FragColor 进行赋值。