0%

Lighting Channels 使用及原理

#Blog

Lighting Channels 使用及原理

字面解释

通过light channel设置可以实现灯光分层对不同层物体的影响
只影响对不透明物体的光照,不影响半透 or Mask材质

开启light channels后在光照计算前多一步CopyStencilToLightingChannelTexture,大致计算时间在0.08ms

内部解析

通过截帧可以看到采样光照的时候采样一张uint 的Texture作为LightingChannelsMask进行计算:

通过查阅代码可知道:
DeferredShadingRenderer.cpp 中 通过 CopyStencilToLightingChannelTexture 函数初始化LightingChannelsTexture。

通过 FCopyStencilToLightingChannelsPS shader实现从stencil贴图中读取到LightingChannels

通过查阅源码可以得知UE对Lighting ChannelsMask进行位运算压缩,将多种情况压缩到3位存储到LightingChannelTexture:

1
2
3
4
5
6
7
8
9
// EngineTypes.h
/** Converts lighting channels into a bitfield */
inline uint8 GetLightingChannelMaskForStruct(FLightingChannels Value)
{
// Note: this is packed into 3 bits of a stencil channel
return (uint8)((Value.bChannel0 ? 1 : 0) | (Value.bChannel1 << 1) | (Value.bChannel2 << 2));
}


具体示例我用下表展示:

lightingChannelsMask == 0 -> 0001 -> 1
lightingChannelsMask == 1 -> 0010 -> 2
lightingChannelsMask == 2 -> 0100 -> 4
lightingChannelsMask == 0,1 -> 0011 -> 3
lightingChannelsMask == 0,2 -> 0101 -> 5
lightingChannelsMask == 1,2 -> 0110 -> 6
lightingChannelsMask == 0,1,2 -> 0111 -> 7

Lighting Channels 统一合并在 stencil Texture,以下是SceneRenderTarget中对Lighting channels 进行的划分:

1
2
3
4
5
6
7
8
9
10
11
12
13
// SceneRenderTargets.h

* Stencil layout during basepass / deferred decals:
* BIT ID | USE
* [0] | sandbox bit (bit to be use by any rendering passes, but must be properly reset to 0 after using)
* [1] | unallocated
* [2] | Distance Field Representation
* [3] | Temporal AA mask for translucent object.
* [4] | Lighting channels
* [5] | Lighting channels
* [6] | Lighting channels
* [7] | primitive receive decal bit

在写入DeferredLightUniforms前,UE已进行位移运算将stencil值调整到lighting channel对应的位数(具体可看:STENCIL_LIGHTING_CHANNELS_MASK)

在shader中通过位运算可计算出通道
light channel == 1 : DeferredLightUniforms.LightingChannelMask & 0x6

Notes: 在UE延迟渲染中,会将stencil值在Decal之前将stencil值拷贝到LightingChannelsTexture , 因为后面延迟贴花会重写这些值

参考

https://docs.unrealengine.com/4.27/en-US/BuildingWorlds/LightingAndShadows/LightingChannels/