大家好,我是程序员牛肉。
就在2024年8月20日,备受期待的国产3A单机游戏《黑神话悟空》终于上线,一上线就打破了国产游戏的各种记录。
关于黑神话悟空的相关话题立马霸占了微博热搜。
在互联网上,大家都戏称:还没开始打游戏,这八十一难就已经开始了。第一难就是解压,有的人解压十几分钟,有的人解压两三个小时。
而第二难就是着色器编译,有多少人卡在着色器编译在这块了?举手让我看看。
不过话说回来:到底什么是着色器呢?到底什么是着色器编译呢?让我尝试在少用专业名词的情况下给你讲清楚。
计算机对图像的处理主要是在GPU中完成的。在早期的GPU中,图形渲染被分为几个预定义的阶段,每个阶段执行特定的操作,而这些操作是不可编程的,即开发者不能修改或替换这些阶段的具体实现。
当时的GPU会给你一些预设,我们只能通过不断的选择各种预设来达到我们想要的效果。
在当时,实现不同效果就好像在电路中打开不同的开关。
而这种固定管线的灵活度实在是太差了。因此在之后,人们就逐渐开始尝试可编程管线。
我们可以手动的编写代码放到GPU中进行执行。这样很多的效果就从可配置变成了可编程。最通常的应用就是自行实现光照和材质。
而这种放到GPU中跑的,用来自行实现一些效果的代码,英文名叫做shader,中文名叫做着色器。
这个着色器的翻译也有点难懂。让我们从英文出发尝试去理解。 shader->shade,说白了就是光影/明暗关系。这东西是可编程渲染管线用来定义一批渲染的处理方法的,即一组数据应该如何处理。包含了一堆缓存数据和一系列状态。
编写着色器也有他自己的语言,目前比较主流的有HLSL和GLSL。这种语言和C语言比较相似。
让我们尝试编写一个自己的着色器。它不执行复杂的操作,只是将每个像素的颜色设置为紫色
而这种高级语言,GPU是直接看不懂的。所以所谓的编译着色器就是把人写的着色器代码编译成为GPU能够看懂的机器码。
让我用再简单一些的描述来告诉你编译着色器是在干什么。
你可以粗暴的理解为正在加载各种滤镜,比如比如逆光下皮肤绒毛的散射,比如楚楚动人的水润眼瞳。
当然这些滤镜都是可以重复使用的,但各种不同的硬件甚至不同的版本的硬件能执行的代码是有差异的,于是开发者用通用语言来定义滤镜,由最终执行的设备使用翻译器先自行翻译成对应的代码再执行。
而在一些早期游戏中,为什么没有这种游戏刚打开就出现的编译器着色环节呢?
正所谓人看到什么,是程序员决定的。不告诉你我在编译着色器不等于我没有编译着色器。(不等式直接秒了)
自从硬件出现可编程管线和高级着色器语言以来,shader就要编译执行,除非你能直接写机器码。
而之所以在很长的一段时间内,没有提前编译着色器;是因为当时的花活并不多,shader程序的编译速度很快,根本就没有必要提前编译。大多数都是获取游戏材质的时候就顺手编译了。
而后续也出现了很多关于着色器编译方面的优化,比如shader cache,这种技术的出现也大大的规避了着色器编译的感知。
但现代游戏的材质复杂程度不是以前能够比的,一个复杂的材质或许会有n多变种,不同变种需要的具体shader程序或有不同,每台机器上,变种的执行情况也会有区别。这就导致,一股脑预编译其实实现起来复杂又高成本,所以一般游戏都是偷懒搞个大概的,缺的部分再到对应机器上去编译。
在这里不得不提一嘴某一个A打头的游戏,每一次进入游戏都要重新编译着色器。
写到最后,贴一下我在查找着色器相关资料的时候读的一本相关领域的书。
https://thebookofshaders.com/?lan=ch
在这本书中,作者还提供了一个在线网站,可以在线运行我们的着色器代码。
https://editor.thebookofshaders.com/
我本人并不是计算机图形学方面的从业者,因此在介绍这方面的知识的时候,肯定从专业度和深度来讲是不如从业者的,如果在我的文章中出现了错误,还请直接指出,欢迎大家一起讨论。
通过我的介绍,相信大家已经了解了什么是着色器以及为什么要编译着色器。
你对于黑神话悟空这款游戏有什么想说的?你觉得对局BOSS的强度怎么样?欢迎在评论区留言。