From 0e5712546f32a2c27e43c5e928a42c7d0809c8f3 Mon Sep 17 00:00:00 2001 From: BlueRose <378100977@qq.com> Date: Thu, 14 Nov 2024 12:15:35 +0800 Subject: [PATCH] vault backup: 2024-11-14 12:15:34 --- .../various-complements/histories.json | 2 +- .../虚幻开放日2024/其他有价值的分享.md | 8 + .../虚幻引擎4移动端渲染管线改造总结分享.md | 212 ++++++++++++++++++ 3 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 02-Note/演讲与教程笔记/虚幻开放日2024/其他有价值的分享.md create mode 100644 02-Note/演讲与教程笔记/虚幻开放日2024/虚幻引擎4移动端渲染管线改造总结分享.md diff --git a/.obsidian/plugins/various-complements/histories.json b/.obsidian/plugins/various-complements/histories.json index c2e7e8a..b9b0385 100644 --- a/.obsidian/plugins/various-complements/histories.json +++ b/.obsidian/plugins/various-complements/histories.json @@ -1 +1 @@ -{"实现了一个在屏幕空间宽度恒定的":{"实现了一个在屏幕空间宽度恒定的":{"currentFile":{"count":1,"lastUpdated":1728700795488}}},"TsDirectorCamManagerActor":{"TsDirectorCamManagerActor":{"currentFile":{"count":1,"lastUpdated":1729139925413}}},"Bloom":{"Bloom":{"currentFile":{"count":1,"lastUpdated":1729490733473}}},"FBloomFinalizeApplyConstantsCS":{"FBloomFinalizeApplyConstantsCS":{"currentFile":{"count":1,"lastUpdated":1729584275683}}},"解决NaiLin高跟":{"解决NaiLin高跟":{"currentFile":{"count":1,"lastUpdated":1729587089926}}},"优化项目举例,参与多个项目。":{"优化项目举例,参与多个项目。":{"currentFile":{"count":1,"lastUpdated":1729696025968}}},"制作各种编辑器工具":{"制作各种编辑器工具":{"currentFile":{"count":1,"lastUpdated":1729696038138}}},"RigidBodyIndex":{"RigidBodyIndex":{"currentFile":{"count":1,"lastUpdated":1730280351906}}},"IOS&Android Engine Package":{"IOS&Android Engine Package":{"internalLink":{"count":1,"lastUpdated":1730702690372}}},"AI动捕优化思路:":{"AI动捕优化思路:":{"currentFile":{"count":1,"lastUpdated":1731243010285}}}} \ No newline at end of file +{"TsDirectorCamManagerActor":{"TsDirectorCamManagerActor":{"currentFile":{"count":1,"lastUpdated":1729139925413}}},"Bloom":{"Bloom":{"currentFile":{"count":1,"lastUpdated":1729490733473}}},"FBloomFinalizeApplyConstantsCS":{"FBloomFinalizeApplyConstantsCS":{"currentFile":{"count":1,"lastUpdated":1729584275683}}},"解决NaiLin高跟":{"解决NaiLin高跟":{"currentFile":{"count":1,"lastUpdated":1729587089926}}},"优化项目举例,参与多个项目。":{"优化项目举例,参与多个项目。":{"currentFile":{"count":1,"lastUpdated":1729696025968}}},"制作各种编辑器工具":{"制作各种编辑器工具":{"currentFile":{"count":1,"lastUpdated":1729696038138}}},"RigidBodyIndex":{"RigidBodyIndex":{"currentFile":{"count":1,"lastUpdated":1730280351906}}},"IOS&Android Engine Package":{"IOS&Android Engine Package":{"internalLink":{"count":1,"lastUpdated":1730702690372}}},"AI动捕优化思路:":{"AI动捕优化思路:":{"currentFile":{"count":1,"lastUpdated":1731243010285}}},"TODO清单":{"TODO清单":{"internalLink":{"count":1,"lastUpdated":1731553316709}}},"CustomThunk":{"CustomThunk":{"internalLink":{"count":1,"lastUpdated":1731555464503}}},"MobileTAA只做两帧混合":{"MobileTAA只做两帧混合":{"currentFile":{"count":1,"lastUpdated":1731557419798}}},"UMG组件作用笔记":{"UMG组件作用笔记":{"internalLink":{"count":1,"lastUpdated":1731557505574}}}} \ No newline at end of file diff --git a/02-Note/演讲与教程笔记/虚幻开放日2024/其他有价值的分享.md b/02-Note/演讲与教程笔记/虚幻开放日2024/其他有价值的分享.md new file mode 100644 index 0000000..34134cd --- /dev/null +++ b/02-Note/演讲与教程笔记/虚幻开放日2024/其他有价值的分享.md @@ -0,0 +1,8 @@ +# 其他有价值的分享 +- 【[UFSH2024]《三角洲行动》,诠释新一代游戏开发方式 | 王理川 天美Y1工作室技术美术组负责人/专家】 https://www.bilibili.com/video/BV18F2oYAEp2/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e +- TODO + - [x] 【[UFSH2024]虚幻引擎4移动端渲染管线改造总结分享 | 陈勇 成都西山居 引擎组组长】 https://www.bilibili.com/video/BV18F2oYAES8/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e + - [ ] 【[UFSH2024]关于程序化生成,我们还能做什么? | 周杰 徐凯鸣 腾讯IEG Global】 https://www.bilibili.com/video/BV1MP2oYhE6h/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e + - [ ] 【[UFSH2024]虚幻引擎5移动渲染管线扩展与优化 | 张锦 永航科技 引擎组负责人】 https://www.bilibili.com/video/BV1mP2oY8EBh/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e + - [ ] 【[UFSH2024]在虚幻引擎中使用移动端光追实现大世界阴影和环境光遮蔽效果 | 姚巍 陆星宇 腾讯游戏生态发展部】 https://www.bilibili.com/video/BV1mP2oY8Erq/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e + - [ ] 【[UFSH2024]0A团队享3A开发 ——像大厂一样玩转LookDev 和CFX | 高颖俊 铃空游戏 首席TA管线TD】 https://www.bilibili.com/video/BV1Vry5Y7EZY/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e \ No newline at end of file diff --git a/02-Note/演讲与教程笔记/虚幻开放日2024/虚幻引擎4移动端渲染管线改造总结分享.md b/02-Note/演讲与教程笔记/虚幻开放日2024/虚幻引擎4移动端渲染管线改造总结分享.md new file mode 100644 index 0000000..de68a7d --- /dev/null +++ b/02-Note/演讲与教程笔记/虚幻开放日2024/虚幻引擎4移动端渲染管线改造总结分享.md @@ -0,0 +1,212 @@ +# 移动端SSR +## GBuffer +- SSR计算阶段需要的WorldNormal来自GBufferA,Roughness来自GBufferB +- SSR结果转换成间接高光需要的SpecularColor来自GBufferB和GbufferC +```c++ +derived from BaseColor,Metalness,Specular +GBuffer.SpecularColor = ComputeF0(GBuffer.Specular,GBuffer.BaseColor,GBuffer.Metallic); + +``` + +MobileBasePass片段着色器额外增加一张RT--OutColorAux,rgb通道存SpecularColor,a通道存Roughness +```c++ +PIXELSHADER_EARLYDEPTHSTENCIL +void Main( + FVertexFactory InterpolantsVSTOPS Interpolants + , FMobileBasePassInterpolantsVSTOPS BasePassInterpolantts + , in float4 SvPosition:SV_Position + OPTIONAL_IsFrontFace + , out half4 OutColor : SV_Target0 + , out half4 OutColorAux : SV_Target1 +#if DEFERRED_SHADING_PATH +``` + +```c++ +OutColorAux.rgb=ShadingModelContext.Specularcolor; +OutColorAux.a=GBuffer.Roughness; +``` + +- 其中SpecularColor初始化值为计算得到的间接高光(延迟管线是在混合阶段计算) +```c++ +ShadingModelContext.SpecularColor = (DielectricSpecular -) +ShadingModelContext.SpecularColor = GetEnvBRDF(ShadingMode +``` + +## TemporalAAHistory +- TemporalAA多帧累积的SceneColor,用于射线RayCast交点的屏幕坐标采样获取颜色 +- 降噪作用(SSR默认Quality每个像素打一根Ray) +- 移植DesktopTAA替换MobileTAA(详细见图像处) + +## HZBFurthest +- 可以理解为场景深度的Mipmap,用于RayMarching求交加速。 +- 参考UE4.27移植(不是必须) + +## SSR计算 +- SpecularColor和Roughness从OutColorAux获取,WorldNormal通过SceneDepth重构获得 +```c++ +#if SHADING_PATH_DEFERRED + FGBufferData GBuffer = GetGBufferDataFromSceneTextures(UV +#else + FGBufferData GBuffer = (FGBufferData)0; + GBuffer.ShadingModelID + = SHADINGMODELID_DEFAULT_LIT; + GBuffer.WorldNormal = normalize(ReconstructNorma1FromDept + GBuffer.SpecularColor = MobileSceneColorAux.SampleLevel( + GBuffer.Roughness = MobileSceneColorAux.SampleLevel(Mobil + GBuffer.Depth = CalcSceneDepthByTexture(UV); +#endif +``` + +- SSR结果预乘SpecularColor,这样可以与SceneColorMobile做Blend One One混合 +```c++ +#if FEATURE_LEVEL == FEATURE_LEVEL_ES3_1 +Outcolor.rgb*=GBuffer.SpecularColor; +#endif +``` + +## 结论 +- 不足:重建的WorldNormal是面法线,没有延迟管线GBuffer的像素级法线,某些角度反射结果会有差异 +- 早期的方案:OutColorAux的rg通道存WorldNormal,a通道存Roughness,b通道存SpecularColor的灰度值(某些光照环境下结果不准确,放弃) + +# 实时平面反射 +平面反射与DepthPass的兼容问题修改。 +## 需求 +在包含平面反射(裁剪平面开启)的场景中,开启Full Prepass的情况下,平面反射绘制的内容出现深度遮挡错误 + +**裁剪平面** +平面反射的裁剪平面(Global Clip Plane)用于保证绘制结果的正确--那些在反射相机的视锥体内,但在反射平面下方的物体不应该参与反射,需要被剔除掉 + +**硬件实现** +默认实现是通过SV_ClipDistance语义在模型的光栅化阶段剔除,但不是所有的平台都支持,移动平台BasePass走的是PS的clip剔除 + +## 实现方法 +1. 自定义语义 +DepthOnlyVS设置ClipDistance值,通过自定义语义插值传递给片段着色器DepthOnlyPS。 +```c++ +struct FDepthonlyVSTOPS +{ +#if USE_PS_CLIP_PLANE + float OutclipDistance : OUTCLIPDIST; +#endif +``` + +2. PS剔除 +在DepthOnlyPS中用clip函数剔除(负值表示在裁剪平面以下,会被剔除) +```c++ +#if USE_PS_CLIP_PLANE + clip(Interpolants.OutClipDistance); +#endif +``` + +3. PS绑定条件 +在移动平台,当场景包含平面反射的情况下走DepthOnlyPS + +## 结论 +- Depth Pass走PS会有额外开销,但仅限场景中包含平面反射的时候,其它情况下Depth Pass仍然可以不需要PS +- 另一种修改方案:当场景中包含平面反射的时候关闭Full Prepass,在某些效果依赖Full Prepass的时候不行(详细见接下来动态阴影分享) + +# CSM策略优化 +- 移除视锥外物体的阴影渲染 + +# ModulatedShadow渲染管线改造 +## 需求 +- 在角色展示时CSM阴影精度不够,阴影效果不稳定(ViewDependentWholeScene的阴影方式) +- 解决方案:Modulated Shadow具有独立的阴影视锥和阴影深度图区域,在阴影精度方面更有优势(Per-Object的阴影方式) + +## 问题1:阴影重叠 +- Modulated Shadow独立计算各个投影物体的阴影,与SceneColorMobile相乘输出,导致投影重叠区域多次与阴影颜色相乘被压黑 +- 解决方案:增加一个中间RenderTarget,做为每个Per-Object阴影视锥的输出目标,最后对RT统一阴影颜色处理后,再与SceneColorMobile相乘输出 +## 问题2:透明物体无阴影接收 +- 阴影方式处理依赖场景深度,而透明物体不写场景深度 +- 解决方案:透明物体的阴影Receive还是走CSM +## 问题3:在MobileBasePass之后计算 +- 阴影信息需要早于MobileBassPass构造好,用于着色计算 +- 考虑过的方案:MobileBassPass用上一帧的Modulated Shadow信息,但存在阴影拖影和透明物体阴影结合的问题 +- 最终方案:参考UE4.27移植并开启Full Prepass,在MobileBassPass之前获得场景深度,构造好Modulated Shadow + +## 结论 +项目应用两套阴影方案:角色展示场景主要用Modulated Shadow,满足高精度的阴影效果需求,战斗场景用CSM,效率优先 + +# 特效性能 Separate Translucency透明渲染管线改进 +修改方案:参考非移动端做透明渲染RenderPass与MobileBasePass分离。 + +1. SeparateTranslucencyColor +申请低分辨率的RenderTarget用于透明绘制,然后Upsample到SceneColorMobile上 +2. SeparateTranslucencyDepth +SceneDepth需要跟SeparateTranslucencyColor做同比例Downsample + +注意:SceneDepth的Resolve跨RenderPass渲染目标改变,基于Memoryless的SceneDepth获取方式需要改为从Texture中获取,比如:DepthFade,LookupDeviceZ + +3. 重设SceneTextures +增加EMobileSceneTextureSetupMode去设置降分辨率后的SceneDepthTexture +```c++ +(buseSeparateTranslucencyDepth && SceneContext.SeparaateTranslucencyDepth) +SceneTextureParameters.SceneDepthTexture=GetRDG(SceneContext.Separate +``` + +## 进一步需求 +- 角色的透明材质不想受降透明分辨率影响 +1.保证角色渲染的精度;2.透明和不透明的衔接部分因为精度不一样出现裂缝问题 +## 解决方案 +- 通过扩展材质上的SeparateTranslucency的勾选项灵活控制走Normal还是SeparateTranslucencyPass +## 与其他透明的乱序问题 +- 通过角色透明写CustomeDepth,其他透明判断CustomDepth解决 + +## 结论 +- 通过透明渲染分辨率可根据机型、画质和场景的不同灵活控制特效的GPU开销 +- 透明渲染Pass拆分产生了更多的透明渲染乱序问题,通过设置Sort Priority,配合CustomDepth解决 +- SceneCapture下的透明渲染:还是走Normal Translucency (SceneCapture需要使用alpha通道) + +# 图像处理 Desktop Temporal AA移动端移植 +## 需求 +- MSAA对Depth Resolve支持的不好,无法满足渲染管线特性扩展的需求(SSPR、AO和Full Prepass等都需要Depth的Resolve) +- TemporalAA通过每帧使用不同的像素抖动Jitter,把采样结果分散到多帧,累积到History帧与当前帧混合,可以达到很好的抗锯效果 +- MobileTAA只做两帧混合,抗锯效果不够,而且没有基于Velocity的像素修正,快速移动会有鬼影(Ghosting) + +## 解决方案 +**增加Velocity Pass** +- 可移动模型:更新Primitive的LocalToWorld和PreviousLocalToWorld +- 骨骼模型:需要上一帧的骨骼矩阵计算顶点位置,使用SRV Buffer代替Uniform Buffer传递骨骼变换矩阵(UniformBuffer有大小上限) +- VS计算出顶点当前和上一帧的屏幕空间坐标,传递给PS计算差值作为Velocity输出 +```c++ +// 3d velocity,includes camera an object motion +float3 Velocity = float3(ScreenPos - PrevScreenPos, DeeviceZ - PrevDeviceZ); +``` + +**Reprojection位置纠正** +- 在后期阶段,通过变换计算当前屏幕坐标在上一帧中的屏幕坐标,再结合Velocity数据对History帧做正确采样 +```c++ +float2 BackN = PosN.xy - PrevScreen; + +BackN = DecodeVelocityFromTexture(EncodedVeloc:ty).xy; + +HistoryScreenPosition = InputParams.ScreenPoS -BackN; +``` + +## 结论 +- TAA整体抗锯效果最好,而且基于多帧的时间域实现,可以更好的与新渲染特性兼容,且对SSR起到降噪的作用 +- TAA后期位置需放在Bloom之前,避免放在Bloom之后产生的flicker +- 在后期的末端加上FXAA,弥补TAA在后期管线上靠前对有些效果(比如AfterTonemap)抗锯不生效的问题 + +# 图像处理 Mobile FSR +## 具体方案 +从UE5移植Mobile FSR 1.0,主要包含针对移动端优化的Upscale和锐化两个Pass。 + +# 3D UMG +Canvas Panel 3D +- 继承自Canvas Panel,增加透视相关参数,比如Camera的Anchor、FOV和Panel的Rotation、Offset等参数,OnPaint时转换成ViewProjection矩阵传递给Widget +- 优点:1.顶点还是2D,没有增加渲染开销;2.可在编辑器实时预览3D效果 +- 不足:只有Canvas的深度信息,无法做顶点级别的深度效果 + +## 场景交互3DUI +- 新增SeparateTranslucencyAfterPostProcess半透明材质标识,对应新增一个Mesh Pass和Processor收集此类型MeshBatch,放在Tonemap之后绘制 +- 解决默认的WidgetComponent受到Tonemap影响带来的色差问题 +- 本质上是Mesh的透明渲染,有顶点级别的深度信息,可以访问SceneDepth来实现场景交互 +## 需处理的问题 +- Tonemap之后绘制,需跳过MobileBasePass的颜色纠正和Android平台的Y轴翻转 +- TAA早于TranslucencyAfterPostprocess Pass生效,在该Pass绘制前,View的投影矩阵像素Jitter需去掉(HackRemoveTemporalAAProjectionJitter) + +## 结论 +- Canvas Panel3D类型满足最常用的界面需求;TranslucencyAfterPostprocess类型满足与场景交互的界面需求 +- 抗锯齿:Canvas Panel 3D类型通过带MSAA的中间RenderTarget方式处理;TranslucencyAfterPostprocess类型依靠后期末尾的FXAA +- 其他:使用第三方NiagaraUIRenderer插件来满足UMG上显示特效的需求 \ No newline at end of file