super1 发表于 2022-6-5 11:18

虚幻五渲染编程(Graphic篇)【第六卷: Customize GBuffer ...




在Ue5当中拓展GBuffer的时候,我发现UE5的GBuffer的Encode和Decode和Ue4有一点不同,所以我就仔细研究了下UE5的GBuffer的Encode和Decode机制。


GBuffer的Encode和Decode

在UE5中目前会有两套Encode和Decode机制,通过GBUFFER_REFACTOR宏来区隔


第一种是C++生成的Shader来生成Encode和Decode代码


第二种是在Shader里写死的


在FShaderCompileUtilities::ApplyDerivedDefines函数中把GBUFFER_REFACTOR宏塞入


这种通过C++来生成Shader代码的方式问题在于不方便阅读,但好处是非常灵活,可以让C++层来控制Shading。



不方便阅读

GBuffer拓展需要做的事情

如果我们要拓展GBuffer我们需要做几件事情
第一是在C++层要把我们的RT先绑定上去,这件事情需要在CreateSceneTextureUniformBuffer中完成




当然与此同时也需要拓展好FSceneTextureParameters


做完C++层的拓展以后,我们需要拓展C++层和Shader层的DecodeGBuffer和EncodeGBuffer,UE5中需要做好C++方法和Shader写死方法的两个方法的拓展
ShaderGenerationUtil.cpp




我们可以在VS中查看FullStr的值是否符合要求:





DecodeGBufferDataDirect

然后我们就可以开始拓展Shader层了
DeferredShadingCommon.ush


SceneTexturesCommon.ush


最后在LightingPass里就能塞入我们的GBuffer,下面是我的结果:


<hr/>更新:
不知道有没有朋友遇到:“给GBuffer增加了一个数据成员以后就编译不过”的问题:


可是我的GBuffer明明之前有初始化的就是那句 FGBufferData GBuffer = (FGBufferData)0; 这句就是在初始化GBuffer了怎么还会报错呢?
通过我艰苦的寻找Bug我发现如下的代码(下面是我没动过的UE官方原生UE5代码):


我的ToonBufferA这个数据是在这个函数的最后赋值初始化的


这个DecodeGBufferData已经把所有的成员全部重新赋值了一遍了呀,而且出错的地方也不是这样,报错的信息是出在了其它函数身上,但是我怎么改其它函数都不对。
后面经过三天的寻找,我试着把代码改成了下面这样:


问题就解决了。
这说明了几个问题:
1.Epic的代码还是存在漏洞。
2.Epic的Shader代码报错的Output可信度很差,只能作为你修改代码的建议不能作为依据。
3.虚幻的底层Shader开发的确难度过大,这一点UE对比Unity还存在明显差距。
4.假设现在有个Shader的结构体
struct AAA
{
    float a;
    float b;
    float c;
    float d;
};如果我们要编写一个Init函数,如果按照虚幻这个bug里的写法就是:
void Init()
{
    AAA data;
    data.a = 0;
    data.b = 0.1;
    data.c = 0.2;
    data.d = 0.2;
}像上述代码这么写是不保险的,最安全的写法是:
void Init()
{
    AAA data = (AAA)0;
    data.a = 0;
    data.b = 0.1;
    data.c = 0.2;
    data.d = 0.2;
}


通过虚幻的这个实例,我发现控制Shader的方式还可以通过通知Shader的生成来控制,这个也不失为一个比较好的办法。但是C++写Shader太难阅读了,而且目前UE5.0版本C++部分和Shader写死部分并没有完全解耦,我个人认为这种设计十分失败。
Enjoy it.


todo...




2022/5/29

xiaozongpeng 发表于 2022-6-5 11:20

日黑unity呀

Zephus 发表于 2022-6-5 11:21

你去看下他写的那个代码,也会想diss他的,真的代码和设计水平太差了。

xiaozongpeng 发表于 2022-6-5 11:30

不愧是大佬,思路清晰。我想做卡渲,多加几个Gbuffer,结果发现太难改,最后还是舍弃一些进度encode到已有gbuffer了
页: [1]
查看完整版本: 虚幻五渲染编程(Graphic篇)【第六卷: Customize GBuffer ...