欢迎参与讨论,转载请注明出处。
前言
Demo也到了做渲染的时候了,经过一番鏖战后,算是大体完成了。但随着后续需求的到来,发现这套纯代码的Shader方案对于扩展、复用等方面有着诸多不便。于是便打起了Shader Graph的主意……经过一番纠缠,于是有了本篇踩坑实录。另附源码地址,但本篇并不会对其做讲解。基于Unity2020.1.0a20,渲染管线为URP7.18。
优劣
首先要明确的是:Shader Graph不支持Builtin渲染管线,且尚未处于彻底成熟的阶段,哪怕是最新版本尚有不少缺陷。但瑕不掩瑜,且说其优劣:
- 优点
- 由于节点化与Sub Graph的存在,Shader的组装将变得相当容易,极大提升了模块化水平。
- 调整Property与Keyword变得相当方便,纯代码下将需要多些工序。
- 内置各种节点,降低了美术参与创作的门槛。
- 能够实时预览每个节点造成的变化预览,虽然对我而言没啥用。
- 缺点
- 编辑器尚不够稳定,经常会出现整个程序崩溃的情况。
- 生成的代码不够优化,比较暴力,存在各种分支判断、重复函数(也许最终会优化?)
- 由于Slot机制的原因,可能会出现很多运算集中在片元着色器中。
- 对于创建Pass并不友好,需要修改源码。
来龙
其实一般的浅度Shader Graph使用者并不会如我这般踩这么多坑:直接使用内置的Graph模板进行创作即可。不幸的是,如前文所言:对于创建Pass并不友好,需要修改源码。于是便开始了踩坑之旅……
在默认情况下,Unity的Package将保存在工程的Library/PackageCache目录下,这样子是不能直接修改源码的(Library目录下的东西属于可再生物,随时会被覆盖),需将之搬迁至工程的Packages目录下。
对于考虑到日后Shader Graph的版本升级情况,所以尽可能的不要修改原工程的内容,而是尽量新建文件。但考虑到Shader Graph源码下存在不少inner元素,直接在外面写自己的内容也并非彻底可行。只能直接在Shader Graph包下进行添加文件的方式了,这也是要将之移至Packages目录的原因。
我要做的事情相当明确:新建一个自定义的Graph类型。在URP下已经自带Unlit与PBR两种类型了,于是本人便基于Unlit Graph并结合先前实现的Shader的特性进行新类型的创作。
去脉
我们能接触到Unlit Graph创建的起点便是Project区下右键菜单的Create->Shader->Unlit Graph
了,直接在Shader Graph源码包下全局搜索Create/Shader/Unlit Graph
即可找到:
照葫芦画瓢在同目录下弄个新文件实现相同功能即可,这下我们便知道Unlit Graph的正主了:UnlitMasterNode
。经过研究发现,它决定了在编辑器下Unlit Master Node的样式:
但这只是个壳子罢了,根据代码中的IUnlitSubShader
为引,找到了其核心:
这个UniversalUnlitSubShader
的作用相当简单:根据编辑器的设置生成Shader代码。如上图便可看出定义Pass数据结构的行为,这也是诱使我来改源码的直接原因。在里面你将见到形如这般的代码:
|
|
如此情况便变得相当清晰了,只要清楚你想生成怎样的Shader代码,在摸熟了生成代码的API,便可自由地进行创作了。通过右键节点可以随时查看生成的代码情况:
注意事项
也许看似还算简单,但其中坑点还是有不少的:
- 不要尝试采用继承的形式去新建新类型,其本身代码就没打算让你这么做,必然会碰壁,除非改源码(如此便违反原则了)
- 做出了修改后,要到对应的Graph文件进行Save操作触发检测。
- 也许是检测的原因,有时候HLSL代码做出了修改后不会被识别到,需要换下行。
- Shader Graph生成的着色器参数有着自己的一套处理方式,务必参考自带的代码。
- Unlit Graph的主Pass并没有LightMode,想做背面Pass的时候要注意下。
- Unlit Graph将渲染模式、混合模式、剔除做成节点设置并不是一个好选择(无法让材质修改),推荐按照URP的方式做成材质属性。
- Shader Graph对于生成的Shader代码存在分支数限制,需要到
Preference->Shader Graph
进行修改上限。值得一提的是,全局Keyword与局部Keyword似乎是分别对待的。 - Shader Graph并不存在完整的环境,它是无法识别到一些渲染管线里的函数的。所以在编写Custom Shader的时候需要加上
#if SHADERGRAPH_PREVIEW
分支判定以处理在编辑模式下的情况:
|
|
后记
现在感觉游戏开发的未来方向就是连连看了,从这点来说UE4的确算是时代前沿。在编辑器里加入逻辑控制元素,让更多人能加入创作,尽可能地解放生产力,的确是游戏开发所需要的。