【实验笔记】Unity游戏Shader提取(上) | 您所在的位置:网站首页 › unity打包游戏源码可以反编译吗 › 【实验笔记】Unity游戏Shader提取(上) |
前言:本打算解析一下镜头脚本,不过转念一想要不先把场景给提取了,然后就跑去学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 实验室设备网 版权所有 |