From b57516268abccf0efea9d821ba35d21ae11d3c01 Mon Sep 17 00:00:00 2001 From: BlueRose <378100977@qq.com> Date: Fri, 27 Jun 2025 11:02:45 +0800 Subject: [PATCH] vault backup: 2025-06-27 11:02:45 --- .../ShaderWorldPlugin/ShaderWorld.md | 108 +++++++++++++++++- .../卡通渲染相关资料/卡通渲染开发总览.md | 45 ++++---- 2 files changed, 128 insertions(+), 25 deletions(-) diff --git a/03-UnrealEngine/Rendering/RenderFeature/ShaderWorldPlugin/ShaderWorld.md b/03-UnrealEngine/Rendering/RenderFeature/ShaderWorldPlugin/ShaderWorld.md index e485c4c..300baeb 100644 --- a/03-UnrealEngine/Rendering/RenderFeature/ShaderWorldPlugin/ShaderWorld.md +++ b/03-UnrealEngine/Rendering/RenderFeature/ShaderWorldPlugin/ShaderWorld.md @@ -311,12 +311,16 @@ bool AShaderWorldActor::SetupCollisions() ``` #### CollisionFinalizeWork() +结束碰撞生成任务,true为完成,false为任务超时未完成。 +- TMap CollisionMesh:碰撞Name => 碰撞Mesh Map。 + - FCollisionMeshElement:管理单个碰撞数据的结构体。 + ```c++ bool AShaderWorldActor::CollisionFinalizeWork() { SCOPED_NAMED_EVENT_TEXT("AShaderWorldActor::CollisionFinalizeWork()", FColor::Magenta); SW_FCT_CYCLE() - + if (!CollisionReadToProcess.IsEmpty()) return true; @@ -324,6 +328,7 @@ bool AShaderWorldActor::CollisionFinalizeWork() double TimeStart = FPlatformTime::Seconds(); + //判断处理队列是否为空 if(CollisionWorkQueue.Num()<=0) return true; @@ -331,24 +336,117 @@ bool AShaderWorldActor::CollisionFinalizeWork() FScopeLock CollisionMeshArrayAccess(&CollisionMeshAccessLock); for (int i = CollisionWorkQueue.Num() - 1; i >= 0; i--) { + //判断生成时间是否是否超过预设数值,如果超过就直接返回。默认为1 ms。 if ((FPlatformTime::Seconds() - TimeStart) * 1000.0 > GameThreadBudget_ms) return false; + //将生成的碰撞数据赋予给对应的碰撞Mesh,最后移除任务队列中的任务。 FCollisionProcessingWork& Work = CollisionWorkQueue[i]; - ensure(CollisionMesh.Find(Work.MeshID)); - FCollisionMeshElement& Mesh = CollisionMesh[Work.MeshID]; - Mesh.Mesh->UpdateSectionTriMesh(Work.DestB); - CollisionWorkQueue.RemoveAt(i); } } CollisionWorkQueue.Empty(); return true; +} +void UShaderWorldCollisionComponent::UpdateSectionTriMesh(TSharedPtr& Positions) +{ + //UBodySetup + if (AsyncBodySetupQueue.Num() > 0) + { +#if SWDEBUG + SW_LOG("Collision Update received during alreayd occuring computation %s",*GetName()) +#endif + + UpdatesReceivedDuringCompute.Add(Positions); + + return; + } + + UpdatesReceivedDuringCompute.Empty(); + + + bool EnsureSameBuffers = ProcMeshSections.Num() > 0 && ProcMeshSections[0].PositionBuffer.IsValid() && (ProcMeshSections[0].PositionBuffer->Positions3f.Num() == 0 || ProcMeshSections[0].PositionBuffer->Positions3f.Num() == Positions->Positions.Num()); + if(!EnsureSameBuffers) + { +#if SWDEBUG + UE_LOG(LogTemp,Warning,TEXT("Error UpdateSectionTriMesh : buffers incompatible")); +#endif + + } + else + { + ProcMeshSections[0].PositionBuffer.Reset(); + ProcMeshSections[0].Normals.Reset(); + + ProcMeshSections[0].PositionBuffer = Positions; + ProcMeshSections[0].SectionLocalBox = Positions->Bound; + ProcMeshSections[0].bEnableCollision = true; + + Async(EAsyncExecution::TaskGraph, [WeakThis = MakeWeakObjectPtr(this), PBuffer = Positions, IndexB = ProcMeshSections[0].IndexBuffer] + { + TSharedPtr, ESPMode::ThreadSafe> Normals = SWComputeNormalsForPatch(PBuffer, IndexB); + + AsyncTask(ENamedThreads::GameThread, [WeakThis,PBuffer, Normals]() + { + if (WeakThis.IsValid()) + { + if (UShaderWorldCollisionComponent* Comp = Cast(WeakThis.Get())) + { + if(IsValid(Comp)) + Comp->ReceiveComputedNormals(PBuffer, Normals); + } + } + }); + }); + } + + //Materials + // Pass new positions to trimesh + UpdateCollision(); + UpdateLocalBounds(); // Update overall bounds + UpdateNavigation(); + + if (ProcMeshSections.Num() > 0 && (ProcMeshSections[0].bSectionVisible || (GetWorld() && !GetWorld()->IsGameWorld()))) + { + // If we have a valid proxy and it is not pending recreation + if (SceneProxy && !IsRenderStateDirty()) + { + //SW_LOG("Update trimesh SceneProxy && !IsRenderStateDirty()") + // Create data to update section + FShaderWColProcMeshSectionUpdateData* SectionData = new FShaderWColProcMeshSectionUpdateData; + SectionData->TargetSection = 0; + SectionData->NewPositionBuffer = ProcMeshSections[0].PositionBuffer; + + if(AShaderWorldActor* owner = Cast(GetOwner())) + { + { + // Enqueue command to send to render thread + FShaderWProceduralMeshSceneProxy* ProcMeshSceneProxy = (FShaderWProceduralMeshSceneProxy*)(SceneProxy && !IsRenderStateDirty() ? SceneProxy : nullptr); + ENQUEUE_RENDER_COMMAND(FGeoCProcMeshSectionUpdate) + ([ProcMeshSceneProxy, SectionData](FRHICommandListImmediate& RHICmdList) + { + if(ProcMeshSceneProxy) + ProcMeshSceneProxy->UpdateSection_RenderThread(SectionData); + }); + } + } + else + { + //SW_LOG("Update trimesh !owner") + } + } + else + { + //SW_LOG("Update trimesh !(SceneProxy && !IsRenderStateDirty())") + } + + MarkRenderTransformDirty(); + } } ``` ### SpawnablesManagement() diff --git a/03-UnrealEngine/卡通渲染相关资料/卡通渲染开发总览.md b/03-UnrealEngine/卡通渲染相关资料/卡通渲染开发总览.md index a033221..0c9809d 100644 --- a/03-UnrealEngine/卡通渲染相关资料/卡通渲染开发总览.md +++ b/03-UnrealEngine/卡通渲染相关资料/卡通渲染开发总览.md @@ -164,11 +164,16 @@ rating: ⭐⭐⭐ 3. [ ] [GDC2025 : Generalized Stylized Post Processing Outline](https://zhuanlan.zhihu.com/p/1895785690161198348) 16. [ ] [[Toon多光源参考|Toon多光源后处理Pass]] 17. [ ] [【虚幻5】UE_动画变形工具(晶格变形)](https://www.bilibili.com/video/BV1DsR3YoEML/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e) -18. [ ] 月下幻影的掰法线思路:`N = _Scale * NoL * L + N`尝试找到使用场景。资产路径`/Game/ToonContentExample/MaterialUtility/NormalOffsetToDirectionalLight/M_NormalOffsetToDirectionalLight` -19. [ ] RGS 光线追踪与路径追踪支持。 +18. [ ] +19. [ ] 掰法线相关 + 1. [ ] 【Blender插件 Easy Custom Normals V1.1.0汉化版,卡通渲染优化利器!-哔哩哔哩】 https://b23.tv/meLiEkj + 1. [ ] https://superhivemarket.com/products/stylized-normals + 2. [ ] https://tools.fondant.gg/ + 2. [ ] 月下幻影的掰法线思路:`N = _Scale * NoL * L + N`尝试找到使用场景。资产路径`/Game/ToonContentExample/MaterialUtility/NormalOffsetToDirectionalLight/M_NormalOffsetToDirectionalLight` +20. [ ] RGS 光线追踪与路径追踪支持。 1. [ ] [【UE5】通过Raytracing自定义卡通渲染投影](https://zhuanlan.zhihu.com/p/688722298) https://zhuanlan.zhihu.com/p/688722298 -20. [ ] 给EditorView添加卡通渲染用场景,默认场景的渲染效果对不上。 -21. [ ] 实现前向混合管线?思路有2:1. Material直接计算光照结果。2. 自定义ToonBasePass到LightingPass后,复制阴影贴图与Lumen渲染结果进行Composition。 +21. [ ] 给EditorView添加卡通渲染用场景,默认场景的渲染效果对不上。 +22. [ ] 实现前向混合管线?思路有2:1. Material直接计算光照结果。2. 自定义ToonBasePass到LightingPass后,复制阴影贴图与Lumen渲染结果进行Composition。 1. 原神早期的方案: 1. 渲染地形(远景 2. @@ -179,37 +184,37 @@ rating: ⭐⭐⭐ 6. 渲染深度与法线Buffer。 7. 渲染级联阴影。 8. 合成,阴影与环境光照(AO、环境探针)。 -22. [ ] 云彩生成器 +23. [ ] 云彩生成器 1. [ ] https://www.bilibili.com/video/BV1L5kdYFEXc/?spm_id_from=333.1007.tianma.4-1-11.click&vd_source=d47c0bb42f9c72fd7d74562185cee290 2. [ ] 风格化水面资产 https://item.taobao.com/item.htm?id=865360489543&pisk=gLHsX7NMiNb1gB7njFKURXly5Dwb5q9y1iZxqmBNDReTkigKDtQA6-FLJorOMSU2sqNju2VxQRoZRGDIPtWwSCmAh-yvzUJyUcman-Lyk8kOUGq4mNUAurCKv-rjPdNAXcmgnrIFkQlKjZg5RK5YDrKQpor7k-EYW9KQcuaYHPFAJ6E8JrexkSIdJuZ5MZCTHkKQju5OBoeYvMEaVtBtk-KIvyqxnDXQDCZ-fHz1qUDkpeKgJtBxdlNpTcUKrr-4i5TjbyXvy1Zg1coTRtBxKXkPllz9ZMz0QPDbfqvlIRFjTAVoQeBsl20KBSDp8B00QuV-MD-lTPDIQvFsCU1uCX3nd5DOWhqtsqDbQx71hDMb57HTOKx0CDEYdbneq6zidAkL1AT5ZPMiDjPItNTUuboEBWgJ89g0GXkgZA8dC4IyzTz7sJ5fA7XbAz-BAsf0xzPwqJ_edaNTxlTyAH_Gi5E3AmtBAsDg6kqF6HtCWc1..&spm=a21xtw.29178619.product_shelf.74.41727d6dRCDvul -23. [ ] 添加Debug View https://zhuanlan.zhihu.com/p/668782106 -24. [ ] [_UE5_ Shader Print系统](https://zhuanlan.zhihu.com/p/637929634) -25. [ ] GBufferView实现。 -26. [ ] Toon Debug模式,可以让美术在材质进行进行简单的光照计算。 -27. [ ] ToonShadow +24. [ ] 添加Debug View https://zhuanlan.zhihu.com/p/668782106 +25. [ ] [_UE5_ Shader Print系统](https://zhuanlan.zhihu.com/p/637929634) +26. [ ] GBufferView实现。 +27. [ ] Toon Debug模式,可以让美术在材质进行进行简单的光照计算。 +28. [ ] ToonShadow 1. ![[星穹铁道中下巴阴影处理.png]] 2. [ ] ToonSDFShadow 1. [ ] TODO: SDF贴图工具? -28. [ ] LookDev场景 +29. [ ] LookDev场景 1. [ ] https://zhuanlan.zhihu.com/p/394608910 -29. [ ] 考虑往GBuffer中添加更多数据(考虑Velocity以及SingleLayerWater) +30. [ ] 考虑往GBuffer中添加更多数据(考虑Velocity以及SingleLayerWater) 1. ShaderMaterialDerivedHelpers.cpp(Shader宏)、GBufferInfo.cpp(GBuffer格式)BasePassRendering.cpp(950行,SingleLayerWater写入GBuffer格式相关) 2. 确定一下SingleLayerWater中VSMFiter与DistanceFieldShadow对渲染结果的影响,之后在文档中说明。 -30. [ ] 修复SIngleLayerWater的缩略图渲染渲染错误(双击会有一瞬间的错误产生) -31. [ ] 添加对应的Stat https://zhuanlan.zhihu.com/p/716644594 -32. [ ] ToonLumen、GI以及晕染效果实现。![[卡通渲染晕染效果.mp4]] -33. [ ] 在材质中实现ToonEye相关效果 +31. [ ] 修复SIngleLayerWater的缩略图渲染渲染错误(双击会有一瞬间的错误产生) +32. [ ] 添加对应的Stat https://zhuanlan.zhihu.com/p/716644594 +33. [ ] ToonLumen、GI以及晕染效果实现。![[卡通渲染晕染效果.mp4]] +34. [ ] 在材质中实现ToonEye相关效果 1. 【二次元人物眼睛如何变形?】 https://www.bilibili.com/video/BV14M4m1y71A/?share_source=copy_web&vd_source=fe8142e8e12816535feaeabd6f6cdc8e 1. 原视频 https://www.youtube.com/watch?v=euIyX9v8rvw 2. 眼睛建模 https://youtu.be/s2_7Q2IIvNY?si=fWiYjqcLFXzdeQ-B&t=126 -34. 尝试实现Forward+ +35. 尝试实现Forward+ 1. BasePass https://zhuanlan.zhihu.com/p/618698467 -35. DX11问题修复 +36. DX11问题修复 1. [x] ToonOutline SceneColorTexture为空的问题。 **DX11限制,必须CopyTexture** -36. 卡通渲染针对TAA的优化思路 https://zhuanlan.zhihu.com/p/678876237 +37. 卡通渲染针对TAA的优化思路 https://zhuanlan.zhihu.com/p/678876237 1. https://www.bilibili.com/video/BV1BK411v7FY/?spm_id_from=333.788&vd_source=ea6df38502a795b7533aa33b78bf1159 2. https://zhuanlan.zhihu.com/p/20786650 -37. [ ] Unreal Engine 5.4 Scene Extension https://zhuanlan.zhihu.com/p/706268007 +38. [ ] Unreal Engine 5.4 Scene Extension https://zhuanlan.zhihu.com/p/706268007 1. [ ] 通过SceneExtension改进ToonObjectID,这样可以减少对应ToonBuffer的精度来存其他数据。 2. [ ] https://www.bilibili.com/video/BV1fM4m1U7Tp/