提问
Unity 里可以通过 _WorldSpaceLightPos0 来得到平行光方向,这其实是 Unity 觉得这个 uniform 很常用,自动帮我们传入了。
我在 Unreal 的材质节点里找了很久没有找到类似 Light Vector 表示平行光方向的节点。
还是说 Unreal 中只能通过 Blueprint 自己从外部传入了。我知道 Blueprint + Material Parameter Collections 可以满足我的要求,就像 SetGlobalVector 一样。
所以想问问能不能从材质节点直接获取到平行光方向,省得从外部自己传入了。
回答
1. 用 shader 实现
方法不是没有,如图所示,建立一个 custom 节点,然后在参数里输入如图代码即可,做成 Material Function 就可以到处复用。
代码
#ifdef EyeAdaptationStruct
#if MATERIALBLENDING_ANY_TRANSLUCENT
return TranslucentBasePass.Shared.Forward.DirectionalLightDirection;
#else
return OpaqueBasePass.Shared.Forward.DirectionalLightDirection;
#endif
#else
return 0;
#endif
But,个人并不推荐,很显然这是一个很 hack 的方法。这个方法依赖底层 shader 实现,不保证每个版本都能用(4.22测试)。
究其原因,是因为 Unreal 假定材质编辑器提供的主要节点,都是可以通用于所有光照流程的(forward shading/defer shading),而获取 light direction 这种设定 显然 不符合支持超多光源的 defer shading 管线,所以官方本身是不会提供节点的。
因此顺带一提,这个做法只有在 forward shading 可以使用。
不像 Unity,自己编写的 shader ,Epic 官方不怎么管兼容性,这个版本可以用,下个版本引擎 shader 改了,能不能用就不保证了(不过这段代码应该可以适配相当数量的版本)。
2. 正解,蓝图实现
所以题主说的方案,才是 官方鼓励 的。
即 利用蓝图(关卡蓝图)获得平行光方向,传给材质参数集,再从材质中读取,实现动态更新光照的方向(目前只考虑了平行光)。
获取方式如下:
动态更新(关卡蓝图中实现,但平行光方向好像一般不变,除非在游戏场景中有日落日升的效果):
中文版
英文版