diff --git a/BladeSmith.sln.DotSettings.user b/BladeSmith.sln.DotSettings.user
index 58aa921..571bc59 100644
--- a/BladeSmith.sln.DotSettings.user
+++ b/BladeSmith.sln.DotSettings.user
@@ -2,4 +2,6 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
+ ForceIncluded
ForceIncluded
\ No newline at end of file
diff --git a/Content/StarterContent/Audio/Collapse01.uasset b/Content/StarterContent/Audio/Collapse01.uasset
index 9c68be4..2cfc455 100644
Binary files a/Content/StarterContent/Audio/Collapse01.uasset and b/Content/StarterContent/Audio/Collapse01.uasset differ
diff --git a/Content/StarterContent/HDRI/HDRI_Epic_Courtyard_Daylight.uasset b/Content/StarterContent/HDRI/HDRI_Epic_Courtyard_Daylight.uasset
index bc93f51..9b1f1be 100644
Binary files a/Content/StarterContent/HDRI/HDRI_Epic_Courtyard_Daylight.uasset and b/Content/StarterContent/HDRI/HDRI_Epic_Courtyard_Daylight.uasset differ
diff --git a/Shaders/DeformationCS.usf b/Shaders/DeformationCS.usf
new file mode 100644
index 0000000..3f6dcab
--- /dev/null
+++ b/Shaders/DeformationCS.usf
@@ -0,0 +1,90 @@
+// DeformationCS.usf
+
+#include "/Engine/Public/Platform.ush"
+
+// -----------------------------------------------------------------------------
+// 1. 输入输出定义
+// -----------------------------------------------------------------------------
+// 必须与 C++ 的 SHADER_PARAMETER_RDG_TEXTURE_SRV 匹配
+Texture2D InputTexture;
+// 必须与 C++ 的 SHADER_PARAMETER_RDG_TEXTURE_UAV 匹配
+RWTexture2D OutputTexture;
+
+// -----------------------------------------------------------------------------
+// 2. 参数缓冲区 (必须与 C++ FParameters 结构体严格匹配)
+// -----------------------------------------------------------------------------
+cbuffer Parameters
+{
+ float3 ImpactPoint;
+ float ImpactForce;
+ float3 ImpactNormal;
+ float DeformationRadius;
+ float Plasticity;
+ int3 TextureSize;
+
+ // 修正后的参数:对应 C++ 的 FIntVector4 UpdateRegionParam
+ // 分量顺序: (Min.X, Min.Y, Max.X, Max.Y)
+ int4 UpdateRegionParam;
+};
+
+// -----------------------------------------------------------------------------
+// 3. 线程组大小和入口点
+// -----------------------------------------------------------------------------
+#define THREADGROUP_SIZE_X 8
+#define THREADGROUP_SIZE_Y 8
+[numthreads(THREADGROUP_SIZE_X, THREADGROUP_SIZE_Y, 1)]
+void MainCompute( // 注意: 建议使用 MainCompute,如果 C++ 注册的是 MainCompute
+ uint3 GroupID : SV_GroupID,
+ uint3 GroupThreadID : SV_GroupThreadID,
+ uint3 DispatchThreadID : SV_DispatchThreadID // 全局线程 ID
+)
+{
+ // -------------------------------------------------------------------------
+ // 4. 坐标计算与边界检查
+ // -------------------------------------------------------------------------
+
+ // DispatchThreadID 从 0 开始,代表在调度区域内的偏移量。
+ // 我们将其加上 UpdateRegionParam.xy (Min.X, Min.Y) 得到全局像素坐标。
+ int2 PixelCoord = DispatchThreadID.xy + int2(UpdateRegionParam.x, UpdateRegionParam.y);
+
+ // 边界检查:检查是否超出 UpdateRegionParam.zw (Max.X, Max.Y)
+ if (PixelCoord.x < UpdateRegionParam.x || PixelCoord.x >= UpdateRegionParam.z ||
+ PixelCoord.y < UpdateRegionParam.y || PixelCoord.y >= UpdateRegionParam.w)
+ {
+ // 虽然我们调度时已经只调度了需要的区域,但为了安全起见,保留检查。
+ // 理论上,如果 C++ 端调度正确,这个检查应该很少触发。
+ return;
+ }
+
+ // -------------------------------------------------------------------------
+ // 5. 变形计算逻辑 (与之前相同)
+ // -------------------------------------------------------------------------
+
+ // 从输入纹理读取位置
+ // Load 需要 int3,第三个分量 (MipLevel) 设为 0
+ float4 OriginalPos = InputTexture.Load(int3(PixelCoord, 0));
+
+ // 计算到碰撞点的距离
+ float dist = distance(OriginalPos.xyz, ImpactPoint);
+
+ // 在变形半径内处理
+ if (dist < DeformationRadius)
+ {
+ // 计算变形衰减 (高斯衰减)
+ float falloff = exp(-(dist * dist) / (2.0 * DeformationRadius * DeformationRadius));
+
+ // 计算变形量 (考虑法线方向)
+ float3 deformation = ImpactNormal * ImpactForce * falloff * 0.01;
+
+ // 应用塑性变形
+ float3 newPos = OriginalPos.xyz + deformation * Plasticity;
+
+ // 写入新位置
+ OutputTexture[PixelCoord] = float4(newPos, OriginalPos.w);
+ }
+ else
+ {
+ // 保持原位置
+ OutputTexture[PixelCoord] = OriginalPos;
+ }
+}
\ No newline at end of file
diff --git a/Shaders/Private/DeformationCS.usf b/Shaders/Private/DeformationCS.usf
deleted file mode 100644
index 445c94b..0000000
--- a/Shaders/Private/DeformationCS.usf
+++ /dev/null
@@ -1,64 +0,0 @@
-// DeformationCS.usf
-#include "/Engine/Public/Platform.ush"
-// 输入输出定义
-Texture2D InputTexture;
-RWTexture2D OutputTexture;
-// 参数缓冲区
-cbuffer Parameters
-{
- float3 ImpactPoint;
- float ImpactForce;
- float3 ImpactNormal;
- float DeformationRadius;
- float Plasticity;
- int3 TextureSize;
- int3 UpdateRegionMin;
- int3 UpdateRegionSize;
-};
-// 线程组大小
-#define THREADGROUP_SIZE_X 8
-#define THREADGROUP_SIZE_Y 8
-[numthreads(THREADGROUP_SIZE_X, THREADGROUP_SIZE_Y, 1)]
-void MainCS(
- uint3 GroupID : SV_GroupID,
- uint3 GroupThreadID : SV_GroupThreadID,
- uint3 DispatchThreadID : SV_DispatchThreadID
-)
-{
- // 计算全局像素坐标
- int2 PixelCoord = DispatchThreadID.xy + int2(UpdateRegionMin.xy);
-
- // 检查是否在有效区域内
- if (PixelCoord.x >= UpdateRegionMin.x + UpdateRegionSize.x ||
- PixelCoord.y >= UpdateRegionMin.y + UpdateRegionSize.y)
- {
- return;
- }
-
- // 从输入纹理读取位置
- float4 OriginalPos = InputTexture.Load(int3(PixelCoord, 0));
-
- // 计算到碰撞点的距离
- float dist = distance(OriginalPos.xyz, ImpactPoint);
-
- // 在变形半径内处理
- if (dist < DeformationRadius)
- {
- // 计算变形衰减 (高斯衰减)
- float falloff = exp(-(dist * dist) / (2.0 * DeformationRadius * DeformationRadius));
-
- // 计算变形量 (考虑法线方向)
- float3 deformation = ImpactNormal * ImpactForce * falloff * 0.01;
-
- // 应用塑性变形
- float3 newPos = OriginalPos.xyz + deformation * Plasticity;
-
- // 写入新位置
- OutputTexture[PixelCoord] = float4(newPos, OriginalPos.w);
- }
- else
- {
- // 保持原位置
- OutputTexture[PixelCoord] = OriginalPos;
- }
-}
\ No newline at end of file
diff --git a/Source/BladeSmith/BladeSmith.Build.cs b/Source/BladeSmith/BladeSmith.Build.cs
index 399b74d..841e79f 100644
--- a/Source/BladeSmith/BladeSmith.Build.cs
+++ b/Source/BladeSmith/BladeSmith.Build.cs
@@ -8,6 +8,8 @@ public class BladeSmith : ModuleRules
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
+ // 如果你的模块类型是 Runtime 或 Gameplay 相关的,则添加这行:
+ // bFasterWithoutUnity = false; // 确保非 Unity 构建也能正确加载
PublicDependencyModuleNames.AddRange(new string[] {
"Core",
"CoreUObject",
@@ -16,11 +18,13 @@ public class BladeSmith : ModuleRules
"EnhancedInput",
"RenderCore",
"RHI",
+ "RenderCore",
"Renderer",
"PhysicsCore",
"AudioExtensions",
"AudioMixer",
"AudioPlatformConfiguration"
});
+
}
}
diff --git a/Source/BladeSmith/FDeformComputeShader.cpp b/Source/BladeSmith/FDeformComputeShader.cpp
index c2e9d08..2abd903 100644
--- a/Source/BladeSmith/FDeformComputeShader.cpp
+++ b/Source/BladeSmith/FDeformComputeShader.cpp
@@ -12,41 +12,7 @@
FThreadSafeDeformationParams GDeformationParams;
// 实现Compute Shader
-IMPLEMENT_GLOBAL_SHADER(FDeformationCS, "/Shaders/Private/DeformationCS.usf", "MainCS", SF_Compute);
-
-// 分派函数实现
-void FDeformationCS::Dispatch(
- FRHICommandListImmediate& RHICmdList,
- const FDeformationCSDispatchParams& Params)
-{
- // 创建参数结构
- FParameters Parameters;
- Parameters.ImpactPoint = FVector3f(Params.ImpactPoint);
- Parameters.ImpactNormal = FVector3f(Params.ImpactNormal);
- Parameters.ImpactForce = Params.ImpactForce;
- Parameters.DeformationRadius = Params.DeformationRadius;
- Parameters.Plasticity = Params.Plasticity;
- Parameters.InputTexture = Params.InputTexture;
- Parameters.OutputTexture = Params.OutputTexture;
- Parameters.TextureSize = Params.TextureSize;
- Parameters.UpdateRegionMin = FIntVector(Params.UpdateRegion.Min.X, Params.UpdateRegion.Min.Y, 0);
- Parameters.UpdateRegionSize = FIntVector(Params.UpdateRegion.Width(), Params.UpdateRegion.Height(), 1);
-
- // 计算线程组数量
- const int32 ThreadGroupSizeX = 8;
- const int32 ThreadGroupSizeY = 8;
- const int32 ThreadGroupSizeZ = 1;
-
- const int32 GroupCountX = FMath::DivideAndRoundUp(Params.UpdateRegion.Width(), ThreadGroupSizeX);
- const int32 GroupCountY = FMath::DivideAndRoundUp(Params.UpdateRegion.Height(), ThreadGroupSizeY);
- const int32 GroupCountZ = 1;
-
- // 分派Compute Shader
- TShaderMapRef ComputeShader(GetGlobalShaderMap(GMaxRHIFeatureLevel));
- SetComputePipelineState(RHICmdList, ComputeShader.GetComputeShader());
- SetShaderParameters(RHICmdList, ComputeShader, ComputeShader.GetComputeShader(), Parameters);
- RHICmdList.DispatchComputeShader(GroupCountX, GroupCountY, GroupCountZ);
-}
+IMPLEMENT_GLOBAL_SHADER(FDeformComputeShader, "/Engine/Private/MiceCola/DeformationCS.usf", "MainCompute", SF_Compute);
// 线程安全参数管理
void FThreadSafeDeformationParams::AddParams(const FDeformationCSDispatchParams& NewParams)
diff --git a/Source/BladeSmith/FDeformComputeShader.h b/Source/BladeSmith/FDeformComputeShader.h
index f77c5ff..40f45a0 100644
--- a/Source/BladeSmith/FDeformComputeShader.h
+++ b/Source/BladeSmith/FDeformComputeShader.h
@@ -1,13 +1,8 @@
#pragma once
-#include "GlobalShader.h"
-// DeformComputeShader.h
-
-// DeformationCS.h
-#pragma once
#include "CoreMinimal.h"
-#include "RHI.h"
-#include "RHIResources.h"
+#include "GlobalShader.h"
#include "ShaderParameterStruct.h"
+#include "RenderGraphUtils.h" // 必须包含
// Compute Shader参数结构体
struct FDeformationCSDispatchParams
@@ -52,43 +47,58 @@ extern FThreadSafeDeformationParams GDeformationParams;
// DeformationCS.h (续)
// Compute Shader类
-class FDeformationCS : public FGlobalShader
+class FDeformComputeShader : public FGlobalShader
{
- DECLARE_GLOBAL_SHADER(FDeformationCS);
- SHADER_USE_PARAMETER_STRUCT(FDeformationCS, FGlobalShader);
+ DECLARE_GLOBAL_SHADER(FDeformComputeShader);
+ SHADER_USE_PARAMETER_STRUCT(FDeformComputeShader, FGlobalShader);
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
// 碰撞参数
SHADER_PARAMETER(FVector3f, ImpactPoint)
- SHADER_PARAMETER(FVector3f, ImpactNormal)
SHADER_PARAMETER(float, ImpactForce)
+ SHADER_PARAMETER(FVector3f, ImpactNormal)
SHADER_PARAMETER(float, DeformationRadius)
SHADER_PARAMETER(float, Plasticity)
// 纹理参数
- SHADER_PARAMETER_TEXTURE(Texture2D, InputTexture)
- SHADER_PARAMETER_UAV(RWTexture2D, OutputTexture)
+ SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, InputTexture)
+ SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D, OutputTexture)
// 更新区域
SHADER_PARAMETER(FIntVector, TextureSize)
- SHADER_PARAMETER(FIntVector, UpdateRegionMin)
- SHADER_PARAMETER(FIntVector, UpdateRegionSize)
+ SHADER_PARAMETER(FIntVector4, UpdateRegionParam)
END_SHADER_PARAMETER_STRUCT()
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
{
- return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
+ return GetMaxSupportedFeatureLevel(Parameters.Platform) >= ERHIFeatureLevel::SM5;
}
-
+
+ // 2. ✨ 修复 Precache 错误的关键:实现 ShouldPrecachePermutation
+ // 我们告诉引擎:在开发模式下,请始终预缓存这个着色器。
+ static EShaderPermutationPrecacheRequest ShouldPrecachePermutation(const FGlobalShaderPermutationParameters& Parameters)
+ {
+ // 如果你的着色器没有使用任何模板或标志,只需返回 E_DEVELOPMENT 或 E_ALL。
+ return EShaderPermutationPrecacheRequest::Precached;
+ }
+
+
+ static bool ShouldCache(EShaderPlatform Platform)
+ {
+ return true;
+ }
+
+ // (假设你的 .usf 文件中线程组大小为 8x8x1)
+ static FIntVector GetGroupSize()
+ {
+ return FIntVector(8, 8, 1);
+ }
+
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
{
FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_X"), 8);
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_Y"), 8);
}
-
- // 分派函数
- static void Dispatch(
- FRHICommandListImmediate& RHICmdList,
- const FDeformationCSDispatchParams& Params);
+
};
\ No newline at end of file
diff --git a/Source/BladeSmith/IronBlock.cpp b/Source/BladeSmith/IronBlock.cpp
index 5ee46be..7c9f76c 100644
--- a/Source/BladeSmith/IronBlock.cpp
+++ b/Source/BladeSmith/IronBlock.cpp
@@ -2,7 +2,9 @@
#include "IronBlock.h"
-
+// 确保包含了 RDG 所需的头文件
+#include "RenderGraphBuilder.h"
+#include "RenderGraphUtils.h" // FComputeShaderUtils::AddPass
#include "FDeformComputeShader.h" // 确保这个头文件存在且包含了 FDeformationCSDispatchParams
#include "StaticMeshResources.h"
#include "TextureResource.h"
@@ -12,7 +14,6 @@
#include "Materials/MaterialInstanceDynamic.h"
#include "PhysicsEngine/BodySetup.h"
#include "RHICommandList.h"
-#include "RenderGraphBuilder.h" // 包含 FRDGBuilder
#include "Engine/Texture.h"
#include "GenericPlatform/GenericPlatformProcess.h"
@@ -328,11 +329,11 @@ void AIronBlock::ExecuteDeformationCS()
// --- 关键修复: 在游戏线程只获取 Input RHI Texture 句柄 ---
FTextureRHIRef InputRHI = GetRenderTargetRHI(ReadTarget);
+ FTextureRHIRef WriteRHI = GetRenderTargetRHI(WriteTarget); // 必须获取写入目标的RHI
- // 检查 Input RHI 和 WriteTarget UObject 是否有效
- if (!InputRHI.IsValid() || !WriteTarget)
+ if (!InputRHI.IsValid() || !WriteRHI.IsValid())
{
- UE_LOG(LogTemp, Error, TEXT("Invalid texture RHI resources or WriteTarget UObject!"));
+ UE_LOG(LogTemp, Error, TEXT("Invalid texture RHI resources!"));
return;
}
@@ -355,68 +356,87 @@ void AIronBlock::ExecuteDeformationCS()
if (UpdateRegion.Min.X >= UpdateRegion.Max.X) UpdateRegion.Max.X = UpdateRegion.Min.X + 1;
if (UpdateRegion.Min.Y >= UpdateRegion.Max.Y) UpdateRegion.Max.Y = UpdateRegion.Min.Y + 1;
- // 准备参数
- FDeformationCSDispatchParams Params;
- Params.ImpactPoint = CurrentImpactPoint; // 确保类型匹配 (FVector -> FVector3f)
- Params.ImpactNormal = CurrentImpactNormal;
- Params.ImpactForce = CurrentImpactForce;
- Params.DeformationRadius = CurrentDeformationRadius;
- Params.Plasticity = CurrentPlasticity;
- Params.InputTexture = InputRHI;
- //Params.OutputTexture = OutputUAV; // **直接使用RT的UAV**
- Params.UpdateRegion = UpdateRegion;
- Params.TextureSize = FIntVector(TexSize, TexSize, 1);
-
- // 在渲染线程中执行Compute Shader
- ENQUEUE_RENDER_COMMAND(ExecuteDeformationCS)(
- [Params, WriteTarget](FRHICommandListImmediate& RHICmdList)
+ // --- 关键修改:使用 RDG ---
+ ENQUEUE_RENDER_COMMAND(ExecuteDeformationCS_RDG)(
+ [
+ // 捕获所有需要的参数
+ InputRHI,
+ WriteRHI,
+ CurrentImpactPoint = this->CurrentImpactPoint, // 拷贝一份
+ CurrentImpactNormal = this->CurrentImpactNormal,
+ CurrentImpactForce = this->CurrentImpactForce,
+ CurrentDeformationRadius = this->CurrentDeformationRadius,
+ CurrentPlasticity = this->CurrentPlasticity,
+ UpdateRegion, //
+ TexSize //
+ ](FRHICommandListImmediate& RHICmdList)
{
- // --- 现在我们在渲染线程上 ---
+ // 1. 创建 RDG Builder
+ FRDGBuilder builder(RHICmdList);
- // 1. 从 UObject 获取 FTextureResource
- FTextureResource* RTResource = WriteTarget->GetResource();
- if (!RTResource)
+ // 2. 将我们的外部 RT 注册到 RDG 中
+ // 注意:我们使用 WriteRHI->GetDesc() 来获取纹理描述
+ FRDGTextureRef RDGReadTexture = builder.RegisterExternalTexture(
+ CreateRenderTarget(InputRHI, TEXT("DeformInputTex"))
+ );
+ FRDGTextureRef RDGWriteTexture = builder.RegisterExternalTexture(
+ CreateRenderTarget(WriteRHI, TEXT("DeformOutputTex"))
+ );
+
+ // 3. 分配着色器参数
+ FDeformComputeShader::FParameters* Params = builder.AllocParameters();
+
+ // 4. 填充 CPU 参数
+ Params->ImpactPoint = FVector3f(CurrentImpactPoint); // 注意:从 FVector 转为 FVector3f
+ Params->ImpactNormal = FVector3f(CurrentImpactNormal);
+ Params->ImpactForce = CurrentImpactForce;
+ Params->DeformationRadius = CurrentDeformationRadius;
+ Params->Plasticity = CurrentPlasticity;
+ Params->UpdateRegionParam = FIntVector4(UpdateRegion.Min.X, UpdateRegion.Min.Y, UpdateRegion.Max.X, UpdateRegion.Max.Y);
+ Params->TextureSize = FIntVector(TexSize, TexSize, 1);
+
+ // 5. ✨ 魔法发生的地方:RDG 为我们创建 SRV 和 UAV
+ // 这就是解决你 nullptr 问题的核心
+ Params->InputTexture = builder.CreateSRV(RDGReadTexture);
+ Params->OutputTexture = builder.CreateUAV(RDGWriteTexture);
+
+ // 6. 获取着色器实例
+ TShaderMapRef ComputeShader(GetGlobalShaderMap(GMaxRHIFeatureLevel));
+ if (!ComputeShader.IsValid())
{
- UE_LOG(LogTemp, Error, TEXT("Failed to get WriteTarget resource on render thread!"));
+ UE_LOG(LogTemp, Error, TEXT("FDeformComputeShader is not valid!"));
return;
}
- // 2. 转换为 FTextureRenderTargetResource
- FTextureRenderTargetResource* WriteRTResource = static_cast(RTResource);
- if (!WriteRTResource)
- {
- UE_LOG(LogTemp, Error, TEXT("Failed to cast to FTextureRenderTargetResource on render thread!"));
- return;
- }
+ // 7. 计算线程组数量
+ // (注意:你的USF需要处理 UpdateRegion,这里我们调度整个区域)
+ FIntVector NumGroups = FIntVector::DivideAndRoundUp(
+ FIntVector(UpdateRegion.Width(), UpdateRegion.Height(), 1),
+ FDeformComputeShader::GetGroupSize()
+ );
+ // 如果你的shader总是处理整个纹理,请使用:
+ // FIntVector NumGroups = FIntVector::DivideAndRoundUp(
+ // Params->TextureSize, FDeformComputeShader::GetGroupSize()
+ // );
- // 3. ✨ 在渲染线程上调用 GetRenderTargetUAV()
- FUnorderedAccessViewRHIRef OutputUAV = WriteRTResource->GetRenderTargetUAV();
+ // 8. 添加 Compute Pass
+ FComputeShaderUtils::AddPass(
+ builder,
+ RDG_EVENT_NAME("ExecuteDeformationCS"),
+ ComputeShader,
+ Params,
+ NumGroups
+ );
- // 4. 检查是否成功
- if (!OutputUAV.IsValid())
- {
- // 如果在这里仍然失败,说明 bCanCreateUAV=true 没有生效,
- // 或者 RHI 后端没有为这个 RT 创建 UAV。
- UE_LOG(LogTemp, Error, TEXT("GetRenderTargetUAV() returned null ON RENDER THREAD!"));
- return;
- }
-
- // 5. 填充参数并调度
- FDeformationCSDispatchParams RenderParams = Params;
- RenderParams.OutputTexture = OutputUAV;
-
- FDeformationCS::Dispatch(RHICmdList, RenderParams);
-
- // 6. (重要) 添加一个UAV屏障
- // 告诉GPU,Compute Shader对UAV的写入操作已完成,
- // 在下一帧中,图形管线(材质)可以安全地将其作为 SRV (TextureSample) 读取。
- RHICmdList.Transition(FRHITransitionInfo(OutputUAV, ERHIAccess::UAVCompute, ERHIAccess::SRVGraphics));
+ // 9. 执行 RDG (这会处理所有屏障和调度)
+ builder.Execute();
});
- // 等待渲染命令完成,以便在CPU上读取 (如果需要立即更新碰撞体)
- // 注意:这是一个同步点,会影响性能。
+ // --- 结束 RDG 修改 ---
+
+ // 确保渲染命令完成 (如果你需要立即更新碰撞体)
// FlushRenderingCommands();
- // UpdateCollisionAsync(UpdateRegion, WriteTarget); // 异步更新碰撞体
+ // UpdateCollisionAsync(UpdateRegion, WriteTarget);
// --- 关键修复: 更新材质参数,使其下一帧读取我们刚刚写入的纹理 ---
if (DynMaterial)