diff --git a/.obsidian/plugins/various-complements/data.json b/.obsidian/plugins/various-complements/data.json index e67c881..09512a3 100644 --- a/.obsidian/plugins/various-complements/data.json +++ b/.obsidian/plugins/various-complements/data.json @@ -102,6 +102,30 @@ "lastUpdated": 1704193979940 } } + }, + "UE5中,这些名称有了一定的变化": { + "UE5中,这些名称有了一定的变化": { + "currentFile": { + "count": 1, + "lastUpdated": 1706168576772 + } + } + }, + "MooaToonDataB": { + "MooaToonDataB": { + "currentFile": { + "count": 1, + "lastUpdated": 1706175926016 + } + } + }, + "LightColor": { + "LightColor": { + "currentFile": { + "count": 1, + "lastUpdated": 1706177275907 + } + } } } } \ No newline at end of file diff --git a/03-UnrealEngine/Rendering/Debug/RenderDoc使用技巧.md b/03-UnrealEngine/Rendering/Debug/RenderDoc使用技巧.md index 83d47bd..eb7b814 100644 --- a/03-UnrealEngine/Rendering/Debug/RenderDoc使用技巧.md +++ b/03-UnrealEngine/Rendering/Debug/RenderDoc使用技巧.md @@ -13,7 +13,6 @@ rating: ⭐⭐ ### UE5中的改动 UE5中,这些名称有了一定的变化 - | 旧名称 | 新名称 | 注解 | | --------------------------------------- | ------------------------ | -------------------------------------------------------------------------- | | r.Shaders.KeepDebugInfo | r.Shaders.Symbols | 通过生成符号并将其写入主机的磁盘来启用着色器调试,PC符号仍以内联方式存储。 | @@ -21,6 +20,7 @@ UE5中,这些名称有了一定的变化 | r.Shaders.PrepareExportedDebugInfo | r.Shaders.GenerateSymbol | 生成符号,但不将其写入磁盘(备注:符号存储在DDC中) | | r.Shaders.ExportDebugInfo | r.Shaders.WriteSymbols | 如果符号已生成,则将其写入磁盘。 | + ## 其他设置 renderdoc.BinaryPath  // 查看RenderDoc的安装路径 renderdoc.BinaryPath "C:\Program Files\RenderDoc"  // 设置RenderDoc的安装路径为C:\Program Files\RenderDoc @@ -160,4 +160,8 @@ Resource Inspector中右侧查看那些事件使用了此资源 ![](https://pic4.zhimg.com/80/v2-84f8f79ac5d241946aeabaa59576a947_720w.webp) -![](https://pic4.zhimg.com/80/v2-6dca8e57407f84970125b9114b9bde2f_720w.webp) \ No newline at end of file +![](https://pic4.zhimg.com/80/v2-6dca8e57407f84970125b9114b9bde2f_720w.webp) +# UE5.2之后开启Renderdoc +在DefaultEngine.ini中添加一下配置: +[/Script/RenderDocPlugin.RenderDocPluginSettings] +renderdoc.AutoAttach=True \ No newline at end of file diff --git a/03-UnrealEngine/Rendering/RenderingPipeline/开启RenderDoc功能.md b/03-UnrealEngine/Rendering/RenderingPipeline/开启RenderDoc功能.md new file mode 100644 index 0000000..f3ee21d --- /dev/null +++ b/03-UnrealEngine/Rendering/RenderingPipeline/开启RenderDoc功能.md @@ -0,0 +1,7 @@ +--- +title: Untitled +date: 2024-01-25 15:40:49 +excerpt: +tags: +rating: ⭐ +--- diff --git a/03-UnrealEngine/卡通渲染相关资料/演讲笔记/JasonMa/JasonMa渲染方案分析.md b/03-UnrealEngine/卡通渲染相关资料/演讲笔记/JasonMa/JasonMa渲染方案分析.md new file mode 100644 index 0000000..e2f2cb6 --- /dev/null +++ b/03-UnrealEngine/卡通渲染相关资料/演讲笔记/JasonMa/JasonMa渲染方案分析.md @@ -0,0 +1,311 @@ +--- +title: JasonMa渲染方案分析 +date: 2024-01-25 16:02:26 +excerpt: +tags: +rating: ⭐ +--- +# 前言 +截止版本UE5.3.2。添加了一种新的GBuffer精度格式GBT_Uint_32_32_32_32,以及RT7。 + +修改内容: +- GBufferPostDecode.ush:在GBufferPostDecode中给FGBufferData添加InitMooaToonContext()逻辑 +- SceneRendering.cpp:Debug用的渲染变量调节,并且在FViewInfo::SetupUniformBufferParameters()添加设置相关变量的逻辑。 +- 其他: + - MaterialBaking:ExportMaterialProxy.h + - MaterialEditor:MaterialEditor.cpp + - PixelInspector:PixelInspectorResult.cpp、PixelInspectorResult.h + +# ToonShadingCommon.ush +除了一下工具函数,主要实现: +1. GBuffer的一些Encode / Decode Helper函数。 +2. 用于存储数据的struct FMooaToonData、FMooaToonContext。 +3. 针对上面2个结构体编码与解码的函数。FMooaCustomPayload用于光追Shader。 + +## 数据结构体 +```c++ +struct FMooaToonContext +{ + FMooaToonData MooaToonData; + bool IsMainLight; + float3 LightColor; + bool IsEditorPreviewWorldType; + float Exposure; + uint2 PixelPos; // SVPos.xy +}; + +struct FMooaToonData +{ + // Diffuse + float3 MainLightShadowColor; + float MainLightShadowValueOffset; + float MainLightShadowApplyLightColor; + float OtherLightDiffuseThreshold; + float OtherLightDiffuseFeather; + float GlobalIlluminationIntensity; + float GlobalIlluminationDirectionality; + + // Specular + float3 SpecularColor; + float SpecularThreshold; + float SpecularFeather; + float ReflectionIntensity; + bool IsPBRSpecular; + float RimLightIntensity; + float RimLightWidth; + float RimLightAngle; + float RimLightDepthThreshold; + // Ray Tracing Shadow + uint Stencil; + uint RayTracingShadowFlag; + float HairShadowWidth; + float HairShadowIntensity; + + // Unused + float CustomData3; +}; +``` +## Encode/Decode +这里推荐使用计算器进行计算更加好理解。 +```c++ +//取得指定Bits位数的最大数值,8位 => 255 +uint GetBitsMaxValue(int Bits = 8) {return (1L << Bits) - 1;} + +//将2个uint合并1个uint,将Src1移动Scr2的位数后,将2者进行或运算合并到一起。 +uint EncodeUint2ToUint(uint Src1, uint Src2, int BitsSrc1 = 8, int BitsSrc2 = 8) +{ + return ((Src1 & GetBitsMaxValue(BitsSrc1)) << BitsSrc2) | + (Src2 & GetBitsMaxValue(BitsSrc2)); +} + +//将2个uint合并1个uint后转换成浮点数(0~1) +float EncodeUint2ToFloat(uint Src1, uint Src2, int BitsSrc1 = 8, int BitsSrc2 = 8) +{ + return float(EncodeUint2ToUint(Src1, Src2, BitsSrc1, BitsSrc2)) / GetBitsMaxValue(BitsSrc1 + BitsSrc2); +} + +//将合并后Uint还原成2个uint +void DecodeUint2FromUint(uint Src, out uint Dst1, out uint Dst2, int BitsDst1 = 8, int BitsDst2 = 8) +{ + Dst1 = (Src >> BitsDst2) & GetBitsMaxValue(BitsDst1); + Dst2 = Src & GetBitsMaxValue(BitsDst2); +} + +//将合并后float(0~1)还原成2个uint +void DecodeUint2FromFloat(float Src, out uint Dst1, out uint Dst2, int BitsDst1 = 8, int BitsDst2 = 8) +{ + uint FloatToUint = uint(Src * GetBitsMaxValue(BitsDst1 + BitsDst2)); + DecodeUint2FromUint(FloatToUint, Dst1, Dst2, BitsDst1, BitsDst2); +} + +//将float(0~1)编码成uint +uint EncodeFloatToUint(float Src1, int BitsSrc1 = 8) +{ + return saturate(Src1) * GetBitsMaxValue(BitsSrc1); +} + +uint EncodeFloat2ToUint(float Src1, float Src2, int BitsSrc1 = 8, int BitsSrc2 = 8) +{ + return EncodeUint2ToUint(EncodeFloatToUint(Src1, BitsSrc1), EncodeFloatToUint(Src2, BitsSrc2), BitsSrc1, BitsSrc2); +} + +float EncodeFloat2ToFloat(float Src1, float Src2, int BitsSrc1 = 8, int BitsSrc2 = 8) +{ + return EncodeUint2ToFloat(EncodeFloatToUint(Src1, BitsSrc1), EncodeFloatToUint(Src2, BitsSrc2), BitsSrc1, BitsSrc2); +} + +//将uint还原成float(0~1) +float DecodeFloatFromUint(uint Src, int BitsDst1 = 8) +{ + return float(Src & GetBitsMaxValue(BitsDst1)) / GetBitsMaxValue(BitsDst1); +} + +void DecodeFloat2FromUint(uint Src, out float Dst1, out float Dst2, int BitsDst1 = 8, int BitsDst2 = 8) +{ + uint OutUint1, OutUint2; + DecodeUint2FromUint(Src, OutUint1, OutUint2, BitsDst1, BitsDst2); + Dst1 = DecodeFloatFromUint(OutUint1, BitsDst1); + Dst2 = DecodeFloatFromUint(OutUint2, BitsDst2); +} + +void DecodeFloat2FromFloat(float Src, out float Dst1, out float Dst2, int BitsDst1 = 8, int BitsDst2 = 8) +{ + uint OutUint1, OutUint2; + DecodeUint2FromFloat(Src, OutUint1, OutUint2, BitsDst1, BitsDst2); + Dst1 = DecodeFloatFromUint(OutUint1, BitsDst1); + Dst2 = DecodeFloatFromUint(OutUint2, BitsDst2); +``` + +## 结构体与GBuffer Encode/Decode +```c++ +void EncodeMooaToonData(FMooaToonData MooaToonData, out float4 MooaToonDataA, out float4 MooaToonDataB, out float4 MooaToonDataC) +{ + MooaToonDataA = (float4)0; + MooaToonDataB = (float4)0; + MooaToonDataC = (float4)0; + + MooaToonDataA.x = EncodeFloat2ToUint(MooaToonData.OtherLightDiffuseThreshold, MooaToonData.OtherLightDiffuseFeather); + MooaToonDataA.y = EncodeFloat2ToUint(MooaToonData.GlobalIlluminationIntensity, MooaToonData.GlobalIlluminationDirectionality, 6, 6); + MooaToonDataA.z = EncodeFloat2ToUint(MooaToonData.MainLightShadowApplyLightColor, MooaToonData.CustomData3, 6, 4); + MooaToonDataA.w = EncodeUint2ToUint( + EncodeFloatToUint(MooaToonData.HairShadowWidth, 6), + EncodeUint2ToUint( + MooaToonData.Stencil, + EncodeUint2ToUint(MooaToonData.RayTracingShadowFlag, MooaToonData.IsPBRSpecular ? 1 : 0, 2, 1), + 5, 3), + 6, 8); + + MooaToonDataB.x = EncodeFloat2ToUint(MooaToonData.SpecularColor.r, MooaToonData.SpecularColor.g); + MooaToonDataB.y = EncodeUint2ToUint( + EncodeFloatToUint(MooaToonData.SpecularColor.b), + EncodeFloat2ToUint(MooaToonData.ReflectionIntensity, MooaToonData.HairShadowIntensity, 6, 6), + 8, 12); + MooaToonDataB.z = EncodeUint2ToUint( + EncodeFloat2ToUint(MooaToonData.SpecularThreshold, MooaToonData.SpecularFeather), + EncodeFloatToUint(MooaToonData.RimLightIntensity, 6), + 16, 6); + MooaToonDataB.w = EncodeUint2ToUint( + EncodeFloat2ToUint(MooaToonData.RimLightWidth, MooaToonData.RimLightAngle, 6, 6), + EncodeFloatToUint(MooaToonData.RimLightDepthThreshold, 6), + 12, 6); + + MooaToonDataC.rgb = saturate(MooaToonData.MainLightShadowColor); + MooaToonDataC.a = saturate(MooaToonData.MainLightShadowValueOffset); +} + +FMooaToonData DecodeMooaToonData(float4 MooaToonDataA, float4 MooaToonDataB, float4 MooaToonDataC) +{ + FMooaToonData MooaToonData = (FMooaToonData)0; + uint Out0, Out1, Out2, Out3; + DecodeFloat2FromUint(MooaToonDataA.x, MooaToonData.OtherLightDiffuseThreshold, MooaToonData.OtherLightDiffuseFeather); + DecodeFloat2FromUint(MooaToonDataA.y, MooaToonData.GlobalIlluminationIntensity, MooaToonData.GlobalIlluminationDirectionality, 6, 6); + DecodeFloat2FromUint(MooaToonDataA.z, MooaToonData.MainLightShadowApplyLightColor, MooaToonData.CustomData3, 6, 4); + DecodeUint2FromUint(MooaToonDataA.w, Out0, Out1, 6, 8); + MooaToonData.HairShadowWidth = DecodeFloatFromUint(Out0, 6); + DecodeUint2FromUint(Out1, MooaToonData.Stencil, Out2, 5, 3); + DecodeUint2FromUint(Out2, MooaToonData.RayTracingShadowFlag, MooaToonData.IsPBRSpecular, 2, 1); + + DecodeFloat2FromUint(MooaToonDataB.x, MooaToonData.SpecularColor.r, MooaToonData.SpecularColor.g); + DecodeUint2FromUint(MooaToonDataB.y, Out0, Out1, 8, 12); + MooaToonData.SpecularColor.b = DecodeFloatFromUint(Out0); + DecodeFloat2FromUint(Out1, MooaToonData.ReflectionIntensity, MooaToonData.HairShadowIntensity, 6, 6); + + DecodeUint2FromUint(MooaToonDataB.z, Out0, Out1, 16, 6); + DecodeFloat2FromUint(Out0, MooaToonData.SpecularThreshold, MooaToonData.SpecularFeather); + MooaToonData.RimLightIntensity = DecodeFloatFromUint(Out1, 6); + DecodeUint2FromUint(MooaToonDataB.w, Out0, Out1, 12, 6); + DecodeFloat2FromUint(Out0, MooaToonData.RimLightWidth, MooaToonData.RimLightAngle, 6, 6); + MooaToonData.RimLightDepthThreshold = DecodeFloatFromUint(Out1, 6); + + MooaToonData.MainLightShadowColor = MooaToonDataC.rgb; + MooaToonData.MainLightShadowValueOffset = MooaToonDataC.a; + + return MooaToonData; +} + +uint4 EncodeMooaToonDataToBuffer(FMooaToonData MooaToonData) +{ + MooaToonData.SpecularColor = LinearToSrgb(saturate(MooaToonData.SpecularColor)); + + float4 MooaToonDataA, MooaToonDataB, MooaToonDataC; + uint4 Out; + EncodeMooaToonData(MooaToonData, MooaToonDataA, MooaToonDataB, MooaToonDataC); + Out.x = EncodeUint2ToUint(MooaToonDataA.x, MooaToonDataB.x, 16, 16); + Out.y = EncodeUint2ToUint(MooaToonDataA.y, MooaToonDataB.y, 12, 20); + Out.z = EncodeUint2ToUint(MooaToonDataA.z, MooaToonDataB.z, 10, 22); + Out.w = EncodeUint2ToUint(MooaToonDataA.w, MooaToonDataB.w, 14, 18); + + return Out; +} + +FMooaToonData DecodeMooaToonDataFromBuffer(uint4 ToonBufferA, float4 CustomData) +{ + uint4 Out0, Out1; + DecodeUint2FromUint(ToonBufferA.x, Out0.x, Out1.x, 16, 16); + DecodeUint2FromUint(ToonBufferA.y, Out0.y, Out1.y, 12, 20); + DecodeUint2FromUint(ToonBufferA.z, Out0.z, Out1.z, 10, 22); + DecodeUint2FromUint(ToonBufferA.w, Out0.w, Out1.w, 14, 18); + float4 MooaToonDataA = Out0; + float4 MooaToonDataB = Out1; + FMooaToonData MooaToonData = DecodeMooaToonData(MooaToonDataA, MooaToonDataB, CustomData); + MooaToonData.MainLightShadowColor = sRGBToLinear(MooaToonData.MainLightShadowColor); + MooaToonData.SpecularColor = sRGBToLinear(MooaToonData.SpecularColor); + return MooaToonData; +} +``` +# BasePassPixelShader.usf + +## GBuffer +```c++ +/* + * CustomData (GBufferD) (MP_MooaToonDataC) (0~1) = MainLightShadowColor(8 8 8) MainLightShadowValueOffset(8) + * + * ToonBufferA (RGBA Uint 32) + * xyzw: MooaToonDataA.xyzw | MooaToonDataB.xyzw (32 bits total) + * + * MP_MooaToonDataA (float4, max storage 23 bits uint) + * x: OtherLightDiffuseThreshold(8) OtherLightDiffuseFeather(8) + * y: GlobalIlluminationIntensity(6) GlobalIlluminationDirectionality(6) + * z: MainLightShadowApplyLightColor(6) CustomData3(4) + * w: HairShadowWidth(6) Stencil(5) RayTracingShadowFlag(2) IsPBRSpecular(1) + * + * MP_MooaToonDataB (float4, max storage 23 bits uint) + * x: SpecularColor.x(8) SpecularColor.y(8) + * y: SpecularColor.z(8) ReflectionIntensity(6) HairShadowIntensity(6) + * z: SpecularThreshold(8) SpecularFeather(8) RimLightIntensity(6) + * w: RimLightWidth(6) RimLightAngle(6) RimLightDepthThreshold(6) + * + * + * Tips: store sRGB Color to maximize accuracy + */ +``` + +>PS.float4, max storage 23 bits uint +>Jason自己添加了GBT_Uint_32_32_32_32的GBuffer格式。 +- MooaToonDataA (RGBA Uint 32 **ToonBufferA**) + - R(4+4):OtherLightDiffuseThreshold + OtherLightDiffuseFeather + - G(4+4):GlobalIlluminationIntensity + GlobalIlluminationDirectionality + - B(4+4):MainLightShadowApplyLightColor + CustomData3 + - A (6+5+2+1):HairShadowWidth + Stencil + RayTracingShadowFlag + IsPBRSpecular +- MooaToonDataB (RGBA Uint 32,从材质直接传递到FGBuffer结构体中,位置位于BasePassPixelShader.usf的InitMooaToonData与InitMooaToonContext,其他可能位置位于GBufferHelpers.ush的GBufferPostDecode()、DeferredShadingCommon.ush的DecodeGBufferData()) + - R(8+8):SpecularColor.x + SpecularColor.y + - G(8+6+6):SpecularColor.z + ReflectionIntensity + HairShadowIntensity + - B(8+8+6):SpecularThreshold + SpecularFeather + RimLightIntensity + - A(6+6+6):RimLightWidth + RimLightAngle + RimLightDepthThreshold(6) +- MooaToonDataC(**GBufferD CustomData**) = MainLightShadowColor(8 8 8) + MainLightShadowValueOffset(8) + + +# LightModel +```c++ +/* ================================== Mooa Toon Deferred Lighting Model ====================================================================================================== + * IndirectColor                (DiffuseIndirectComposite.usf)    = IndirectDiffuse + IndirectSpecular + * DirectionalLightShadingColor (DeferredLightPixelShaders.usf)    = (lerp(ShadowColor, Diffuse * LightColor, min(ShadowValue, LightAttenuation)) + Specular * LightColor) * MooaExposure + * OtherLightShadingColor        (DeferredLightPixelShaders.usf)    = (Diffuse + Specular) * LightColor * min(ShadowValue, LightAttenuation) * OtherLightCount + * FinalColor                                                    = IndirectColor + DirectionalLightShadingColor + OtherLightShadingColor + * ================================================================================================================================================================== + */ + // Mooa Indirect Lighting +if (Material.GBufferData.ShadingModelID == SHADINGMODELID_TOON) +{ + float3 SHDiffuseAverage = GetSkySHDiffuse(0.0f) * View.SkyLightColor.rgb * View.PreExposure; + float3 LumenGiDiffuse = IndirectLighting.Diffuse; + FMooaToonData MooaToonData = Material.GBufferData.MooaToonContext.MooaToonData; + OutAddColor.rgb = //MooaToonData.MainLightShadowColor + + lerp(SHDiffuseAverage * Material.GBufferData.BaseColor, LumenGiDiffuse, MooaToonData.GlobalIlluminationDirectionality) * MooaToonData.GlobalIlluminationIntensity; + OutAddColor.rgb += IndirectLighting.Specular * Pow2(MooaToonData.ReflectionIntensity); + OutAddColor.rgb *= View.MooaExposureScale; + OutAddColor.a = Luminance(OutAddColor.rgb); +} +else +{ + IndirectLighting.Specular *= GetSSSCheckerboadSpecularScale(PixelPos, Material.bNeedsSeparateLightAccumulation); + FLightAccumulator LightAccumulator = (FLightAccumulator)0; + LightAccumulator_Add( + LightAccumulator, + IndirectLighting.Diffuse + IndirectLighting.Specular, + IndirectLighting.Diffuse, + 1.0f, + Material.bNeedsSeparateLightAccumulation); + OutAddColor = LightAccumulator_GetResult(LightAccumulator); +} +``` \ No newline at end of file