如何理解 OpenGL 中着色器、渲染管线、光栅化等概念?
在 OpenGL 中,设置好顶点数据,设置好着色器,调用 drawcall 函数,3D 图形就被绘制出来了。
那么在这背后,GPU 做了什么工作呢?其实,从输入的顶点 3D 信息,到输出每个像素点的颜色信息,中间经过了很多步操作。这些操作按照一定的顺序构成了一条图形流水线(Graphics Pipeline),或者叫渲染管线。
每个步骤的输入都依赖于前一步骤输出的结果。其中的步骤包括顶点处理(vertex processing)、图元装配(triangle assembly)、光栅化(rasterization)、片段处理(fragment processing)、测试和混合(testing and blending)几个关键步骤。
图片来源:https://graphicscompendium.com/intro/01-graphics-pipeline
在 OpenGL 2.0 版本之前,这些步骤都是功能固定的,OpenGL 用户不能对其编程,叫做固定渲染管线(Fixed Function Pipeline)。
从 OpenGL 2.0 版本开始支持可编程的渲染管线,在图形流水线的某些特定的步骤上,OpenGL 用户可以通过自己编写代码,告诉 GPU 做出不同于固定管线的效果。这些不同步骤上的代码有一个共同的名字:着色器(Shader)。
Shader 一词来源于 shading,意思是在图画上增加明暗或颜色。所以 Shader 的意思在图形学上就是计算图像颜色的程序。OpenGL 的 shader 一共包括六种:vertex shader、geometry shader、 tessellation control shader、tessellation evaluation shader、fragment shader、compute shader。
最常用的两个 shader 是 vertex shader 和 fragment shader,分别对应顶点处理阶段和片段处理阶段。其实 Shader 不仅可以用来计算图像的颜色,还可以计算其他数据,比如用于生成新几何数据的 geometry shader,用于曲面细分的 tessellation shader 和用于通用计算的 compute shader。
光栅化(Rasterization),又叫栅格化。类比于西方绘画中的一种技法,画家通过一个网格观察景物,把每个网格中人眼能够看到的影像记录在画像上。这里看到的景物是带有透视效果和前后遮挡关系的。
图片来源:http://www.brian-curtis.com/dfo\_second\_edition\_white/powerslide2.html
在图形学上,这个网格变得非常细密,即一个格子只包括一个像素。光栅化就像画家一样,确定每个 3D 图元在 2D 画面上占据了哪些像素位置。在这一阶段,同一 2D 位置上可能对应了多个 3D 图元的子区域,每个子区域叫做一个片段。
例如下图中,每个格子是一个像素,蓝色圆点是像素的中心。黑色三角形通过像素网格观察,可以看到它占据了绿色那些区域。每个绿色的格子就是这个三角形的一个片段。
图片来源:https://www.scratchapixel.com/lessons/3d-basic-rendering/rasterization-practical-implementation/rasterization-stage
参考资料:
https://www.khronos.org/opengl/wiki/Shader
作者:旷视科技
链接:https://www.zhihu.com/question/29163054/answer/2298413553
-- END --
进技术交流群,扫码添加我的微信:Byte-Flow
获取相关资料和源码
推荐:
全网最全的 Android 音视频和 OpenGL ES 干货,都在这了