WebGL学习02-WebGL工作流程初窥

821 阅读3分钟

什么是WebGL

一句话概括,WebGL是提供直接访问GPU绘图能力的一套API。它有以下几个特点

  1. WebGL API是面向过程的设计。举例来说, 如果面向对象编程的语句是obj.someFunc(arg1, arg2),那么面向过程的表示就是someFunc(obj, arg1, arg2)
  2. 所有的数据最终都会通过WebGL API传递给GPU,每次更新数据,都需要使用API再次传递给GPU
  3. 所有绘图操作都在GPU上执行,我们通过WebGL的API只是告知GPU绘图指令和相关数据

其实WebGL的难点并不在于API的使用,而在于对GPU绘图流程的理解。

WebGL绘图流程

接下来我们来看一下WebGL绘图需要哪些步骤,你不需要完全理解其中的含义,因为会包含很多术语。后面我会将这些术语对应到第一节的步骤中,给出一个比较具象的参考。

配合第一节四面体的例子,我们来对每一步一一解释。

Vertex Data

我们先来看第一步,Vertex Data就是四面体的四个顶点位置数据,通过WebGL的相关API,将顶点数据告知GPU。

Vertex Shader

Shader是WebGL中很重要的概念,一句话概括,Shader就是跑在GPU上的程序,并且GPU可以同时并发执行很多这样的程序。Vertex Shader就是专门处理顶点数据的Shader,每个顶点都会经过它处理一次,我们对四面体顶点的透视变换操作就可以在这里进行,最终输出处理后的顶点数据。由于Shader是可以同时跑多个的,所以GPU能够以极高的效率处理很多的顶点。

Primitive Assembly

这一步把顶点组装成多边形,WebGL支持的多边形最大顶点数只有三个,也就是三角形。四面体一共四个三角面,所以在这一步会被组装成四个三角形。如果你是渲染一个正方体,那么你就需要把一个矩形面拆成2个三角面了。

Rasterization

这一步系统计算出四面体的四个三角形在屏幕上覆盖的像素,每个像素对应屏幕上的一个二维坐标。可能多个面之间会互相重叠,不过这一步并不关心这些,它会把每个三角面所覆盖的像素全部枚举出来,这些像素的位置是可以重复的。这一步对应之前说的分割最小上色点的操作。

Fragment Shader

和Vertex Shader一样,它也是在跑在GPU上的程序,它专门处理上一步产生的像素,每个像素都会经过一次Fragment Shader的处理。处理像素主要就是设置像素的颜色,我们可以向Fragment Shader传入信息,来决定这个像素应该是什么颜色。我们在游戏中常见到的光照,阴影主要都是在这一步进行实现的。

Per-Fragment Operations

这一步对Fragment Shader输出的像素进行再次处理,比如剔除掉不会显示的像素,以四面体为例,隐藏在后面的三角面所覆盖的像素将被丢弃。除此之外,如果你设置的像素是半透明的,则需要在这一步进行透明混合。这一步和上一步则对应之前说的给最小上色点上色的操作。

Present

最终系统将输出的像素信息绘图到屏幕或者其他输出目标上,从而完成一次绘图。

总结

这一小节主要介绍了WebGL绘图的主要流程,或者也可说这是GPU绘图的主要流程,相对于2D的绘图,引入了很多新的概念,比如Vertex Shader,Fragment Shader。读者可以尝试去思考每个步骤在绘图流程中的意义,然后带着你的疑问,在后面的章节中寻找答案。