9.1 渲染与着色器

“渲染”(Rendering)是即使非计算机专业的都不会觉得陌生的词,虽然在很多人说这个词的时候,并不清楚“渲染”究竟意味着什么。相反,“着色器”(Shader)很可能是大家比较陌生的词,从名字看上去似乎是用来上色的,但它具体能做什么呢?

在解释着色器之前,我们先来聊聊渲染。

渲染


用通俗的话来说,渲染就是将模型数据在屏幕上显示出来的过程。

这听起来好像很简单呢!但正如你打开一个Word写文档一样,之所以这个过程看起来毫不费力是因为那些繁杂而枯燥的活都让计算机完成了。同样,要渲染出一幅画面GPU也需要做很多工作,如果你有兴趣了解的话,可以查阅渲染流水线(Rendering Pineline)的相关知识。

Three.js最重要的一个好处就是让你在无需知道图形学知识的前提下完成从建模到渲染的一整套工作。因而,在本书中我们不会对图形学知识做展开,否则就是违背了这一本意了。在这里,我们只要理解渲染做的将你的模型数据呈现在屏幕上的过程即可。

着色器


在定义了场景中的物体、照相机、光源等等之后,渲染的结果就确定了吗?

在可编程GPU时代到来前,答案是肯定的,但现在我们已经可以通过着色器程序对GPU编程来控制渲染的结果。着色器是屏幕上呈现画面之前的最后一步,用它可以对先前渲染的结果做修改,包括对颜色、位置等等信息的修改,甚至可以对先前渲染的结果做后处理,实现高级的渲染效果。

如果这听上去很抽象,那让我们来看一些具体的例子吧!

比如,我们要渲染一个宇航员,使用同样的模型、同样的光源、同样的照相机,但是不同的着色器,我们就能得到不同的渲染效果:

图片来源

左图的是塑料效果,右图的是卡通效果,这都是由不同的着色器实现的。

我们知道WebGL是基于OpenGL的,而OpenGL用GLSL(OpenGL Shading Language)这一着色器语言完成着色器工作,因此,WebGL的着色器程序大致与GLSL相同,是一种接近C语言的代码。着色器通常分为几何着色器(Geometry Shader)、顶点着色器(Vertex Shader)、片元着色器(Fragment Shader)等等。由于WebGL基于OpenGL ES 2.0,因此WebGL支持的着色器只有顶点着色器与片元着色器。

顶点着色器

顶点着色器中的“顶点”指的正是Mesh中的顶点,对于每个顶点调用一次。因此,如果场景中有一个正方体,那么对八个顶点将各自调用一次顶点着色器,可以修改顶点的位置或者颜色等信息,然后传入片元着色器。

片元着色器

片元是栅格化之后,在形成像素之前的数据。片元着色器是每个片元会调用一次的程序,因此,片元着色器特别适合用来做图像后处理。

Three.js与着色器


由此,我们看到,着色器可以用来渲染高级的效果。但是对于很多应用而言,并不需要着色器。

WebGL强制需要程序员定义着色器,即使你只是希望采用默认的渲染方法。这似乎有些不近人情,尤其对于对图形学理解不多的开发者而言。

幸运的是,Three.js允许你不定义着色器(就像前面所有章节的例子)采用默认的方法渲染,而仅在你有需要时,才使用自定义的着色器,这大大减少了程序员的工作量,而且对于初学者而言,无疑是减少入门难度的福音。