From 7a7ce4a596574608e13c79ad9e809d767af9e4f2 Mon Sep 17 00:00:00 2001 From: BlueRose <378100977@qq.com> Date: Mon, 14 Jul 2025 22:20:22 +0800 Subject: [PATCH] vault backup: 2025-07-14 22:20:22 --- .../ShaderWorldPlugin/ShaderWorld.md | 151 ++++++++++++++++++ 1 file changed, 151 insertions(+) diff --git a/03-UnrealEngine/Rendering/RenderFeature/ShaderWorldPlugin/ShaderWorld.md b/03-UnrealEngine/Rendering/RenderFeature/ShaderWorldPlugin/ShaderWorld.md index 5a4a5b0..a63e781 100644 --- a/03-UnrealEngine/Rendering/RenderFeature/ShaderWorldPlugin/ShaderWorld.md +++ b/03-UnrealEngine/Rendering/RenderFeature/ShaderWorldPlugin/ShaderWorld.md @@ -641,6 +641,157 @@ bool AShaderWorldActor::CollisionPreprocessGPU() ``` + +#### CollisionGPU() +```c++ + +void AShaderWorldActor::CollisionGPU() +{ + SCOPED_NAMED_EVENT_TEXT("AShaderWorldActor::CollisionGPU()", FColor::Magenta); + SW_FCT_CYCLE() + + double CurrentTime = FPlatformTime::Seconds(); + + + if (!(!(*bPreprocessingCollisionUpdate.Get()) && ( + CollisionShareable->CollisionMeshToUpdate.Num() > 0 || + CollisionShareable->CollisionMeshToRenameMoveUpdate.Num() > 0 || + CollisionShareable->CollisionMeshToCreate.Num() > 0))) + { + /* + * No collision Preprocessing running, we can safely access the data in the shared pointer without risking race condition + * 确保没有PreprocessingCollision任务在运行 + */ + if(!(*bPreprocessingCollisionUpdate.Get())) + { + FScopeLock CollisionMeshArrayAccess(CollisionMeshAccessLock.Get()); + + TArray NameToRemove; + //遍历AvailableCollisionMesh + for (const FName& AvailableID : CollisionShareable->AvailableCollisionMesh) + { + FCollisionMeshElement& Elem = *CollisionMesh.Find(AvailableID); + //更新时间戳 + if (Elem.SleepTime < 0.0) + Elem.SleepTime = CurrentTime; + else if ((abs(CurrentTime - Elem.SleepTime) >= 1.0) && (CollisionBufferHolder == "" || AvailableID != CollisionBufferHolder) && (!Elem.Mesh || (Elem.Mesh && !Elem.Mesh->HasAsyncWorkPending()))) + { + if (IsValid(Elem.Mesh)) + Elem.Mesh->DestroyComponent(); + + Elem.Mesh = nullptr; + + DecountRTAllocatedMemory(Elem.CollisionRT) + DecountRTAllocatedMemory(Elem.CollisionRT_Duplicate) + + Elem.CollisionRT = nullptr; + Elem.CollisionRT_Duplicate = nullptr; + Elem.DynCollisionCompute = nullptr; + Elem.LayerComputeForPhysicalMaterial.Empty(); + + CollisionMesh.Remove(AvailableID); + + if (UsedCollisionMesh.Contains(AvailableID)) + { + UsedCollisionMesh.Remove(AvailableID); + } + + CollisionShareable->CollisionMeshData.Remove(AvailableID); + CollisionShareable->UsedCollisionMesh.Remove(AvailableID); + NameToRemove.Add(AvailableID); + } + else + { + } + } + for (auto& TR : NameToRemove) + { + CollisionShareable->AvailableCollisionMesh.Remove(TR); + } + } + + return; + } + + + + UWorld* World = GetWorld(); + + bool RequireRenderFence = false; + int32 CollisionDrawCallCount = 0; + + + UsedCollisionMesh = CollisionShareable->UsedCollisionMesh; + + /* + * Async task created proxy CollisionMesh and associated IDs to them, create actual GameThread collision using the provided IDs + */ + for (FName& ID : CollisionShareable->CollisionMeshToCreate) + { + const FSWCollisionMeshElemData& Mesh_Shareable = *CollisionShareable->CollisionMeshData.Find(ID); + + FCollisionMeshElement& Mesh = GetACollisionMesh(ID); + + Mesh.Location = Mesh_Shareable.Location; + Mesh.MeshLocation = Mesh_Shareable.MeshLocation; + + Mesh.Mesh->SetWorldTransform(FTransform(Mesh_Shareable.MeshLocation)); + Mesh.Mesh->SetCollisionProfileName(UCollisionProfile::BlockAll_ProfileName); + Mesh.Mesh->Mobility = EComponentMobility::Static; + } + + CollisionShareable->CollisionMeshToCreate.Empty(); + + + for (int i = CollisionShareable->CollisionMeshToUpdate.Num() - 1; i >= 0; i--) + { + FName& CollisionIDToUpdate = CollisionShareable->CollisionMeshToUpdate[i]; + FCollisionMeshElement& El = *CollisionMesh.Find(CollisionIDToUpdate); + UpdateCollisionMeshData(El); + + CollisionShareable->CollisionMeshToUpdate.RemoveAt(i); + + RequireRenderFence = true; + CollisionDrawCallCount++; + + if (CollisionDrawCallCount >= CollisionMaxDrawCallPerFrame) + break; + } + + for (int i = CollisionShareable->CollisionMeshToRenameMoveUpdate.Num() - 1; i >= 0; i--) + { + FName& CollisionIDToUpdate = CollisionShareable->CollisionMeshToRenameMoveUpdate[i]; + + ensure(CollisionMesh.Find(CollisionIDToUpdate) != nullptr); + ensure(CollisionShareable->CollisionMeshData.Find(CollisionIDToUpdate) != nullptr); + + FCollisionMeshElement& El = *CollisionMesh.Find(CollisionIDToUpdate); + const FSWCollisionMeshElemData& El_Shareable = *CollisionShareable->CollisionMeshData.Find(CollisionIDToUpdate); + + El.Location = El_Shareable.Location; + El.MeshLocation = El_Shareable.MeshLocation; + + El.Mesh->SetLocationOnPhysicCookComplete(El.MeshLocation); + + UpdateCollisionMeshData(El); + + CollisionShareable->CollisionMeshToRenameMoveUpdate.RemoveAt(i); + + RequireRenderFence = true; + CollisionDrawCallCount++; + + if (CollisionDrawCallCount >= CollisionMaxDrawCallPerFrame) + break; + } + + if (RequireRenderFence) + { + CollisionProcess.BeginFence(); + } + +} +``` + ### ```c++ void AShaderWorldActor::CollisionCPU()