Shader,也就是着色器,对于我们大部分人来讲,可以说是一个既熟悉又陌生的小伙伴。

经常玩游戏的小伙伴应该熟悉,《着色器编译中》,经常很费时间。

让我们来看看着色器shader会在哪些地方用到吧:

目前市面上大部分的3D游戏,里面的一些视觉效果都用到了Shader:

上图是游戏《原神》中一个波光粼粼的水面效果,除了水体的光泽、扰动外,还有物理光学的折射现象,它们都是由Shader渲染出来的。

除了3D游戏外,Shader在图像处理领域也有一定的应用。


上图是一款名叫 PhotoMosh 的图像处理应用,里面内置了非常多的图像效果,比如上图用的Wobble效果可以使图片发生扭曲变形,如果你查看了网站的源码,就会发现它背后用的不是Canvas2D,而是Shader来实现的。

图像处理,既可以是处理静态的图片,也可以是处理动态的视频。

上图是一款名叫剪映专业版的视频剪辑软件,同样地也内置了很多视频特效,这些特效背后也是用Shader实现的。


在Web页面上,我们可以看到很多图像,用Shader可以给这些内容注入一种奇妙的“魔法”,例如上图中 taotajima 网站的鼠标悬浮图片特效,体验一下还是挺有意思的。

还有下面这个:

云朵效果

这个也是完完全全用shader制作的。

那么我们来到正式的内容:

shader是什么?

Shader,是运行于GPU显卡里的一段程序。GPU负责整个的图形渲染流程(也被称之为“渲染管线”),而Shader就是用于让我们能够使用编程的手段来控制渲染管线的一部分的工具。

最主要的Shader有两种:顶点着色器Vertex Shader 和片元着色器Fragment Shader。顶点着色器负责确定图形的每一个顶点的位置,片元着色器负责渲染图形的每一个片元(像素)的颜色。

shader和其他技术的关系

对于我现在的职业,前端来说,复习一下知识点吧:
前端常用的图形技术有:csssvgCanvas2D webGL

  • CSS创作的效果基本都是直线式的,上图就是用CSS的animation属性配合transform属性创作的一个轨道运动的动画效果。

  • 而SVG就是拿来创造折线式或曲线式的效果。SVG有一个path标签,它可以定义出任意形状的路径,再配合stroke-dasharray、stroke-dashoffset等属性,我们能很轻松地实现如上图所示的线条运动的动画

  • 但是对于创作欲望强烈的前端开发来说,svg是无法满足的,那么canvas应运而生。它能对画面进行像素级的操控。用Canvas2D配合一些数学运算和随机函数,就可以实现这个效果。

  • 但是canvas2D对3D的效果不是太好,亦或者说是不太适合,那么我们就要搬出来webGL了

WebGL是一种能让我们在浏览器中高效地渲染3D图形的技术,它把图形渲染到屏幕上的方式被称为“渲染管线”,而用编程的方式来控制渲染管线其中的一部分,则正是Shader的职责所在。因此,ShaderWebGL的一个重要的组成部分。

由于原生的WebGL非常难用,我们会更倾向于使用一些封装好的框架,如 three.js,这个框架封装了很多WebGL的API,同时也封装了很多Shader,用它我们就能避免很多冗余的代码,轻松地创建出一个3D场景。

但是因为封装的太多,很多场景的重合率太高了,没有个性。

舍弃了个性和死掉了没什么两样

所以我们这个shader分类专题,就是为了学习如何自定义shader,创造我们自己的东西。

Shader的本质是用各种数学计算来操控屏幕上的像素,这带给了我们极高的自由度:小到写各种创意的图形demo,大到实现3D游戏里的场景特效,对于我们前端来说,则可以实现各种新颖的网页特效。

比如这些网站:

除此之外,shader在GPU显卡的并行计算的帮加持下,渲染像素的效率非常的高。

在很久以前,英伟达发布GTX280的时候,现场通过简单易懂的演示介绍了CPU和GPU的效率对比。

这个视频很形象的介绍了GPU和CPU的差距,再拿我自己的电脑举例:

我的电脑的显示器是这样的:

帧率是120帧,那么我的电脑的GPU需要处理的数据是:

显示器分辨率和刷新率:3024 x 1964,帧率为120Hz。
每帧像素数:3024 x 1964 = 5,938,176 像素。
每秒帧数:120 帧。

每秒像素总数=每帧像素数×每秒帧数

将数据代入公式

5,938,176 像素/帧×120 帧/秒=712,581,120 像素/秒
每秒需要处理的像素总数是 712,581,120 个像素。

假设每个像素平均需要进行 10 次运算(这是一个相对保守的估计,实际运算量可能会更高),那么每秒需要进行的总运算次数为:

712,581,120 像素/秒×10 次/像素=7,125,811,200 次/秒

每秒需要进行的 GPU 运算次数约为 7,125,811,200 次。

这足以说明在GPU并行计算能力的加持下,Shader的渲染效率是非常高的。平时写Shader时,我们可以放心大胆地用各种方式来进行创作,而不用担心GPU会来不及渲染这种问题。

除非你的GPU实在是差劲,支持不了这种需求。这个时候就建议更换显卡啦!

游戏里的降帧也是这些原因,GPU的重要程度不言而喻,高复杂程度的3A大作,当GPU无法在预定时间内完成所有的渲染任务时,就会无法按时生成新的一帧,导致帧率下降。如果在屏幕上显示的内容过于复杂,需要更多的计算资源,GPU可能无法按时完成渲染任务。

最后修改:2024 年 07 月 26 日
收款不要了,给孩子补充点点赞数吧