【实验笔记】Unity游戏Shader提取(上) 您所在的位置:网站首页 unity打包游戏源码可以反编译吗 【实验笔记】Unity游戏Shader提取(上)

【实验笔记】Unity游戏Shader提取(上)

2024-06-16 20:05| 来源: 网络整理| 查看: 265

前言:本打算解析一下镜头脚本,不过转念一想要不先把场景给提取了,然后就跑去学Unity渲染了XD

第一节:什么是Shader

一句话总结:Shader(着色器)是控制模型如何在游戏中被渲染的脚本

比如说模型的点在游戏空间坐标的位置,或者某个像素的颜色什么,都是由这个脚本定义的。

具体原理涉及到图形学方面的知识,如果想了解推荐这个视频:

如果打算在Unity了解基本使用快速入门的话,推荐这个视频(我就是这学的):

当然这边也没怎么认真学就是...重点在于——我想知道怎么用别人写好的Shader,所以逆向,开始。

第二节:Shader文件在哪里

还是以我比较熟悉的赛马娘为例,把相关资源整理好后(如何整理见下述专栏)

就可以在整理好后的目录下发现一个名为shader的文件

这里面就包括了赛马娘用到的所有shader了,将其拖入二进制文本查看器

重要的信息有两个,一是UnityFS的文件头,说明这个文件是AssetBundle(AB包)的数据储存格式可被Unity读取,二是第二行的2020.3.24f1,定义了这个AssetBundle所用的Unity的版本号。

所以结论就是——这大概是个正常的AB包,我们可以用工具来解析它。

那么既然这个Shader本身就是给Unity引擎用的,我们就先试试在Unity进行提取。

第三节:用Unity查看AB包

Unity提供了个方便的小插件:

https://github.com/Unity-Technologies/AssetBundles-Browser

通过这个插件,我们可以在对应AB包版本的Unity上对AB包进行查看

我们先在版本为2020.3.24的Unity上新建一个项目

打开解压好之后的插件,将里面的Editor文件夹拖进来

然后我们就可以在上方的Window->AssetBundle Browser处打开插件

点击Inspect面板,选择好我们打算读取的AB包,就可以知道这个AB包内包含什么了。

我们以选择shader这个文件为例

其中包含了什么文件一目了然,而且不止如此,我们可以通过这个工具来查看AB包之间的依赖关系,也就是——这个AB包的物品其所依赖的资源被储存在了哪些别的AB包上。

我们可以拿一个模型的AB包来看看

其中的Missing Object就储存在其依赖的AB包下,当我们把其依赖的AB包都导入进来后,这个AB包就可以自动匹配到对应的Object(物品)。

那么,AssetBundle的查看就是这样,该如何在Unity使用这些资源呢?

第四节:用Unity加载AB包

Unity为AssetBundle的相关操作提供了一系列函数

通过这些函数,我们就可以将AssetBundle里(几乎所有)的资源在Unity上用起来。

由于具体过程涉及脚本编程所以我不太好描述,如果想了解的话推荐这个视频:

那么目前我们已经完全掌握了Unity加载AB包的方法(迫真),我们把shader导进来看看效果。

第五节:相关资源导入

shader必须要应用在模型上才能产生效果,再加上AB包内的模型一般已经绑定好了对应的材质(同时也匹配上了对应的shader),所以我们需要做的是从AB包里导入一个模型预设,所有的一切都会自动帮你安排好。

我们以重炮的头部模型为例,写好加载AB包的相关代码(记得把所有依赖的包都加上)

仅作参考

然后尝试在Unity中运行这个代码(新建一个空对象然后把脚本拖过去)

大功告成,模型以及其相关的贴图材质shader都已经加载好了。

第六节:所以为啥模型是黑的?

让我们查看模型的具体参数来找原因,以头发部分的模型为例,选择

在右方检视栏内我们可以看到各种参数,其中可以发现shader部分已经把需要的材质都分配好了,而且有一大堆可以调节的参数,我们可以试着胡乱调节一下...

当然就结果来说,这里的参数不管怎么调,模型始终还是会以黑色显示...

在把所有的可能原因都排查一遍之后,我发现这是和shader的全局变量有关。

第七节:Shader全局变量

我们知道shader的作用是——接收设定好了的基本信息,进行计算后,得出渲染后的信息。

但就像我们在前几节所见,每个shader中都有一大堆参数需要调整,这就需要对每个shader进行分别的设置。这也就意味着如果我有一个所有shader都需要的参数(比如说阴影的颜色),要修改的话就要在每个shader下分别进行修改,这是一件非常麻烦的事情。

所以Shader全局变量的作用就在于此——只要在游戏里设定好了全局变量,每个shader用到时直接从全局变量上读取就好,而且只需修改全局变量就能达成统一修改参数的效果。

如果说一个shader需要全局变量,但全局变量并没有被定义,那么这个变量就会默认为0。

现在就可以解释为什么模型时黑色的了,由于某些原因,这个shader需要几个全局变量的参与,但由于找不到全局变量,所以所有全局变量就默认为0,然后对于RGB颜色来说,(0, 0,0)代表着黑色,这也就是模型黑了的原因(当然这并不能完全解释)。

第八节:如何知道Shader需要哪些全局变量

Unity提供了一个帧分析工具(Frame Debugger),用于查看场景中的渲染情况,其中就包括了shader的很多相关信息。

我们可以通过Windows->Analysis->Frame Debugger来使用这个工具

点击左上角的Enable开始分析,经过一番探索后找到我们打算分析的shader

只要经过对比我们就可以发现里面包括了全局变量在内的该shader所有需要的参数的情况

比如说_Global打头的这些,值为0,就是这个shader需要但并没有被定义的全局变量。

所以说只要给这些全局变量设定个值就好,但是该设定为什么值呢?

第九节:游戏的全局变量在哪定义的

事实是,我并没有找到...

估计是根据代码来设定的,不过我翻了翻IDA也并每有发现太多设定shader全局变量的代码。

当然,我们也不是没有获取这些变量的方法。

有个叫做Intel GPA(Graphics-Performance-Analyzers)的图像分析程序可以对游戏进行截帧分析(类似于Frame Debugger,不过是作用在应用程序上),并获取其中传入传出shader的数据。

不过这边就涉及到太多东西了所以估计得放到下篇再说(而且我现在还没弄明白)

当然既然全局变量也只是些参数,我们可以自己设定调整看看效果就好。

第十节:Unity定义Shader全局变量

Unity提供了设定shader全局变量相关的函数

通过这些函数和已知的全局变量信息,我们可以写个脚本来即使调整这些全局变量

这里只修改了比较关键的几个全局变量,可能其他的也能起到什么的作用

然后将这个脚本放入Editor文件夹内,我们就可以从脚本定义好的Global->Value Set处打开设置界面。

让我们调节这些全局变量看看效果

再调一下光照的方向,以及全局变量中阴影的颜色

可以看出效果还...可以?另外眼球高光方面好像也要用到些全局变量才能调出来。

总之拿多调调多试试,大概就可以还原出游戏里的效果了。

小结

本篇主要介绍了如何通过Unity对AssetBundle中的Shader进行读取使用与调试(其实通过这步基本就可以直接使用了),关于Shader的提取以及二进制反编译将会在中篇进行介绍,最后下篇的话,大概会介绍一下Shader从汇编代码还原到Unity能直接看懂的源代码的基本思路。

不过就我目前这程度,能不能看懂shader源码都是个问题更别说解析汇编代码了...

所以下篇大概率会鸽了(不管怎样学shader去了,逃ε=( o`ω′)ノ



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有