Unity5之后加入了Physically Based Shading, 即PBS。PBS提供一整套BRDF Shading和Global Illumination解决方案,可以实现真实质感的渲染品质。
使用PBS改变了美术资源制作的pipeline。美术不需要再把光影表现画在贴图上,而是通过第三方工具在贴图上标记出模型表面的物理属性,通过引擎的shading和lighting系统自动得到当前环境下正确的渲染结果。这种方式还有利于实现游戏中的日夜系统和其他动态光影效果。
Unity自带的Standard Shader提供金属度和高光两种方式Shading, 可以满足大部分场景物件的材质表现需要。下图是Unity官方给出类似于迪士尼Shading Spectrum的Shader Charts。
但是在实际项目的开发过程中,往往需要在Standard Shader的基础上添加一些自定义效果,比如服装道具上Bling Bling的反光,天气系统里的雨雪等。这种需求既要求兼容Unity的光照系统,又要实现PBR多样化的表现。
下面以在Standard Shader上添加雪的效果为例,主要扩展BuildIn Shaders的两个文件:
1. Standard Shader.shader。Standard Shader里有两个lod sub shader。以第一个sub shader为例,分为5个pass。第一个pass是对主光源的前向渲染。第二个pass是对应动态点光源的渲染。第三个pass是关于Shadow map的计算。第四个pass是延迟渲染。第五个参与烘培间接光照计算,不参与实时渲染。添加雪的示例需要创建自己的shader文件: Standard Shader with Snow.shader。并且修改第一个pass,自定义fragment shader: #pragma fragment fragForwardBase_Snow。
2. StandardCore.cginc。此文件包含了vertex shader和fragment shader的实现。所以要自己创建一个新的StandardCoreSnow.cginc文件,在里面实现fragment shader。并且在Standard Shader with Snow.shader里包含此文件。
fragment shader的前向渲染实现是在fragForwardBaseInternal函数内。函数主要分三部分
i. 在FragmentSetup()内获得像素的BRDF参数,例如albedo,metallic, normal, eyeVec等。
ii. 在FragmentGI()内收集光照信息。
iii. UNITY_BRDF_PBS()在StandardBRDF.cginc内根据当前graphics tier setting获得相应的BRDF模型和光照输入,输出计算结果。
后两步涉及lighting和BRDF模型的计算,无需改动。只需要重写第一部分像素信息的收集函数即可: FragmentSetup_Snow()。这个函数内部实现照抄FragmentSetup(),只在结尾添加一个AddSnow()函数,在内部定义albedo如何表现雪的机制(示例中的实现因为项目关系暂时不便公开)。
Standard Shader的场景效果:
Standard Shader上加雪的效果:
还可以用一些trick做出不同的效果。比如下面石头上雪的两种覆盖效果。第一种是正常的覆盖方式,第二种侧面覆盖方式。后者可以用到石板台阶上,造成雪地被踩过的效果。
还可以做其他的一些效果,比如雪消融的动态效果,或者修改下颜色模拟植被。
结论, Unity5的Buildin Shaders虽然不是一个严格意义上的开源工程,但Unity实现了lighting和shading的分离,仍然很容易在其基础上做出更复杂的扩展效果。
附:
腾讯光子工作室群技术美术组招聘 Shading Tech Artist(含实习生,长期有效)
相关阅读:
手游逆向分析: Unity内还原游戏场景/角色渲染效果
戏角色写实头发制作
作者:大星星
专栏地址:https://zhuanlan.zhihu.com/p/26395413