【Milk】Shader 不再是玄学/浅谈着色器语言

2,061 阅读4分钟
原文链接: mp.weixin.qq.com

查看图片


shader(着色器)语言简言之是一段可编辑程序,负责将输入的图像按指定的命令转化成屏幕上每个像素的具体渲染方式。虽然同样的工程不用shader也可以达成,但是用shader可以利用GPU高速渲染的特性。


计算机图形学里使用的GPU Shader有基于OpenGL的GLSL(OpenGL Shading Language for embeded systems),有基于DirectX的HLSL(High Level Shading Language)。OpenGL提供了可编辑的渲染管线,灵活度非常高,同时也难以掌握。目前的一些图像编程开发框架例如Processing,OpenFrameworks 和three.js都是在使用GLSL语言。


可编译的shader有两种,分别是vertex shaderfragment shader。vertex shader主要输出顶点的几何关系等的运算,fragment shader主要输出片源颜色等的计算。shader其中的变量可以归纳为三类:attributes, uniformsvaryingattributes只能被vertext shader读取,可以包括一些来自position,normal和uv的属性;uniforms可以同时被vertex shader和fragment shader 读取,可以传递lights,camera和materials的一些属性。类型声明为varying的属性只能用于在vertex shader和fragment shader之间传输。下面是他们的关系示意图:

查看图片

查看图片


无意间发现一篇一位chrome开发者写的关于shader很好的例子(原文地址 https://aerotwist.com/tutorials/an-introduction-to-shaders-part-1/),亲测好用,简译了一下分享给大家。虽然是three.js框架下,但在p5, OF框架下的运用大同小异(参见 http://thebookofshaders.com/04/),皆可作参考。




“hello world”


先讲最简单的例子,在vertex shader中,输入以下代码,其作用是将物体在3D空间里的坐标转换为最终呈现在画布上2D视野中的位置。最终返回gl_Position值。

查看图片

在fragment shader中,设定其颜色,为一个四分量浮点向量,有四个变量分别是rbga。(注:在shader语言中经常出现浮点向量vec,vec后面的数字是代表其维度)

查看图片

然后将这两者赋予一个新的ShaderMaterial,成为Mesh的材质( Mesh可以是任何输入的图形)。

查看图片

渲染结果就是个青红色的图形,并不是很fancy ,不过不要急,这只是一个最基础的例子- -



“模拟光线”


接下来我们试着在shader里面给图形打上光线。这一操作虽然在shader外部也可以进行,例如在three.js中添加一个新的光源,但我们这次想用着色器来实现。这里我们只要把上一个hello world 的例子稍作修改。


在vertex shader中,加入一个varying变量(varying变量用来在vertex shader和fragment shader之间传输信息),赋予其一个vec3的normal值。

查看图片

在fragment shader中,创建一个右上方打来的灯光,dot(x,y)是用来进行一个乘法,是计算一个物体的位置坐标和灯光坐标的相似度,模拟一个阳面亮,阴面暗的效果。

查看图片
渲染效果如下:

查看图片




attribute变量控制


试着加入一个attribute变量,命名为displacement。

查看图片

同时在three.js的脚本中添加attribute。设定displacement的类型为浮点,并且为一个数列。

查看图片
查看图片

同时获取three.js里设置的图像的顶点数量,random相应长度的数值,返回到vertex shader中,叠加在原有顶点上,在着色器中生成新的噪音化后的顶点位置信息。

查看图片
渲染效果如下:

查看图片




uniform变量控制


按照上面类似的步骤,在vertex shader中加入uniform变量,控制变形的幅度。

查看图片
three.js的代码中同时也添加uniform。

查看图片
查看图片

然后可以在更新的部分,加入一些根据时间而改变的动态效果。

查看图片
生成效果:

查看图片




后记


尝试了某一种可能的输出,绑定了Yoshihiro Hanno的一段噪音,分分钟玩坏一粒希腊石膏头- -

查看图片

关于shader,可以说的还有很多,希望这片文章可以给你帮助。如果本文的理解有所疏漏,有失偏颇,望请指正。有兴趣深入了解着色器语言GLSL的朋友可以继续读the book of shader,目前有中文翻译(http://thebookofshaders.com/)。





查看图片