首页 > Unity3D频道 > 【Unity3D研究院之游戏开发】 > URP下让美术同学困惑的多主光计算
2022
08-28

URP下让美术同学困惑的多主光计算

在URP中Input.hlsl中定义了主光的全局变量,C#管线这边需要每帧将主光的位置和颜色传递到Shader中。

如下图所示,在FrameDebugger中可以看到,这里显示的数值是localToWorldMatrix后的结果,做了归一化它和面板中显示主光的世界坐标是不同的。
URP下让美术同学困惑的多主光计算 - 雨松MOMO程序研究院 - 1

美术同学可能会添加多盏直光, 比如一盏照场景,另一盏照角色,通过层来控制光照影响的层。显然最好是角色使用角色的主光,场景使用场景的主光。然而URP并不是,它会从多盏直光找找一盏来当主光,这盏光有可能是照场景的,也有可能是照角色的。

UniversalRenderPipeline.cs的 GetMainLightIndex方法中

上述代码中可以看到,URP会首先使用RenderSettings.sun太阳光,Lighting天空盒面板中设置的对象。如果没有的话,它会找灯光强度最强的一盏当主光。现在场景中光的结构是这样的。

Hierarchy

Directional Light 1(照场景) 灯光强度 2

Directional Light 2(照角色) 灯光强度 1

此时由于照角色的光强小于场景的光强,所以主光使用Directional Light 1。Directional Light 2则以点光的形式传入计算,当角色渲染时先用主光计算,显然不是美术想要的结果,只是因为后面在多点光的计算中又算了一遍Directional Light 2显示上才不会有太大问题。

多点光的定义是什么呢? 只要不是主光,并且处于激活状态下的光都属于多点光,也就是说将这些光进行计算把结果加上去。

如下图所示,在FrameDebug中可以看到一共会把所有多点光保存在256数组中传入。

URP下让美术同学困惑的多主光计算 - 雨松MOMO程序研究院 - 2
这里的光包含了所有的非主光源以外的所有光,全都计算显然是错误的,因为光上是可以添加过滤层的,还有灯光衰减等因素。Shader这边就需要知道哪些多点光是对自身有用的才需要进行计算。全局变量256数组显然没办法记录,要给每个材质单独记录。

UnityInput.hlsl中CBUFFER中记录了

其中 unity_LightData.y记录了影响当前材质的光源数量,unity_LightIndeices[2]则记录每个索引对应的具体光源index,然后就可以在全局变量256长度的数组中找对具体那盏光对它起了影响。这两个变量的赋值目前SRP并没有开出接口,则是在引擎层做的。

如下代码所示,min(_AdditionalLightsCount.x=4或8,unity_LightData.y是影响物体的点光数量) 最终影响物体的点光数量在4或8以内。

有了数量以后就可以通过Index找光源对应_AdditionalLightsPosition[256] 数组中的索引。

就是这里

综上所述,主光的计算会让美术产生困惑,点光的计算则不会。 这段代码读懂后其实也可以自定义一组针对角色或场景的特殊光源,这样需要修改c#的管线代码,可能美术就不会在困惑了。

最后编辑:
作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

留下一个回复

你的email不会被公开。