跳转至

本期内容: - 烘焙静态阴影 - 烘焙光配合实时光照 - 混合实时阴影和静态阴影 - 支持四种阴影遮罩灯光

烘焙阴影的优点

可以不受最大阴影距离的限制。烘焙阴影不会被剔除,也无法更改

Distance ShadowMask

将Lighting中的Lighting Mode设置成ShadowMask 将Project Setting的Quality的ShadowMask Mode设置为Distance ShadowMask模式

多了很多红黑色的阴影贴图 ![[Pasted image 20250218010606.png]]

我们需要做的是,将设置了Mixed混合模式Light和ShadowMask的Lighting进行识别,并开启shadowMask关键字及功能,提供阴影遮罩的相关功能。

经过一系列(此处大量省略)的gi和shadow设置后,得到采样阴影蒙版的结果 ![[Pasted image 20250218014247.png]]

遮挡探针ProbesOcclusion

我们可以明显看到,动态对象并没有使用阴影遮罩数据。他们使用光照探针。 不过,Unity会将阴影遮罩数据也烘焙到光照探针中,将其称为遮挡探针

阴影遮罩未使用通道则以白色为探针。

![[Pasted image 20250218021823.png]]

遮罩探针虽然足以让阴影遮罩通过探针工作,但它会破坏GPU Instance

破坏GPUInstancing问题

UnityInstancing仅在定义SHADOWS_SHADOWMASK时执行此作。所以我们需要在引用UnityInstancing.hlsl库(common.hlsl)前,定义:

#if defined(_SHADOW_MASK_DISTANCE)
    #define SHADOWS_SHADOWMASK
#endif

LPPVS

经过一系列处理。。。 ![[Pasted image 20250218022559.png]]

MeshBall增加遮挡探针数据

省略了,总之就是增加遮挡探针,教程好像忘了处理LPPVs了(哦不对,好像这就是处理过后的) ![[Pasted image 20250218022844.png]]

删除调试效果

Lighting.hlsl

~~//return gi.shadowMask.shadows.rgb;~~

混合阴影

目前我们已经有了阴影遮罩,但是目前还没有在实时阴影的时候使用它,当片段最终超出最大阴影距离时,阴影还是会消失。因此我们要实现混合的方案。

烘焙阴影(未过渡版本)

这个时候和实时阴影一样会随着距离消失 ![[Pasted image 20250218100658.png]] 但我们可以看到阴影其实已经烘焙下来了 ![[Pasted image 20250218100743.png]]

过渡阴影

要根据深度从实时阴影过渡到烘焙阴影,我们必须根据全局阴影强度在它们之间进行插值。

动态阴影照常淡化,而静态对象投射的阴影过渡到阴影蒙版(下图柱子开始淡化了) ![[Pasted image 20250218101231.png]]

仅烘焙阴影

当我们拉到超出阴影距离范围时,实时阴影和阴影遮罩都会消失。我们还需要支持有阴影遮罩但是没有实时阴影的情况。

![[Pasted image 20250218101740.png]]

因此超出距离后,我们不能直接剔除阴影投射物的光源。我们需要获取阴影强度,但是阴影强度大于0,着色器将对阴影贴图采样,所以使用负阴影强度

bakedShadow的时候取个绝对值

        //现在改为:仅使用烘焙阴影或无阴影
        shadow =  GetBakedShadow(global.shadowMask, abs(directional.strength));

最终结果: ![[Pasted image 20250218103038.png]]

ShadowMask遮罩方式

这是另一种阴影遮罩模式,简称为 Shadowmask 。它的工作原理与距离模式完全相同,不同之处在于 Unity 会省略使用阴影遮罩的光源的静态阴影投射物,即静态几何体没有实时阴影投射。

因为阴影遮罩随处可见,所以我们也可以将其用于任何地方的静态阴影。这意味着更少的实时阴影,这使得渲染速度更快,但代价是近距离静态阴影的质量较低

实现方式: - 首先,实时阴影必须由全局强度调制,以根据深度淡化它。 - 然后,通过取最小值来组合烘焙阴影和实时阴影。之后,光源的阴影强度将应用于合并的阴影。(注意,还是要混合实时阴影的,只不过近处我们把阴影都设置为静态阴影了)

效果: ![[Pasted image 20250218105247.png]]

多光源阴影遮罩通道

由于阴影遮罩贴图有四个通道,因此它最多可以支持四个混合光源。烘焙时最重要的光源获得红色通道,第二个光源获得绿色通道,依此类推。(不过第四个光源是alpha通道,所以看不见) ![[Pasted image 20250218112812.png]]

我们先检索光源的遮罩通道索引。当我们向 GPU 发送 4D 向量时,我们可以将其存储在我们返回的向量的第四个通道中,将返回类型更改为 Vector4。当光源不使用阴影遮罩时,我们通过将其索引设置为 −1 来表示这一点。