feat: 适配 UE5.8 升级与仓库配置整理

- 升级 Target.cs 构建设置到 V7 / EngineIncludeOrderVersion.Unreal5_8
- DynamicIronBlock 温度计算从手动 RHI dispatch 迁移到 RDG (FRDGBuilder + FComputeShaderUtils::Dispatch + FRDGPooledBuffer 包装外部缓冲)
- 移除两个 shader 头中废弃的 SHADER_USE_PARAMETER_STRUCT 宏 (UE5.8 已不需要)
- BladeSmith.uproject: 关联 UE5.8 + 启用 ModelContextProtocol/AllToolsets/MCPClientToolset 插件
- DefaultEngine.ini: r.Substrate=False
- 移除废弃的 DeformAsyncTask.cpp
- 新增项目级 opencode.json (MCP unreal-mcp 配置) 与 .vscode 手写配置 (c_cpp_properties/mcp)
- 整理 .gitignore: 永久排除 AI 工具配置/缓存 (.claude/.codex/.cursor/.gemini/.codegraph/.planning 等)、graphify 缓存、IDE 生成物
- 移出跟踪: .claude/ (含 session-namer 技能)、.vsconfig
This commit is contained in:
2026-08-12 08:57:20 +08:00
parent 68f5f91a08
commit ff8d77d8c0
15 changed files with 159 additions and 148 deletions
+3 -2
View File
@@ -8,8 +8,9 @@ public class BladeSmithTarget : TargetRules
public BladeSmithTarget(TargetInfo Target) : base(Target)
{
Type = TargetType.Game;
DefaultBuildSettings = BuildSettingsVersion.V5;
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_5;
DefaultBuildSettings = BuildSettingsVersion.V7;
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_8;
CppStandard = CppStandardVersion.Cpp20;
ExtraModuleNames.Add("BladeSmith");
}
}
+65 -55
View File
@@ -955,8 +955,7 @@ void ADynamicIronBlock::UpdateVertexColors()
FVector VertexPosFloat(VertexPos.X, VertexPos.Y, VertexPos.Z);
// 采样该位置的温度
//float Temperature = SampleTemperatureAtPosition(VertexPosFloat);
float Temperature = 900;
float Temperature = SampleTemperatureAtPosition(VertexPosFloat);
// 统计温度范围
MinTemp = FMath::Min(MinTemp, Temperature);
MaxTemp = FMath::Max(MaxTemp, Temperature);
@@ -1294,6 +1293,14 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
return;
}
// 验证其他缓冲区
if (!PlasticityBuffer.IsValid() || !SurfaceVoxelFlagsBuffer.IsValid())
{
UE_LOG(LogTemp, Error, TEXT("DynamicIronBlock: Plasticity or Flags buffer not valid! P=%d F=%d"),
PlasticityBuffer.IsValid(), SurfaceVoxelFlagsBuffer.IsValid());
return;
}
// 准备调度参数(捕获到lambda中)
FIntVector Resolution = TemperatureResolution;
float Conductivity = ThermalConductivity;
@@ -1305,16 +1312,17 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock: Dispatching temperature compute - Resolution=(%d,%d,%d), DeltaTime=%.4f"),
Resolution.X, Resolution.Y, Resolution.Z, DeltaTime);
// Ping-Pong缓冲区引用(捕获到lambda传递给RDG)
FBufferRHIRef InputBuffer = bUseBufferA ? TemperatureBufferA : TemperatureBufferB;
FBufferRHIRef OutputBuffer = bUseBufferA ? TemperatureBufferB : TemperatureBufferA;
// Ping-Pong缓冲区引用(捕获到lambda传递给渲染线程)
const bool bCurrentBufferA = bUseBufferA;
FBufferRHIRef InputBuffer = bCurrentBufferA ? TemperatureBufferA : TemperatureBufferB;
FBufferRHIRef OutputBuffer = bCurrentBufferA ? TemperatureBufferB : TemperatureBufferA;
FBufferRHIRef FlagsBuffer = SurfaceVoxelFlagsBuffer;
FBufferRHIRef PlasticityBuf = PlasticityBuffer;
// 切换缓冲区(下次Tick使用新的缓冲区)
bUseBufferA = !bUseBufferA;
// 调度GPU计算(使用RDG正确的资源管理)
// 调度GPU计算(UE5.8已移除手动RHI Compute dispatch API,改用RDG)
ENQUEUE_RENDER_COMMAND(DispatchTemperatureCS)(
[Resolution, Conductivity, Cooling, Ambient, ForgeMin, ForgeMax, DeltaTime,
InputBuffer, OutputBuffer, FlagsBuffer, PlasticityBuf]
@@ -1336,48 +1344,47 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
return;
}
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: Shader valid, creating RDG..."));
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: Shader valid, setting up RDG compute dispatch..."));
// 使用RDG
FRDGBuilder GraphBuilder(RHICmdList, RDG_EVENT_NAME("TemperatureConduction"));
// 构建RDG图
FRDGBuilder GraphBuilder(RHICmdList);
// 将外部RHI缓冲区正确注册到RDG系统
// 创建缓冲区描述符
const uint32 NumElements = InputBuffer->GetSize() / sizeof(float);
FRDGBufferDesc TempBufferDesc = FRDGBufferDesc::CreateBufferDesc(sizeof(float), NumElements);
FRDGBufferDesc FlagsBufferDesc = FRDGBufferDesc::CreateBufferDesc(sizeof(uint32), NumElements);
// 将外部裸RHI缓冲区包装为FRDGPooledBuffer后注册到RDG
//(UE5.8的RegisterExternalBuffer只接受FRDGPooledBuffer,不再接受裸FBufferRHIRef)
auto WrapExternalBuffer = [&GraphBuilder](FBufferRHIRef RawBuffer, const TCHAR* Name) -> FRDGBufferRef
{
// 所有缓冲区均为4字节typed元素(float温度/塑性 或 uint体素标志)
const uint32 BytesPerElement = sizeof(float);
const uint32 NumElements = RawBuffer->GetSize() / BytesPerElement;
FRDGBufferDesc Desc = FRDGBufferDesc::CreateBufferDesc(BytesPerElement, NumElements);
TRefCountPtr<FRDGPooledBuffer> PooledBuffer = new FRDGPooledBuffer(RawBuffer, Desc, NumElements, Name);
return GraphBuilder.RegisterExternalBuffer(PooledBuffer);
};
// 创建FRDGPooledBuffer并注册
TRefCountPtr<FRDGPooledBuffer> InputPooledBuffer = new FRDGPooledBuffer(RHICmdList, InputBuffer, TempBufferDesc, NumElements, TEXT("InputTemperatureBuffer"));
TRefCountPtr<FRDGPooledBuffer> OutputPooledBuffer = new FRDGPooledBuffer(RHICmdList, OutputBuffer, TempBufferDesc, NumElements, TEXT("OutputTemperatureBuffer"));
TRefCountPtr<FRDGPooledBuffer> FlagsPooledBuffer = new FRDGPooledBuffer(RHICmdList, FlagsBuffer, FlagsBufferDesc, NumElements, TEXT("SurfaceVoxelFlagsBuffer"));
TRefCountPtr<FRDGPooledBuffer> PlasticityPooledBuffer = new FRDGPooledBuffer(RHICmdList, PlasticityBuf, TempBufferDesc, NumElements, TEXT("PlasticityBuffer"));
FRDGBufferRef InputRDG = WrapExternalBuffer(InputBuffer, TEXT("InputTemperature"));
FRDGBufferRef OutputRDG = WrapExternalBuffer(OutputBuffer, TEXT("OutputTemperature"));
FRDGBufferRef FlagsRDG = WrapExternalBuffer(FlagsBuffer, TEXT("SurfaceVoxelFlags"));
FRDGBufferRef PlasticityRDG = WrapExternalBuffer(PlasticityBuf, TEXT("Plasticity"));
FRDGBufferRef InputTempRDG = GraphBuilder.RegisterExternalBuffer(InputPooledBuffer);
FRDGBufferRef OutputTempRDG = GraphBuilder.RegisterExternalBuffer(OutputPooledBuffer);
FRDGBufferRef FlagsRDG = GraphBuilder.RegisterExternalBuffer(FlagsPooledBuffer);
FRDGBufferRef PlasticityRDG = GraphBuilder.RegisterExternalBuffer(PlasticityPooledBuffer);
// 通过RDG创建SRV/UAV(格式必须与缓冲区创建时一致:温度/塑性=PF_R32_FLOAT,体素标志=PF_R32_UINT)
FRDGBufferSRV* InputTempSRV = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(InputRDG, PF_R32_FLOAT));
FRDGBufferSRV* FlagsSRV = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(FlagsRDG, PF_R32_UINT));
FRDGBufferUAV* OutputTempUAV = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(OutputRDG, PF_R32_FLOAT));
FRDGBufferUAV* OutputPlasticityUAV = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(PlasticityRDG, PF_R32_FLOAT));
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: External RHI buffers registered to RDG, setting shader parameters..."));
// 设置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;
// 创建SRV和UAV(使用正确注册的RDG资源)
PassParameters->InputTemperatureBuffer = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(InputTempRDG, PF_R32_FLOAT));
PassParameters->SurfaceVoxelFlagsBuffer = GraphBuilder.CreateSRV(FRDGBufferSRVDesc(FlagsRDG, PF_R32_UINT));
PassParameters->OutputTemperatureBuffer = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(OutputTempRDG, PF_R32_FLOAT));
PassParameters->OutputPlasticityBuffer = GraphBuilder.CreateUAV(FRDGBufferUAVDesc(PlasticityRDG, PF_R32_FLOAT));
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: Shader parameters set, calculating group count..."));
// 分配并填充参数(RDG参数指针由GraphBuilder托管生命周期)
FTemperatureComputeShader::FParameters* Parameters = GraphBuilder.AllocParameters<FTemperatureComputeShader::FParameters>();
Parameters->VoxelResolution = Resolution;
Parameters->ThermalConductivity = Conductivity;
Parameters->CoolingRate = Cooling;
Parameters->AmbientTemperature = Ambient;
Parameters->ForgeTemperatureMin = ForgeMin;
Parameters->ForgeTemperatureMax = ForgeMax;
Parameters->DeltaTime = DeltaTime;
Parameters->InputTemperatureBuffer = InputTempSRV;
Parameters->SurfaceVoxelFlagsBuffer = FlagsSRV;
Parameters->OutputTemperatureBuffer = OutputTempUAV;
Parameters->OutputPlasticityBuffer = OutputPlasticityUAV;
// 计算线程组数量
FIntVector GroupSize = FTemperatureComputeShader::GetGroupSize();
@@ -1387,21 +1394,24 @@ void ADynamicIronBlock::DispatchTemperatureCompute(float DeltaTime)
FMath::DivideAndRoundUp(Resolution.Z, GroupSize.Z)
);
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: GroupCount=(%d,%d,%d), adding compute pass..."),
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: GroupCount=(%d,%d,%d), dispatching..."),
GroupCount.X, GroupCount.Y, GroupCount.Z);
// 添加计算Pass
FComputeShaderUtils::AddPass(
GraphBuilder,
RDG_EVENT_NAME("TemperatureConduction"),
ComputeShader,
PassParameters,
GroupCount
);
// 添加Compute Pass并调度(RDG自动处理资源状态转换与屏障)
GraphBuilder.AddPass(
RDG_EVENT_NAME("TemperatureCompute"),
Parameters,
ERDGPassFlags::Compute,
[ComputeShader, Parameters, GroupCount](FRHIComputeCommandList& CommandList)
{
FComputeShaderUtils::Dispatch(
CommandList,
ComputeShader,
*Parameters,
GroupCount);
});
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock [RenderThread]: Compute pass added, executing RDG..."));
// 执行RDG,自动处理资源转换和同步
// 执行RDG图(编译并提交到RHI命令列表)
GraphBuilder.Execute();
UE_LOG(LogTemp, Log, TEXT("DynamicIronBlock: Temperature compute dispatched successfully (%d x %d x %d groups)"),
+3 -2
View File
@@ -8,8 +8,9 @@ public class BladeSmithEditorTarget : TargetRules
public BladeSmithEditorTarget(TargetInfo Target) : base(Target)
{
Type = TargetType.Editor;
DefaultBuildSettings = BuildSettingsVersion.V5;
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_5;
DefaultBuildSettings = BuildSettingsVersion.V7;
IncludeOrderVersion = EngineIncludeOrderVersion.Unreal5_8;
CppStandard = CppStandardVersion.Cpp20;
ExtraModuleNames.Add("BladeSmith");
}
}