虚幻五渲染编程(Graphic篇)【第十二卷:虚幻5中的 ...

2

主题

3

帖子

7

积分

新手上路

Rank: 1

积分
7
发表于 2023-1-13 12:03:21 | 显示全部楼层



我发现自己好久都没有写文章了,究其原因是我个人的研究重点从“一个单点技术”移向“一套技术方案体系”,而一个技术体系或者技术管线可能就不太适合写一个简短的文章了。
这篇文章我将从底层原理上介绍LightChannel的实现方法


What And Why LightChannel

灯光通道机制是UnrealEngine中的一个灯光分层机制


可以让不同层级的灯光互不影响。如果灯光想要影响一个物体,那么这个灯光的channel必须要和物体的channel一致。


这个机制可以让艺术家方便得控制灯光对物体的影响,不过目前虚幻引擎只给了三个灯光channel。比较经常使用的场景是,人物的灯光和场景的灯光是分开的,虽然这有些物理不正确,但是在艺术处理上或者一些影视化的处理上是经常需要使用的手法。


<hr/>引擎底层是如何实现LightChannel的

物体的LightChannel会被先渲染进DepthStencilBuffer中,然后单独拷贝到一张LightChannelTexture中去


这张图乍一看看上去是红色的,但是它里面存的值是int值




然后在渲染灯光的时候,灯光的lightchannel会被保存到UniformBuffer中,下面的代码位于:
FDeferredLightUniformStruct GetDeferredLightParameters(const FSceneView& View, const FLightSceneInfo& LightSceneInfo)函数中


我们再来梳理一下,物体的LightChannel值是存在一张Texture中的,灯光的Lightchannel是存在UniformBuffer中的,所以在渲染灯光的时候,我们比较一下这两个值就可以了,如果两个值相等说明当前像素的物体的LightChannel和灯光的LightChannel是一致的,那么就计算灯光结果,如果不一致那么就直接不进行下面的灯光计算。比较代码:




特别需要强调的是LightChannel和ShadowChannle在虚幻里是两个东西,需要特别注意一下。
<hr/>探索到这里其实大部分机制已经很清楚了,但是这个LightChannel的值是怎么写入DepthStencilBuffer的呢
让我们回到PreDepthPass,我发现DepthPass种并没有写入Stencil值,而是在BasePass里


可以看到BasePass的状态是DepthRead_StencilWrite
我们找到BasePass的MeshDrawCommand的生成逻辑就会发现,LightChannle信息会在构建MeshDrawCommand的时候从PrimitiveSceneProxy塞入MeshDrawCommand




可以看到上面的那段代码STENCIL_LIGHTING_CHANNELS_MASK(PrimitiveSceneProxy ? PrimitiveSceneProxy->GetLightingChannelStencilValue() : 0x00);这里会拿到LightChannel的值,这里的
bEnableReceiveDecalOutput对于BasePass一定是True的,理由如下:




最后这个StencilRef值会被塞入MeshDrawCommand


这里要特别补充的是,Stencil只有八位




Stencil的八位数据基本上被填满了,所以LightChannel的只有三个这么少。


可以看到整个机制还是很简单的
Enjoy it.


todo...




2023/1/11
回复

举报 使用道具

6

主题

9

帖子

21

积分

新手上路

Rank: 1

积分
21
发表于 2023-1-13 12:03:31 | 显示全部楼层
还没有评论,发表第一个评论吧
回复

举报 使用道具

2

主题

5

帖子

9

积分

新手上路

Rank: 1

积分
9
发表于 2023-1-13 12:03:41 | 显示全部楼层
三个太少了,不太够用
回复

举报 使用道具

您需要登录后才可以回帖 登录 | 立即注册
快速回复 返回顶部 返回列表