修改shader

This commit is contained in:
2025-12-07 23:50:00 +08:00
parent 0ee31987b5
commit 3ea9686964
6 changed files with 136 additions and 34 deletions
+1
View File
@@ -2,6 +2,7 @@
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADanyxuq_002Easm_002Fl_003AC_0021_003FUsers_003Fstarm_003FAppData_003FLocal_003FTemp_003FSandboxFiles_003FRewuwer_003FDanyxuq_002Easm/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADanyxuq_002Easm_002Fl_003AC_0021_003FUsers_003Fstarm_003FAppData_003FLocal_003FTemp_003FSandboxFiles_003FRewuwer_003FDanyxuq_002Easm/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADycuvaq_002Easm_002Fl_003AC_0021_003FUsers_003Fstarm_003FAppData_003FLocal_003FTemp_003FSandboxFiles_003FWoqosub_003FDycuvaq_002Easm/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ADycuvaq_002Easm_002Fl_003AC_0021_003FUsers_003Fstarm_003FAppData_003FLocal_003FTemp_003FSandboxFiles_003FWoqosub_003FDycuvaq_002Easm/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFunction_002Eh_002Fl_003AD_0021_003FProgram_0020Files_003FEpic_0020Games_003FUE_005F5_002E6_003FEngine_003FSource_003FRuntime_003FCore_003FPublic_003FTemplates_003FFunction_002Eh/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AFunction_002Eh_002Fl_003AD_0021_003FProgram_0020Files_003FEpic_0020Games_003FUE_005F5_002E6_003FEngine_003FSource_003FRuntime_003FCore_003FPublic_003FTemplates_003FFunction_002Eh/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASaryqah_002Easm_002Fl_003AC_0021_003FUsers_003Fstarm_003FAppData_003FLocal_003FTemp_003FSandboxFiles_003FZexazuc_003FSaryqah_002Easm/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATedilij_002Easm_002Fl_003AC_0021_003FUsers_003Fstarm_003FAppData_003FLocal_003FTemp_003FSandboxFiles_003FKotyxod_003FTedilij_002Easm/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATedilij_002Easm_002Fl_003AC_0021_003FUsers_003Fstarm_003FAppData_003FLocal_003FTemp_003FSandboxFiles_003FKotyxod_003FTedilij_002Easm/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATextureDefines_002Eh_002Fl_003AD_0021_003FProgram_0020Files_003FEpic_0020Games_003FUE_005F5_002E6_003FEngine_003FSource_003FRuntime_003FEngine_003FClasses_003FEngine_003FTextureDefines_002Eh/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATextureDefines_002Eh_002Fl_003AD_0021_003FProgram_0020Files_003FEpic_0020Games_003FUE_005F5_002E6_003FEngine_003FSource_003FRuntime_003FEngine_003FClasses_003FEngine_003FTextureDefines_002Eh/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AShaderParameterStruct_002Eh_002Fl_003AD_0021_003FProgram_0020Files_003FEpic_0020Games_003FUE_005F5_002E6_003FEngine_003FSource_003FRuntime_003FRenderCore_003FPublic_003FShaderParameterStruct_002Eh/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AShaderParameterStruct_002Eh_002Fl_003AD_0021_003FProgram_0020Files_003FEpic_0020Games_003FUE_005F5_002E6_003FEngine_003FSource_003FRuntime_003FRenderCore_003FPublic_003FShaderParameterStruct_002Eh/@EntryIndexedValue">ForceIncluded</s:String>
Binary file not shown.
@@ -8,7 +8,7 @@
/** /**
* 温度传导计算着色器的调度参数 * 温度传导计算着色器的调度参数
*/ */
struct BLADESMITH_API FTemperatureCSDispatchParams struct MICESHADERS_API FTemperatureCSDispatchParams
{ {
// 体素网格分辨率 // 体素网格分辨率
FIntVector VoxelResolution; FIntVector VoxelResolution;
@@ -42,7 +42,7 @@ struct BLADESMITH_API FTemperatureCSDispatchParams
/** /**
* 线程安全的温度计算参数队列 * 线程安全的温度计算参数队列
*/ */
struct FThreadSafeTemperatureParams struct MICESHADERS_API FThreadSafeTemperatureParams
{ {
FCriticalSection ParamsCriticalSection; FCriticalSection ParamsCriticalSection;
TArray<FTemperatureCSDispatchParams> PendingParams; TArray<FTemperatureCSDispatchParams> 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); DECLARE_GLOBAL_SHADER(FTemperatureComputeShader);
SHADER_USE_PARAMETER_STRUCT(FTemperatureComputeShader, FGlobalShader); SHADER_USE_PARAMETER_STRUCT(FTemperatureComputeShader, FGlobalShader);
+127 -30
View File
@@ -13,8 +13,8 @@
#include "GeometryScript/MeshNormalsFunctions.h" #include "GeometryScript/MeshNormalsFunctions.h"
#include "Materials/MaterialInstanceDynamic.h" #include "Materials/MaterialInstanceDynamic.h"
// GPU计算相关 // GPU计算相关(从MiceShaders插件引用)
#include "Shaders/FTemperatureComputeShader.h" #include "FTemperatureComputeShader.h"
#include "RHI.h" #include "RHI.h"
#include "RHIResources.h" #include "RHIResources.h"
#include "RHICommandList.h" #include "RHICommandList.h"
@@ -23,6 +23,8 @@
#include "GlobalShader.h" #include "GlobalShader.h"
#include "ShaderParameterStruct.h" #include "ShaderParameterStruct.h"
#include "RHIStaticStates.h" #include "RHIStaticStates.h"
#include "ShaderCompilerCore.h"
#include "ShaderCore.h"
ADynamicIronBlock::ADynamicIronBlock() ADynamicIronBlock::ADynamicIronBlock()
{ {
@@ -39,7 +41,8 @@ ADynamicIronBlock::ADynamicIronBlock()
void ADynamicIronBlock::BeginPlay() void ADynamicIronBlock::BeginPlay()
{ {
Super::BeginPlay(); Super::BeginPlay();
// 初始化 Box 网格
InitializeBoxMesh();
// 创建GPU缓冲区 // 创建GPU缓冲区
if (bEnableTemperatureSystem && TemperatureGrid.Num() > 0) if (bEnableTemperatureSystem && TemperatureGrid.Num() > 0)
{ {
@@ -57,6 +60,12 @@ void ADynamicIronBlock::Tick(float DeltaTime)
return; return;
} }
// 检查GPU缓冲区是否准备好
if (!bGPUBuffersReady.load(std::memory_order_acquire))
{
return;
}
// 累积时间 // 累积时间
TimeSinceLastUpdate += DeltaTime; TimeSinceLastUpdate += DeltaTime;
@@ -88,7 +97,7 @@ void ADynamicIronBlock::OnConstruction(const FTransform& Transform)
Super::OnConstruction(Transform); Super::OnConstruction(Transform);
// 初始化 Box 网格 // 初始化 Box 网格
InitializeBoxMesh(); //InitializeBoxMesh();
} }
void ADynamicIronBlock::InitializeBoxMesh() void ADynamicIronBlock::InitializeBoxMesh()
@@ -684,11 +693,11 @@ void ADynamicIronBlock::CreateGPUBuffers()
ENQUEUE_RENDER_COMMAND(CreateTemperatureBuffers)( ENQUEUE_RENDER_COMMAND(CreateTemperatureBuffers)(
[this, TotalVoxels, BufferSize, FlagsBufferSize](FRHICommandListImmediate& RHICmdList) [this, TotalVoxels, BufferSize, FlagsBufferSize](FRHICommandListImmediate& RHICmdList)
{ {
// 创建温度缓冲A // 创建温度缓冲A(使用ByteAddressBuffer而非StructuredBuffer)
FRHIBufferCreateDesc TempBufferADesc; FRHIBufferCreateDesc TempBufferADesc;
TempBufferADesc.DebugName = TEXT("TemperatureBufferA"); TempBufferADesc.DebugName = TEXT("TemperatureBufferA");
TempBufferADesc.Size = BufferSize; TempBufferADesc.Size = BufferSize;
TempBufferADesc.Usage = BUF_StructuredBuffer | BUF_ShaderResource | BUF_UnorderedAccess; TempBufferADesc.Usage = BUF_ShaderResource | BUF_UnorderedAccess;
TempBufferADesc.InitialState = ERHIAccess::UAVCompute; TempBufferADesc.InitialState = ERHIAccess::UAVCompute;
TemperatureBufferA = RHICmdList.CreateBuffer(TempBufferADesc); TemperatureBufferA = RHICmdList.CreateBuffer(TempBufferADesc);
TemperatureUAV_A = RHICmdList.CreateUnorderedAccessView(TemperatureBufferA, FRHIViewDesc::CreateBufferUAV().SetType(FRHIViewDesc::EBufferType::Typed).SetFormat(PF_R32_FLOAT)); TemperatureUAV_A = RHICmdList.CreateUnorderedAccessView(TemperatureBufferA, FRHIViewDesc::CreateBufferUAV().SetType(FRHIViewDesc::EBufferType::Typed).SetFormat(PF_R32_FLOAT));
@@ -698,7 +707,7 @@ void ADynamicIronBlock::CreateGPUBuffers()
FRHIBufferCreateDesc TempBufferBDesc; FRHIBufferCreateDesc TempBufferBDesc;
TempBufferBDesc.DebugName = TEXT("TemperatureBufferB"); TempBufferBDesc.DebugName = TEXT("TemperatureBufferB");
TempBufferBDesc.Size = BufferSize; TempBufferBDesc.Size = BufferSize;
TempBufferBDesc.Usage = BUF_StructuredBuffer | BUF_ShaderResource | BUF_UnorderedAccess; TempBufferBDesc.Usage = BUF_ShaderResource | BUF_UnorderedAccess;
TempBufferBDesc.InitialState = ERHIAccess::UAVCompute; TempBufferBDesc.InitialState = ERHIAccess::UAVCompute;
TemperatureBufferB = RHICmdList.CreateBuffer(TempBufferBDesc); TemperatureBufferB = RHICmdList.CreateBuffer(TempBufferBDesc);
TemperatureUAV_B = RHICmdList.CreateUnorderedAccessView(TemperatureBufferB, FRHIViewDesc::CreateBufferUAV().SetType(FRHIViewDesc::EBufferType::Typed).SetFormat(PF_R32_FLOAT)); TemperatureUAV_B = RHICmdList.CreateUnorderedAccessView(TemperatureBufferB, FRHIViewDesc::CreateBufferUAV().SetType(FRHIViewDesc::EBufferType::Typed).SetFormat(PF_R32_FLOAT));
@@ -708,7 +717,7 @@ void ADynamicIronBlock::CreateGPUBuffers()
FRHIBufferCreateDesc PlasticityBufferDesc; FRHIBufferCreateDesc PlasticityBufferDesc;
PlasticityBufferDesc.DebugName = TEXT("PlasticityBuffer"); PlasticityBufferDesc.DebugName = TEXT("PlasticityBuffer");
PlasticityBufferDesc.Size = BufferSize; PlasticityBufferDesc.Size = BufferSize;
PlasticityBufferDesc.Usage = BUF_StructuredBuffer | BUF_ShaderResource | BUF_UnorderedAccess; PlasticityBufferDesc.Usage = BUF_ShaderResource | BUF_UnorderedAccess;
PlasticityBufferDesc.InitialState = ERHIAccess::UAVCompute; PlasticityBufferDesc.InitialState = ERHIAccess::UAVCompute;
PlasticityBuffer = RHICmdList.CreateBuffer(PlasticityBufferDesc); PlasticityBuffer = RHICmdList.CreateBuffer(PlasticityBufferDesc);
PlasticityUAV = RHICmdList.CreateUnorderedAccessView(PlasticityBuffer, FRHIViewDesc::CreateBufferUAV().SetType(FRHIViewDesc::EBufferType::Typed).SetFormat(PF_R32_FLOAT)); PlasticityUAV = RHICmdList.CreateUnorderedAccessView(PlasticityBuffer, FRHIViewDesc::CreateBufferUAV().SetType(FRHIViewDesc::EBufferType::Typed).SetFormat(PF_R32_FLOAT));
@@ -717,18 +726,28 @@ void ADynamicIronBlock::CreateGPUBuffers()
FRHIBufferCreateDesc FlagsBufferDesc; FRHIBufferCreateDesc FlagsBufferDesc;
FlagsBufferDesc.DebugName = TEXT("SurfaceVoxelFlagsBuffer"); FlagsBufferDesc.DebugName = TEXT("SurfaceVoxelFlagsBuffer");
FlagsBufferDesc.Size = FlagsBufferSize; FlagsBufferDesc.Size = FlagsBufferSize;
FlagsBufferDesc.Usage = BUF_StructuredBuffer | BUF_ShaderResource; FlagsBufferDesc.Usage = BUF_ShaderResource;
FlagsBufferDesc.InitialState = ERHIAccess::SRVCompute; FlagsBufferDesc.InitialState = ERHIAccess::SRVCompute;
SurfaceVoxelFlagsBuffer = RHICmdList.CreateBuffer(FlagsBufferDesc); SurfaceVoxelFlagsBuffer = RHICmdList.CreateBuffer(FlagsBufferDesc);
SurfaceVoxelSRV = RHICmdList.CreateShaderResourceView(SurfaceVoxelFlagsBuffer, FRHIViewDesc::CreateBufferSRV().SetType(FRHIViewDesc::EBufferType::Typed).SetFormat(PF_R32_UINT)); 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)"), UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock: GPU buffers created (%d voxels, %.2f MB)"),
TotalVoxels, (BufferSize * 3 + FlagsBufferSize) / (1024.0f * 1024.0f)); 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() void ADynamicIronBlock::ReleaseGPUBuffers()
{ {
// 先标记缓冲区为未准备状态,防止Tick中继续使用
bGPUBuffersReady.store(false, std::memory_order_release);
ENQUEUE_RENDER_COMMAND(ReleaseTemperatureBuffers)( ENQUEUE_RENDER_COMMAND(ReleaseTemperatureBuffers)(
[this](FRHICommandListImmediate& RHICmdList) [this](FRHICommandListImmediate& RHICmdList)
{ {
@@ -840,33 +859,111 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
return; return;
} }
// 准备调度参数 // 准备调度参数(捕获到lambda中)
FTemperatureCSDispatchParams Params; FIntVector Resolution = TemperatureResolution;
Params.VoxelResolution = TemperatureResolution; float Conductivity = ThermalConductivity;
Params.ThermalConductivity = ThermalConductivity; float Cooling = CoolingRate;
Params.CoolingRate = CoolingRate; float Ambient = AmbientTemperature;
Params.AmbientTemperature = AmbientTemperature; float ForgeMin = ForgeTemperatureMin;
Params.ForgeTemperatureMin = ForgeTemperatureMin; float ForgeMax = ForgeTemperatureMax;
Params.ForgeTemperatureMax = ForgeTemperatureMax;
Params.DeltaTime = DeltaTime;
// Ping-Pong缓冲区 // Ping-Pong缓冲区引用
Params.InputTemperatureBuffer = bUseBufferA ? TemperatureBufferA : TemperatureBufferB; FBufferRHIRef InputBuffer = bUseBufferA ? TemperatureBufferA : TemperatureBufferB;
Params.OutputTemperatureUAV = bUseBufferA ? TemperatureUAV_B : TemperatureUAV_A; FBufferRHIRef OutputBuffer = bUseBufferA ? TemperatureBufferB : TemperatureBufferA;
Params.SurfaceVoxelFlagsBuffer = SurfaceVoxelFlagsBuffer; FBufferRHIRef FlagsBuffer = SurfaceVoxelFlagsBuffer;
Params.OutputPlasticityUAV = PlasticityUAV; FBufferRHIRef PlasticityBuf = PlasticityBuffer;
// 保存当前bUseBufferA状态用于Lambda // 创建SRV/UAV(在游戏线程创建,捕获到lambda)
bool bCurrentUseBufferA = bUseBufferA; 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; bUseBufferA = !bUseBufferA;
// 调度GPU计算(使用RDG) // 调度GPU计算(直接使用RHI,不用RDG)
ENQUEUE_RENDER_COMMAND(DispatchTemperatureCS)( 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计算 // 检查ShaderMap是否有效
UE_LOG(LogTemp, Warning, TEXT("DynamicIronBlock: GPU temperature compute temporarily disabled (API compatibility)")); FGlobalShaderMap* ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel);
if (!ShaderMap)
{
UE_LOG(LogTemp, Error, TEXT("DynamicIronBlock: Global ShaderMap is null!"));
return;
}
// 获取Compute Shader并检查是否有效
TShaderMapRef<FTemperatureComputeShader> 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<FTemperatureComputeShader::FParameters>();
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);
}); });
} }
+4
View File
@@ -4,6 +4,7 @@
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "DynamicMeshActor.h" #include "DynamicMeshActor.h"
#include <atomic>
#include "DynamicIronBlock.generated.h" #include "DynamicIronBlock.generated.h"
/** /**
@@ -258,6 +259,9 @@ private:
float TimeSinceLastUpdate = 0.0f; // 距离上次温度更新的时间 float TimeSinceLastUpdate = 0.0f; // 距离上次温度更新的时间
float TemperatureUpdateInterval = 0.1f; // 温度更新间隔(秒) float TemperatureUpdateInterval = 0.1f; // 温度更新间隔(秒)
// GPU缓冲区是否已准备好(线程安全标志)
std::atomic<bool> bGPUBuffersReady{false};
/** /**
* 创建GPU缓冲区 * 创建GPU缓冲区
*/ */