diff --git a/BladeSmith.sln.DotSettings.user b/BladeSmith.sln.DotSettings.user
index d87c8ec..7b4f914 100644
--- a/BladeSmith.sln.DotSettings.user
+++ b/BladeSmith.sln.DotSettings.user
@@ -2,6 +2,7 @@
ForceIncluded
ForceIncluded
ForceIncluded
+ ForceIncluded
ForceIncluded
ForceIncluded
ForceIncluded
diff --git a/Content/Maps/Demo.umap b/Content/Maps/Demo.umap
index d24cbc5..c9eb402 100644
Binary files a/Content/Maps/Demo.umap and b/Content/Maps/Demo.umap differ
diff --git a/Source/BladeSmith/Shaders/FTemperatureComputeShader.cpp b/Plugins/MiceShaders/Source/MiceShaders/Private/FTemperatureComputeShader.cpp
similarity index 100%
rename from Source/BladeSmith/Shaders/FTemperatureComputeShader.cpp
rename to Plugins/MiceShaders/Source/MiceShaders/Private/FTemperatureComputeShader.cpp
diff --git a/Source/BladeSmith/Shaders/FTemperatureComputeShader.h b/Plugins/MiceShaders/Source/MiceShaders/Public/FTemperatureComputeShader.h
similarity index 92%
rename from Source/BladeSmith/Shaders/FTemperatureComputeShader.h
rename to Plugins/MiceShaders/Source/MiceShaders/Public/FTemperatureComputeShader.h
index fecad12..f7bf1f0 100644
--- a/Source/BladeSmith/Shaders/FTemperatureComputeShader.h
+++ b/Plugins/MiceShaders/Source/MiceShaders/Public/FTemperatureComputeShader.h
@@ -8,7 +8,7 @@
/**
* 温度传导计算着色器的调度参数
*/
-struct BLADESMITH_API FTemperatureCSDispatchParams
+struct MICESHADERS_API FTemperatureCSDispatchParams
{
// 体素网格分辨率
FIntVector VoxelResolution;
@@ -42,7 +42,7 @@ struct BLADESMITH_API FTemperatureCSDispatchParams
/**
* 线程安全的温度计算参数队列
*/
-struct FThreadSafeTemperatureParams
+struct MICESHADERS_API FThreadSafeTemperatureParams
{
FCriticalSection ParamsCriticalSection;
TArray PendingParams;
@@ -52,12 +52,12 @@ struct FThreadSafeTemperatureParams
};
// 全局参数存储
-extern BLADESMITH_API FThreadSafeTemperatureParams GTemperatureParams;
+extern MICESHADERS_API FThreadSafeTemperatureParams GTemperatureParams;
/**
* 温度传导计算着色器类
*/
-class BLADESMITH_API FTemperatureComputeShader : public FGlobalShader
+class MICESHADERS_API FTemperatureComputeShader : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FTemperatureComputeShader);
SHADER_USE_PARAMETER_STRUCT(FTemperatureComputeShader, FGlobalShader);
diff --git a/Source/BladeSmith/DynamicIronBlock.cpp b/Source/BladeSmith/DynamicIronBlock.cpp
index b3e367f..dae9ba0 100644
--- a/Source/BladeSmith/DynamicIronBlock.cpp
+++ b/Source/BladeSmith/DynamicIronBlock.cpp
@@ -13,8 +13,8 @@
#include "GeometryScript/MeshNormalsFunctions.h"
#include "Materials/MaterialInstanceDynamic.h"
-// GPU计算相关
-#include "Shaders/FTemperatureComputeShader.h"
+// GPU计算相关(从MiceShaders插件引用)
+#include "FTemperatureComputeShader.h"
#include "RHI.h"
#include "RHIResources.h"
#include "RHICommandList.h"
@@ -23,6 +23,8 @@
#include "GlobalShader.h"
#include "ShaderParameterStruct.h"
#include "RHIStaticStates.h"
+#include "ShaderCompilerCore.h"
+#include "ShaderCore.h"
ADynamicIronBlock::ADynamicIronBlock()
{
@@ -39,7 +41,8 @@ ADynamicIronBlock::ADynamicIronBlock()
void ADynamicIronBlock::BeginPlay()
{
Super::BeginPlay();
-
+ // 初始化 Box 网格
+ InitializeBoxMesh();
// 创建GPU缓冲区
if (bEnableTemperatureSystem && TemperatureGrid.Num() > 0)
{
@@ -57,6 +60,12 @@ void ADynamicIronBlock::Tick(float DeltaTime)
return;
}
+ // 检查GPU缓冲区是否准备好
+ if (!bGPUBuffersReady.load(std::memory_order_acquire))
+ {
+ return;
+ }
+
// 累积时间
TimeSinceLastUpdate += DeltaTime;
@@ -88,7 +97,7 @@ void ADynamicIronBlock::OnConstruction(const FTransform& Transform)
Super::OnConstruction(Transform);
// 初始化 Box 网格
- InitializeBoxMesh();
+ //InitializeBoxMesh();
}
void ADynamicIronBlock::InitializeBoxMesh()
@@ -684,11 +693,11 @@ void ADynamicIronBlock::CreateGPUBuffers()
ENQUEUE_RENDER_COMMAND(CreateTemperatureBuffers)(
[this, TotalVoxels, BufferSize, FlagsBufferSize](FRHICommandListImmediate& RHICmdList)
{
- // 创建温度缓冲A
+ // 创建温度缓冲A(使用ByteAddressBuffer而非StructuredBuffer)
FRHIBufferCreateDesc TempBufferADesc;
TempBufferADesc.DebugName = TEXT("TemperatureBufferA");
TempBufferADesc.Size = BufferSize;
- TempBufferADesc.Usage = BUF_StructuredBuffer | BUF_ShaderResource | BUF_UnorderedAccess;
+ TempBufferADesc.Usage = BUF_ShaderResource | BUF_UnorderedAccess;
TempBufferADesc.InitialState = ERHIAccess::UAVCompute;
TemperatureBufferA = RHICmdList.CreateBuffer(TempBufferADesc);
TemperatureUAV_A = RHICmdList.CreateUnorderedAccessView(TemperatureBufferA, FRHIViewDesc::CreateBufferUAV().SetType(FRHIViewDesc::EBufferType::Typed).SetFormat(PF_R32_FLOAT));
@@ -698,7 +707,7 @@ void ADynamicIronBlock::CreateGPUBuffers()
FRHIBufferCreateDesc TempBufferBDesc;
TempBufferBDesc.DebugName = TEXT("TemperatureBufferB");
TempBufferBDesc.Size = BufferSize;
- TempBufferBDesc.Usage = BUF_StructuredBuffer | BUF_ShaderResource | BUF_UnorderedAccess;
+ TempBufferBDesc.Usage = BUF_ShaderResource | BUF_UnorderedAccess;
TempBufferBDesc.InitialState = ERHIAccess::UAVCompute;
TemperatureBufferB = RHICmdList.CreateBuffer(TempBufferBDesc);
TemperatureUAV_B = RHICmdList.CreateUnorderedAccessView(TemperatureBufferB, FRHIViewDesc::CreateBufferUAV().SetType(FRHIViewDesc::EBufferType::Typed).SetFormat(PF_R32_FLOAT));
@@ -708,7 +717,7 @@ void ADynamicIronBlock::CreateGPUBuffers()
FRHIBufferCreateDesc PlasticityBufferDesc;
PlasticityBufferDesc.DebugName = TEXT("PlasticityBuffer");
PlasticityBufferDesc.Size = BufferSize;
- PlasticityBufferDesc.Usage = BUF_StructuredBuffer | BUF_ShaderResource | BUF_UnorderedAccess;
+ PlasticityBufferDesc.Usage = BUF_ShaderResource | BUF_UnorderedAccess;
PlasticityBufferDesc.InitialState = ERHIAccess::UAVCompute;
PlasticityBuffer = RHICmdList.CreateBuffer(PlasticityBufferDesc);
PlasticityUAV = RHICmdList.CreateUnorderedAccessView(PlasticityBuffer, FRHIViewDesc::CreateBufferUAV().SetType(FRHIViewDesc::EBufferType::Typed).SetFormat(PF_R32_FLOAT));
@@ -717,18 +726,28 @@ void ADynamicIronBlock::CreateGPUBuffers()
FRHIBufferCreateDesc FlagsBufferDesc;
FlagsBufferDesc.DebugName = TEXT("SurfaceVoxelFlagsBuffer");
FlagsBufferDesc.Size = FlagsBufferSize;
- FlagsBufferDesc.Usage = BUF_StructuredBuffer | BUF_ShaderResource;
+ FlagsBufferDesc.Usage = BUF_ShaderResource;
FlagsBufferDesc.InitialState = ERHIAccess::SRVCompute;
SurfaceVoxelFlagsBuffer = RHICmdList.CreateBuffer(FlagsBufferDesc);
SurfaceVoxelSRV = RHICmdList.CreateShaderResourceView(SurfaceVoxelFlagsBuffer, FRHIViewDesc::CreateBufferSRV().SetType(FRHIViewDesc::EBufferType::Typed).SetFormat(PF_R32_UINT));
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock: GPU buffers created (%d voxels, %.2f MB)"),
TotalVoxels, (BufferSize * 3 + FlagsBufferSize) / (1024.0f * 1024.0f));
+
+ // 通知游戏线程缓冲区已准备好
+ AsyncTask(ENamedThreads::GameThread, [this]()
+ {
+ bGPUBuffersReady.store(true, std::memory_order_release);
+ UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock: GPU buffers ready for use"));
+ });
});
}
void ADynamicIronBlock::ReleaseGPUBuffers()
{
+ // 先标记缓冲区为未准备状态,防止Tick中继续使用
+ bGPUBuffersReady.store(false, std::memory_order_release);
+
ENQUEUE_RENDER_COMMAND(ReleaseTemperatureBuffers)(
[this](FRHICommandListImmediate& RHICmdList)
{
@@ -840,33 +859,111 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
return;
}
- // 准备调度参数
- FTemperatureCSDispatchParams Params;
- Params.VoxelResolution = TemperatureResolution;
- Params.ThermalConductivity = ThermalConductivity;
- Params.CoolingRate = CoolingRate;
- Params.AmbientTemperature = AmbientTemperature;
- Params.ForgeTemperatureMin = ForgeTemperatureMin;
- Params.ForgeTemperatureMax = ForgeTemperatureMax;
- Params.DeltaTime = DeltaTime;
+ // 准备调度参数(捕获到lambda中)
+ FIntVector Resolution = TemperatureResolution;
+ float Conductivity = ThermalConductivity;
+ float Cooling = CoolingRate;
+ float Ambient = AmbientTemperature;
+ float ForgeMin = ForgeTemperatureMin;
+ float ForgeMax = ForgeTemperatureMax;
- // Ping-Pong缓冲区
- Params.InputTemperatureBuffer = bUseBufferA ? TemperatureBufferA : TemperatureBufferB;
- Params.OutputTemperatureUAV = bUseBufferA ? TemperatureUAV_B : TemperatureUAV_A;
- Params.SurfaceVoxelFlagsBuffer = SurfaceVoxelFlagsBuffer;
- Params.OutputPlasticityUAV = PlasticityUAV;
+ // Ping-Pong缓冲区引用
+ FBufferRHIRef InputBuffer = bUseBufferA ? TemperatureBufferA : TemperatureBufferB;
+ FBufferRHIRef OutputBuffer = bUseBufferA ? TemperatureBufferB : TemperatureBufferA;
+ FBufferRHIRef FlagsBuffer = SurfaceVoxelFlagsBuffer;
+ FBufferRHIRef PlasticityBuf = PlasticityBuffer;
- // 保存当前bUseBufferA状态用于Lambda
- bool bCurrentUseBufferA = bUseBufferA;
+ // 创建SRV/UAV(在游戏线程创建,捕获到lambda)
+ FShaderResourceViewRHIRef InputSRV = TemperatureSRV_A;
+ FShaderResourceViewRHIRef InputSRV_B = TemperatureSRV_B;
+ FShaderResourceViewRHIRef FlagsSRV = SurfaceVoxelSRV;
+ FUnorderedAccessViewRHIRef OutputUAV_A = TemperatureUAV_A;
+ FUnorderedAccessViewRHIRef OutputUAV_B = TemperatureUAV_B;
+ FUnorderedAccessViewRHIRef PlasticityUAV_Ref = PlasticityUAV;
- // 切换缓冲区
+ bool bReadFromA = bUseBufferA;
+
+ // 切换缓冲区(下次Tick使用新的缓冲区)
bUseBufferA = !bUseBufferA;
- // 调度GPU计算(使用RDG)
+ // 调度GPU计算(直接使用RHI,不用RDG)
ENQUEUE_RENDER_COMMAND(DispatchTemperatureCS)(
- [Params, bCurrentUseBufferA](FRHICommandListImmediate& RHICmdList)
+ [Resolution, Conductivity, Cooling, Ambient, ForgeMin, ForgeMax, DeltaTime,
+ InputBuffer, OutputBuffer, FlagsBuffer, PlasticityBuf,
+ InputSRV, InputSRV_B, FlagsSRV, OutputUAV_A, OutputUAV_B, PlasticityUAV_Ref, bReadFromA]
+ (FRHICommandListImmediate& RHICmdList)
{
- // 暂时简化实现,跳过GPU计算
- UE_LOG(LogTemp, Warning, TEXT("DynamicIronBlock: GPU temperature compute temporarily disabled (API compatibility)"));
+ // 检查ShaderMap是否有效
+ FGlobalShaderMap* ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel);
+ if (!ShaderMap)
+ {
+ UE_LOG(LogTemp, Error, TEXT("DynamicIronBlock: Global ShaderMap is null!"));
+ return;
+ }
+
+ // 获取Compute Shader并检查是否有效
+ TShaderMapRef ComputeShader(ShaderMap);
+ if (!ComputeShader.IsValid())
+ {
+ UE_LOG(LogTemp, Error, TEXT("DynamicIronBlock: FTemperatureComputeShader not found in ShaderMap! Make sure the shader is compiled."));
+ return;
+ }
+
+ // 使用RDG(简化版本 - 创建临时缓冲区)
+ FRDGBuilder GraphBuilder(RHICmdList, RDG_EVENT_NAME("TemperatureConduction"));
+
+ // 创建RDG缓冲区描述
+ FRDGBufferDesc TempBufferDesc = FRDGBufferDesc::CreateBufferDesc(sizeof(float), InputBuffer->GetSize() / sizeof(float));
+ FRDGBufferDesc FlagsBufferDesc = FRDGBufferDesc::CreateBufferDesc(sizeof(uint32), FlagsBuffer->GetSize() / sizeof(uint32));
+
+ // 创建RDG缓冲区
+ FRDGBufferRef InputTempRDG = GraphBuilder.CreateBuffer(TempBufferDesc, TEXT("InputTemperatureBuffer"));
+ FRDGBufferRef OutputTempRDG = GraphBuilder.CreateBuffer(TempBufferDesc, TEXT("OutputTemperatureBuffer"));
+ FRDGBufferRef FlagsRDG = GraphBuilder.CreateBuffer(FlagsBufferDesc, TEXT("SurfaceVoxelFlagsBuffer"));
+ FRDGBufferRef PlasticityRDG = GraphBuilder.CreateBuffer(TempBufferDesc, TEXT("PlasticityBuffer"));
+
+ // TODO: 添加数据复制Pass(从RHI到RDG)
+ // 暂时跳过,shader会处理未初始化数据
+
+ // 设置Shader参数
+ FTemperatureComputeShader::FParameters* PassParameters = GraphBuilder.AllocParameters();
+ PassParameters->VoxelResolution = Resolution;
+ PassParameters->ThermalConductivity = Conductivity;
+ PassParameters->CoolingRate = Cooling;
+ PassParameters->AmbientTemperature = Ambient;
+ PassParameters->ForgeTemperatureMin = ForgeMin;
+ PassParameters->ForgeTemperatureMax = ForgeMax;
+ PassParameters->DeltaTime = DeltaTime;
+
+ PassParameters->InputTemperatureBuffer = GraphBuilder.CreateSRV(InputTempRDG, PF_R32_FLOAT);
+ PassParameters->SurfaceVoxelFlagsBuffer = GraphBuilder.CreateSRV(FlagsRDG, PF_R32_UINT);
+ PassParameters->OutputTemperatureBuffer = GraphBuilder.CreateUAV(OutputTempRDG, PF_R32_FLOAT);
+ PassParameters->OutputPlasticityBuffer = GraphBuilder.CreateUAV(PlasticityRDG, PF_R32_FLOAT);
+
+ // 计算线程组数量
+ FIntVector GroupSize = FTemperatureComputeShader::GetGroupSize();
+ FIntVector GroupCount(
+ FMath::DivideAndRoundUp(Resolution.X, GroupSize.X),
+ FMath::DivideAndRoundUp(Resolution.Y, GroupSize.Y),
+ FMath::DivideAndRoundUp(Resolution.Z, GroupSize.Z)
+ );
+
+ // 添加计算Pass
+ FComputeShaderUtils::AddPass(
+ GraphBuilder,
+ RDG_EVENT_NAME("TemperatureConduction"),
+ ComputeShader,
+ PassParameters,
+ GroupCount
+ );
+
+ // TODO: 添加数据复制Pass(从RDG回RHI)
+ // 暂时跳过,需要实现正确的缓冲区提取
+
+ // 执行RDG
+ GraphBuilder.Execute();
+
+ UE_LOG(LogTemp, Warning, TEXT("DynamicIronBlock: Temperature compute dispatched (%d x %d x %d groups) - Data copy not yet implemented"),
+ GroupCount.X, GroupCount.Y, GroupCount.Z);
});
}
diff --git a/Source/BladeSmith/DynamicIronBlock.h b/Source/BladeSmith/DynamicIronBlock.h
index ffe82e4..8df2a11 100644
--- a/Source/BladeSmith/DynamicIronBlock.h
+++ b/Source/BladeSmith/DynamicIronBlock.h
@@ -4,6 +4,7 @@
#include "CoreMinimal.h"
#include "DynamicMeshActor.h"
+#include
#include "DynamicIronBlock.generated.h"
/**
@@ -258,6 +259,9 @@ private:
float TimeSinceLastUpdate = 0.0f; // 距离上次温度更新的时间
float TemperatureUpdateInterval = 0.1f; // 温度更新间隔(秒)
+ // GPU缓冲区是否已准备好(线程安全标志)
+ std::atomic bGPUBuffersReady{false};
+
/**
* 创建GPU缓冲区
*/