修改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_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_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_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>
Binary file not shown.
@@ -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<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);
SHADER_USE_PARAMETER_STRUCT(FTemperatureComputeShader, FGlobalShader);
+127 -30
View File
@@ -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<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 "DynamicMeshActor.h"
#include <atomic>
#include "DynamicIronBlock.generated.h"
/**
@@ -258,6 +259,9 @@ private:
float TimeSinceLastUpdate = 0.0f; // 距离上次温度更新的时间
float TemperatureUpdateInterval = 0.1f; // 温度更新间隔(秒)
// GPU缓冲区是否已准备好(线程安全标志)
std::atomic<bool> bGPUBuffersReady{false};
/**
* 创建GPU缓冲区
*/