Compare commits

...

9 Commits

Author SHA1 Message Date
starmen1265 ff8d77d8c0 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
2026-08-12 08:57:20 +08:00
starmen1265 68f5f91a08 docs: 添加文档导航索引与 features 范围声明
docs/README.md 作为顶层导航,提供阅读路径推荐(新人/策划/工程师/考古)、需求-设计对应表、边界约定、7 大子系统索引、性能目标。features/hammer-deformation-system.md 顶部加导航头,明确本文档为已交付功能说明,完整需求/设计见对应专题文档。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-11 08:58:58 +08:00
starmen1265 ec5e7556ae docs: 添加应力与疲劳耐久度技术设计
design/06 涵盖四源应力(塑性/热/相变/残余)、扩散松弛、形变阻力、弯曲扭曲与开裂扩展。design/07 涵盖疲劳累积公式、疲劳裂纹、刀具耐久度计算、回火恢复与刀具失效判定。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-11 08:58:47 +08:00
starmen1265 fbb2baa854 docs: 添加物理模拟与淬火系统技术设计
design/04 仅保留加工硬化与晶粒演化,应力/淬火部分引用 design/05、design/06。design/05 涵盖温度区间、冷却速率、Sigmoid 硬度映射、相态系统、三阶段可视化(过程高辨识→冷却过渡→真实回火色)。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-11 08:58:38 +08:00
starmen1265 a9543b5909 docs: 添加几何侧技术设计(刀刃形成/表面磨损/网格质量)
三个对应几何与外观的技术设计。design/01 已包含评估增补(参数语义统一、双区实现回填、流水线协作、形变连续性、碰撞渲染同步、体积守恒策略、性能预算协调),修复了 InverseTransformPosition 法线转换 bug。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-11 08:58:26 +08:00
starmen1265 1514d53df5 docs: 添加材料物理侧需求(硬化/淬火/应力/疲劳)
四个对应材料内部物理过程的需求文档。加工硬化与晶粒演化涵盖越打越硬与回火软化;淬火退火相变涵盖温度区间与三阶段可视化;应力累积涵盖弯曲开裂;疲劳与耐久度涵盖刀具失效。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-11 08:58:15 +08:00
starmen1265 f31518d7e3 docs: 添加玩家行为侧需求(锤击/表面磨损/网格质量)
三个对应玩家直接可见行为的需求文档。锤击形变涵盖各向异性流动与边缘平整;表面磨损涵盖铁锈脱落与无漂移;网格质量承诺连续锻打 50+ 次后无明显退化。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-11 08:58:06 +08:00
starmen1265 4633e866ec docs: 添加锻造系统总体需求与总体技术架构
整合原 01-22 高真实度锻造系统设计与 01-23 淬火退火相变与应力疲劳总览两份重叠文档,拆分为需求侧(玩家/体验视角)与设计侧(技术实现视角)。需求文档不含任何代码与算法名,设计文档定义混合体素-顶点架构、跨子系统共用决策、性能预算。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-11 08:57:55 +08:00
starmen1265 56cb314799 docs: 归档原 plans 目录,迁移实施清单到 impl/
原 docs/plans/ 下的 10 份混合文档(需求+设计混杂)归档到 docs/_archive/plans/ 作为决策考古用途。hammer-deformation-enhancement 实施清单迁移到 docs/impl/。后续工作产出统一进入 docs/requirements/ 与 docs/design/ 两个清晰分层。

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-08-11 08:57:46 +08:00
43 changed files with 7587 additions and 149 deletions
-18
View File
@@ -1,18 +0,0 @@
{
"permissions": {
"allow": [
"Bash(\"E:\\MiceCola\\work\\UE_5_6\\Engine\\Build\\BatchFiles\\Build.bat\" BladeSmithEditor Win64 Development \"-Project=E:\\MiceCola\\work\\BladeSmith\\BladeSmith.uproject\" -WaitMutex -FromMsBuild)",
"Bash(dir:*)",
"Bash(git add:*)",
"Bash(git commit:*)",
"Skill(gsd:*)",
"Bash(findstr:*)",
"Bash(powershell:*)",
"Bash(Select-Object -Last 20)",
"WebSearch"
],
"deny": [],
"ask": []
},
"outputStyle": "Explanatory"
}
-49
View File
@@ -1,49 +0,0 @@
---
name: session-namer
description: 会话命名管理工具 - 在开始新任务前帮助命名或恢复会话
---
# 会话命名管理
当您开始新的工作会话时,此技能帮助您管理会话命名。
## 当前会话状态
请检查是否需要命名当前会话:
### 可用操作
1. **命名当前会话**
使用命令: `/rename <会话名称>`
例如: `/rename 实现各向异性形变`
2. **恢复历史会话**
使用命令: `/resume <会话名称>`
或在 REPL 中使用: `/continue`
3. **继续当前会话**
如果不需要命名,直接开始工作即可
## BladeSmith 项目常用会话命名建议
基于项目结构,建议的会话命名模式:
- **功能开发**: `feat-功能名称` (如 `feat-温度系统`)
- **Bug 修复**: `fix-问题描述` (如 `fix-边缘约束问题`)
- **代码重构**: `refactor-模块名称` (如 `refactor-GPU着色器`)
- **性能优化**: `perf-优化目标` (如 `perf-网格简化`)
- **文档编写**: `docs-文档主题` (如 `docs-API文档`)
- **测试相关**: `test-测试内容` (如 `test-形变系统`)
## 最近的 Git 分支作为参考
当前分支: hammer-deformation-phase1
如果需要查看更多分支或上下文,我可以帮您:
- 列出最近的 git 分支
- 查看最近的提交历史
- 查看未完成的工作
---
**是否需要我帮助您命名当前会话?** 请告诉我您计划做什么,或者直接使用 `/rename` 命令。
+30 -1
View File
@@ -74,4 +74,33 @@ Plugins/**/Intermediate/*
# Cache files for the editor to use
DerivedDataCache/*
nul
nul
# ==================== AI/agent 工具配置与缓存 (机器相关,不入库) ====================
.claude/
.codex/
.cursor/
.gemini/
.codegraph/
.planning/
.omo/run-continuation/
# graphify 技能缓存
.graphify_python
.graphify_uncached.txt
.ignore
graphify-out/
Source/BladeSmith/graphify-out/
# IDE 生成缓存
.vsconfig
.vscode/compileCommands_*/
.vscode/compileCommands_*.json
.vscode/compile_commands.json
BladeSmith.code-workspace
# MCP 配置 (改用 opencode.json)
.mcp.json
# 构建日志
upgrade_build.log
+11
View File
@@ -0,0 +1,11 @@
{
"configurations": [
{
"name": "Win32",
"cStandard": "c17",
"cppStandard": "c++20",
"intelliSenseMode": "msvc-x64"
}
],
"version": 4
}
+10
View File
@@ -0,0 +1,10 @@
{
"servers":
{
"unreal-mcp":
{
"type": "http",
"url": "http://127.0.0.1:8000/mcp"
}
}
}
-17
View File
@@ -1,17 +0,0 @@
{
"version": "1.0",
"components": [
"Component.Unreal.Debugger",
"Component.Unreal.Ide",
"Microsoft.Net.Component.4.6.2.TargetingPack",
"Microsoft.VisualStudio.Component.VC.14.38.17.8.ATL",
"Microsoft.VisualStudio.Component.VC.14.38.17.8.x86.x64",
"Microsoft.VisualStudio.Component.VC.Llvm.Clang",
"Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"Microsoft.VisualStudio.Component.Windows11SDK.22621",
"Microsoft.VisualStudio.Workload.CoreEditor",
"Microsoft.VisualStudio.Workload.ManagedDesktop",
"Microsoft.VisualStudio.Workload.NativeDesktop",
"Microsoft.VisualStudio.Workload.NativeGame"
]
}
+25 -1
View File
@@ -1,6 +1,6 @@
{
"FileVersion": 3,
"EngineAssociation": "5.6",
"EngineAssociation": "{91698CCB-4566-3FC8-DE61-969023373C2D}",
"Category": "",
"Description": "",
"Modules": [
@@ -28,6 +28,30 @@
{
"Name": "HDRIBackdrop",
"Enabled": true
},
{
"Name": "GeometryProcessing",
"Enabled": true
},
{
"Name": "MeshModelingToolset",
"Enabled": true
},
{
"Name": "RiderLink",
"Enabled": false
},
{
"Name": "MCPClientToolset",
"Enabled": true
},
{
"Name": "ModelContextProtocol",
"Enabled": true
},
{
"Name": "AllToolsets",
"Enabled": true
}
]
}
+1
View File
@@ -39,6 +39,7 @@ r.DefaultFeature.LocalExposure.HighlightContrastScale=0.8
r.DefaultFeature.LocalExposure.ShadowContrastScale=0.8
r.DefaultFeature.AutoExposure=False
r.Lumen.TraceMeshSDFs=1
r.Substrate=False
[/Script/WindowsTargetPlatform.WindowsTargetSettings]
DefaultGraphicsRHI=DefaultGraphicsRHI_DX12
@@ -50,8 +50,7 @@ extern FThreadSafeDeformationParams GDeformationParams;
class MICESHADERS_API FDeformComputeShader : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FDeformComputeShader);
SHADER_USE_PARAMETER_STRUCT(FDeformComputeShader, FGlobalShader);
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
// 碰撞参数
SHADER_PARAMETER(FVector3f, ImpactPoint)
@@ -60,7 +60,6 @@ extern MICESHADERS_API FThreadSafeTemperatureParams GTemperatureParams;
class MICESHADERS_API FTemperatureComputeShader : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FTemperatureComputeShader);
SHADER_USE_PARAMETER_STRUCT(FTemperatureComputeShader, FGlobalShader);
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
// 体素网格参数
+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");
}
}
+92
View File
@@ -0,0 +1,92 @@
# BladeSmith 文档索引
BladeSmith 是基于 Unreal Engine 5.6 的真实打铁模拟游戏。本目录存放所有设计文档,按 **需求侧**(玩家/体验视角)与 **设计侧**(技术实现视角)分层组织。
> 项目概述见仓库根目录 [README.md](../README.md)。
---
## 目录结构
```
docs/
├── README.md (本文件)
├── requirements/ 需求文档(玩家视角,无代码)
│ ├── 00-锻造系统总体需求.md
│ └── 01~07 专题需求
├── design/ 技术设计(算法/代码/性能)
│ ├── 00-锻造系统总体技术架构.md
│ └── 01~07 专题设计
├── features/ 已交付功能说明
│ └── hammer-deformation-system.md
├── impl/ 实施记录(Task 清单)
│ └── 2026-01-23-hammer-deformation-enhancement.md
├── tests/ 测试文档
│ └── hammer-deformation-test-results.md
└── _archive/plans/ 原始设计文档归档(2026-01 批次)
```
## 阅读路径
| 角色 | 推荐阅读顺序 |
|---|---|
| **新人了解项目** | [requirements/00](requirements/00-锻造系统总体需求.md) → 各专题需求 → [design/00](design/00-锻造系统总体技术架构.md) |
| **策划验收功能** | [requirements/00](requirements/00-锻造系统总体需求.md) → 对应专题需求 → [features/](features/) 已交付功能 |
| **工程师实现** | [design/00](design/00-锻造系统总体技术架构.md) → 对应专题设计 → [impl/](impl/) 实施记录 |
| **考古(看历史决策)** | [_archive/plans/]( _archive/plans/) 原始文档 |
## 需求/设计对应表
每个主题同时有"需求文档"(玩家可见行为)和"技术设计文档"(算法/代码),一一对应:
| # | 主题 | 需求文档 | 技术设计文档 |
|---|---|---|---|
| 00 | 总体 | [requirements/00](requirements/00-锻造系统总体需求.md) | [design/00](design/00-锻造系统总体技术架构.md) |
| 01 | 锤击形变 / 各向异性流动 | [requirements/01](requirements/01-锤击形变与刀刃形成需求.md) | [design/01](design/01-刀刃形成-各向异性流动设计.md) |
| 02 | 表面磨损 / 无漂移采样 | [requirements/02](requirements/02-表面磨损与外观需求.md) | [design/02](design/02-表面磨损-顶点属性与无漂移采样设计.md) |
| 03 | 网格质量 / 增量式优化 | [requirements/03](requirements/03-网格质量与性能需求.md) | [design/03](design/03-网格质量-增量式优化设计.md) |
| 04 | 加工硬化 / 晶粒演化 | [requirements/04](requirements/04-加工硬化与晶粒演化需求.md) | [design/04](design/04-物理模拟-加工硬化与晶粒演化设计.md) |
| 05 | 淬火退火相变 | [requirements/05](requirements/05-淬火退火相变需求.md) | [design/05](design/05-淬火退火相变系统设计.md) |
| 06 | 应力累积 / 开裂 | [requirements/06](requirements/06-应力累积与开裂需求.md) | [design/06](design/06-应力累积系统设计.md) |
| 07 | 疲劳 / 刀具耐久度 | [requirements/07](requirements/07-疲劳与刀具耐久度需求.md) | [design/07](design/07-疲劳与耐久度系统设计.md) |
## 边界约定
为保证"需求"与"设计"清晰分离:
- **`requirements/` 下严禁**出现代码、UE 宏(UPROPERTY/UFUNCTION)、算法名(Laplacian/Sigmoid/PCA)、变量名、技术概念(Compute Shader/BVH/Ping-Pong)。只用玩家可感知的语言。
- **`design/` 下聚焦**算法、公式、C++/HLSL 代码、数据结构、性能分析、调试工具。需求部分仅用 1-2 句话引用对应需求文档,不重复。
- **`features/`** 是已交付能力的功能清单,供策划与 QA 验收。
- **`impl/`** 是 Step-by-step 实施记录,供工程师追溯历史决策。
- **`_archive/`** 是 2026-01 批次的原始设计文档(当时需求与设计混杂),保留作为决策考古用途,不再更新。
## 7 大玩家可见子系统
锻造系统要让玩家直观感知以下 7 类冶金学物理现象(详见 [requirements/00 §3](requirements/00-锻造系统总体需求.md)):
1. **锤击形变与刀刃形成** — 材料优先沿最小阻力方向流动,边缘附近形成锐利刀刃
2. **表面磨损与外观** — 锤击去锈、纹路随形变移动不漂移、大马士革花纹
3. **网格质量(隐形)** — 连续锻打 50+ 次后刀刃仍平整无锯齿
4. **加工硬化与晶粒演化** — 越打越硬、加热软化、晶粒影响性能
5. **淬火退火相变** — 温度区间+冷却速率共同决定硬度/脆性,三阶段可视化
6. **应力累积与开裂** — 不均匀形变累积应力,超阈值产生裂纹,可弯曲/扭曲/断裂
7. **疲劳与刀具耐久度** — 反复使用累积疲劳,刀具最终可失效
## 性能目标
| 指标 | 目标 |
|---|---|
| 锤击期间帧率 | 稳定 60 FPS |
| 单次锤击响应 | < 10 ms |
| 总锤击开销上限 | ≤ 7 ms |
| 单铁块顶点数 | 20-50 万(刀刃加密到 100 万/cm²) |
| 单铁块内存 | ~30 MB |
详细预算见 [design/00 §6](design/00-锻造系统总体技术架构.md)。
## 维护
- 新增需求 → 在 `requirements/` 下新增文档,更新本 README 的对应表
- 新增技术决策 → 在 `design/` 下新增或更新对应专题,在 `design/00` 的子系统映射表中登记
- 实施完成的 Task → 实施清单存入 `impl/`,功能说明存入 `features/`
- 文档重组或重大调整 → 原 2026-01 批次文档保留在 `_archive/plans/` 不动
@@ -0,0 +1,404 @@
# 锻造系统总体技术架构
**项目**: BladeSmith
**文档类型**: 技术设计(总体)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-22-高真实度锻造系统设计.md` 与 `2026-01-23-淬火退火相变与应力疲劳系统总览.md` 的技术部分
> 本文档描述锻造系统的总体技术架构、数据结构、性能预算与跨子系统共用决策。需求侧见 [requirements/00-锻造系统总体需求.md](../requirements/00-锻造系统总体需求.md)。各子系统的算法/公式/代码细节见 [design/01~07](./)。
---
## 1. 架构目标
| 目标 | 含义 |
|---|---|
| **性能可控** | 体素层粗、顶点层细,分辨率独立可调,保证 60 FPS |
| **物理直觉清晰** | 全局场(温度、应力扩散)+ 局部历史(材料记忆)职责分明 |
| **复用现有基础** | 在已有的 GPU Compute / Ping-Pong / RDG / DynamicMesh3 基础上扩展 |
| **易于调试** | 体素数据与顶点数据可独立可视化 |
| **架构扩展性** | 顶点属性层是开放的,新增子系统不需要改动核心数据结构 |
## 2. 总体架构:混合体素-顶点
核心思想:**体素层存储"全局物理场",顶点层存储"局部材料历史"**,两层通过双向采样通信。
```
┌─────────────────────────────────────────────────────────┐
│ 锤击输入(CPU) │
└─────────────────┬───────────────────────────────────────┘
│
┌────────┴────────┐
│ │
┌────▼─────┐ ┌─────▼─────┐
│ 体素层 │ │ 顶点层 │
│ (GPU) │ │ (CPU/GPU) │
└────┬─────┘ └─────┬────┘
│ │
│ 双向采样通信 │
└────────┬────────┘
│
┌────────▼────────┐
│ 渲染 & 显示 │
└─────────────────┘
```
### 2.1 体素层(全局物理场)
| 字段类别 | 字段 | 说明 |
|---|---|---|
| 已有 | 温度 | °C |
| 已有 | 塑性系数 | 0-1 |
| 已有 | Flags | 标志位(如 bit 0 = 表面体素) |
| 新增 | 平均应变率 | 形变活跃度,0-1 归一化 |
| 新增 | 冷却速率 | °C/s,用于淬火判断 |
| 新增 | 相态 | 奥氏体/马氏体/珠光体/开裂 |
| 新增 | 是否已淬火标记 | bool |
- **分辨率**: 50×50×50(典型),可配置 30³-80³
- **更新方式**: GPU Compute Shader,Ping-Pong 双缓冲
- **优势**: 全局扩散计算(温度传导、应力扩散)在体素层做,与顶点数无关
### 2.2 顶点层(局部材料历史)
| 字段 | 用途 |
|---|---|
| 初始位置 | 无漂移纹理采样 |
| 累积塑性应变 | 加工硬化输入、疲劳计算 |
| 硬度系数 | 形变阻力 |
| 脆性系数 | 开裂风险 |
| 内部应力 | 标量简化,影响形变/弯曲/开裂 |
| 应力方向 | 可选三维向量 |
| 疲劳值 | 0-1,刀具耐久度 |
| 打磨度 | 0=生锈,1=光亮 |
| 晶粒尺寸 | 0-1 归一化 |
| 相态标记 | 从体素采样 |
| 回火颜色 | 真实视觉表现 |
| 氧化层度数 | 氧化层表现 |
| 裂纹状态 | 0=无,1=有 |
- **数量**: 20-50 万顶点(基础),刀刃区域局部加密到 100 万/cm²
- **存储**: `TDynamicMeshVertexAttribute<T>` 自定义属性层
- **优势**: 局部历史精确,顶点独立维护,可承载材料记忆
### 2.3 双向采样
- **体素 → 顶点**: 顶点根据自己的位置,从体素网格三线性插值采样温度、相态、冷却速率等
- **顶点 → 体素**: 顶点的应变率、形变活跃度回写体素,影响全局扩散
## 3. 锤击事件数据流
每次锤击触发以下 8 步流水线(各步对应一个子系统设计文档):
```
锤击事件
↓
1. 形变计算(顶点位移) ── design/01-刀刃形成
↓
2. 更新顶点应变累积 ── design/04-物理模拟
↓
3. 从温度体素采样塑性/相态 ── 架构层(本节)
↓
4. 硬化计算(应变+温度→硬度) ── design/04-物理模拟
↓
5. 应力累积(塑性+热+相变+残余) ── design/06-应力系统
↓
6. 更新体素应变率场、温度/淬火/退火 ── design/05-淬火系统
↓
7. 疲劳累积与裂纹判定 ── design/07-疲劳系统
↓
8. 材质可视化更新(顶点颜色/材质参数) ── design/02-表面磨损、05-淬火系统
```
## 4. 数据结构定义
### 4.1 扩展体素结构
```cpp
USTRUCT(BlueprintType)
struct FTemperatureVoxel
{
GENERATED_BODY()
// ===== 已有字段 =====
UPROPERTY()
float Temperature; // 温度(°C)
UPROPERTY()
float PlasticityCoefficient; // 塑性系数(0-1)
UPROPERTY()
uint8 Flags; // 标志位(bit 0: 表面体素)
// ===== 新增字段 =====
UPROPERTY()
float AverageStrainRate; // 平均应变率(0-1)
UPROPERTY()
float CoolingRate; // 冷却速率(°C/s)
UPROPERTY()
EPhaseState PhaseState; // 相态
UPROPERTY()
bool bHasBeenQuenched; // 是否经历过快速冷却
FTemperatureVoxel()
: Temperature(20.0f)
, PlasticityCoefficient(0.0f)
, Flags(0)
, AverageStrainRate(0.0f)
, CoolingRate(0.0f)
, PhaseState(EPhaseState::Austenite)
, bHasBeenQuenched(false)
{}
};
```
### 4.2 相态枚举
```cpp
UENUM(BlueprintType)
enum class EPhaseState : uint8
{
Austenite UMETA(DisplayName = "奥氏体"), // 高温软相(>800°C)
Martensite UMETA(DisplayName = "马氏体"), // 淬火硬相
Pearlite UMETA(DisplayName = "珠光体"), // 缓冷软相
Bainite UMETA(DisplayName = "贝氏体"), // 中间相
Cracked UMETA(DisplayName = "开裂") // 永久缺陷
};
```
### 4.3 顶点自定义属性层
```cpp
class ADynamicIronBlock : public ADynamicMeshActor
{
private:
// ===== 几何与历史 =====
TDynamicMeshVertexAttribute<FVector>* InitialPositions; // 初始位置(不变,用于无漂移采样)
// ===== 材料状态 =====
TDynamicMeshVertexAttribute<float>* AccumulatedStrain; // 累积塑性应变
TDynamicMeshVertexAttribute<float>* HardnessCoefficient; // 硬度系数(0-1)
TDynamicMeshVertexAttribute<float>* Brittleness; // 脆性系数(0-1)
TDynamicMeshVertexAttribute<float>* GrainSize; // 晶粒尺寸(0-1)
// ===== 应力与疲劳 =====
TDynamicMeshVertexAttribute<float>* StressValue; // 标量应力(简化)
TDynamicMeshVertexAttribute<FVector>* StressDirection; // 应力方向(可选)
TDynamicMeshVertexAttribute<float>* FatigueValue; // 疲劳值(0-1)
TDynamicMeshVertexAttribute<uint8>* CrackState; // 裂纹状态
// ===== 表面与外观 =====
TDynamicMeshVertexAttribute<float>* PolishAmount; // 打磨度(0=生锈,1=光亮)
TDynamicMeshVertexAttribute<float>* RustSeed; // 铁锈噪声种子
TDynamicMeshVertexAttribute<float>* OxideThickness; // 氧化层厚度
TDynamicMeshVertexAttribute<FVector>* TemperColor; // 回火颜色
TDynamicMeshVertexAttribute<float>* OxidationLevel; // 氧化层度数
// ===== 相态(从体素采样) =====
TDynamicMeshVertexAttribute<uint8>* PhaseState; // 相态标记
public:
void InitializeVertexAttributes();
void ReleaseVertexAttributes();
};
```
### 4.4 顶点颜色编码方案
顶点颜色仅 4 通道(RGBA),需精心分配。基础方案:
| 通道 | 用途 | 范围 | 更新频率 |
|---|---|---|---|
| **R** | 温度可视化 | 0-1 | 每帧 |
| **G** | 打磨度(Polish) | 0-1 | 锤击时 |
| **B** | 噪声种子 / 初始位置 Z | 0-1 | 初始化 |
| **A** | 辅助标记(0=正常, 1=裂纹区, 2=淬火区临时) | 0-3 | 事件触发 |
淬火过程期间临时占用通道做高辨识度反馈,过渡期恢复到基础方案(详见 [05-淬火退火相变系统设计.md](05-淬火退火相变系统设计.md))。
超出 4 通道的数据通过 UV1 通道或自定义顶点属性传递。
## 5. GPU-CPU 分工
| 模块 | GPU Compute Shader | CPU |
|---|---|---|
| 温度场 | 更新、传导、冷却 | — |
| 冷却速率 | 滑动平均计算 | — |
| 相态判定 | 体素级相变 | — |
| 热应力 | 计算(简化版) | — |
| 应力扩散 | 简化版 | 完整扩散、累积 |
| 形变 | (可选,GPU 化) | 默认实现、与 BVH 同步 |
| 硬度/脆性 | — | 公式应用 |
| 残余应力/塑性应力 | — | 计算 |
| 裂纹判定/扩展 | — | 全部 |
| 疲劳累积 | — | 全部 |
| 材质可视化 | — | 顶点颜色更新、材质参数 |
### 5.1 异步 Dispatch 模式
```cpp
ENQUEUE_RENDER_COMMAND(FMetallurgyComputeDispatch)(
[this, DeltaTime](FRHICommandListImmediate& RHICmdList)
{
FMetallurgyComputeShader::Dispatch(
RHICmdList,
TemperatureBufferA,
TemperatureBufferB,
MetallurgyBuffer,
DeltaTime,
TemperatureResolution
);
bMetallurgyComputeComplete = true;
}
);
// CPU 继续其他工作,不等待 GPU
```
## 6. 性能与内存预算
### 6.1 帧时间预算(60 FPS = 16.67 ms)
| 系统 | 预算 | 说明 |
|---|---|---|
| 渲染(UE5 基础) | 10 ms | 场景渲染、后处理 |
| 锤击形变计算 | 2-3 ms | 顶点位移、BVH 更新 |
| 网格质量优化 | 1-2 ms | 边翻转、平滑 |
| GPU 物理(温度+冶金) | 0.5-1 ms | Compute Shader(异步) |
| 顶点属性更新 | 0.5 ms | 硬化、应力、疲劳公式 |
| 材质可视化 | 0.5 ms | 顶点颜色更新 |
| **总锤击开销上限** | **≤ 7 ms** | 留足渲染预算 |
### 6.2 内存预算
| 数据 | 大小 | 说明 |
|---|---|---|
| 网格顶点(20 万) | ~17 MB | 84 字节/顶点(含扩展属性) |
| 网格三角形(40 万) | 4.8 MB | 3×4 字节索引 |
| BVH 结构 | 5 MB | 加速结构 |
| 物理场体素(50³) | ~0.4 MB | 扩展后的体素结构 |
| GPU 缓冲区 | ~3 MB | Ping-Pong 缓冲 |
| **单铁块总计** | **~30 MB** | 可接受 |
### 6.3 可扩展性
- **网格密度**: 20 万-100 万顶点可配置
- **体素分辨率**: 30³-80³ 可配置
- **子系统开关**: 各子系统可独立禁用
- **LOD 支持**: 远距离降低网格密度与计算频率
## 7. 子系统映射
每个子系统专题设计文档对应到本架构的具体位置:
| 专题设计 | 主要涉及层 | 主要涉及数据 |
|---|---|---|
| [01-刀刃形成-各向异性流动](01-刀刃形成-各向异性流动设计.md) | 顶点 | 顶点位置、InitialPositions |
| [02-表面磨损-顶点属性与无漂移采样](02-表面磨损-顶点属性与无漂移采样设计.md) | 顶点 + 材质 | PolishAmount、RustSeed、UV1、VertexColor |
| [03-网格质量-增量式优化](03-网格质量-增量式优化设计.md) | 顶点(拓扑) | 三角形/边、属性插值 |
| [04-物理模拟-加工硬化与晶粒演化](04-物理模拟-加工硬化与晶粒演化设计.md) | 体素 + 顶点 | 体素全部、HardnessCoefficient、GrainSize |
| [05-淬火退火相变系统](05-淬火退火相变系统设计.md) | 体素 + 顶点 + 材质 | CoolingRate、PhaseState、TemperColor、OxidationLevel |
| [06-应力累积系统](06-应力累积系统设计.md) | 体素 + 顶点 | StressValue、CrackState、应力方向 |
| [07-疲劳与耐久度系统](07-疲劳与耐久度系统设计.md) | 顶点(纯 CPU) | FatigueValue、CrackState、耐久度聚合 |
## 8. 跨子系统共用决策
这些决策被多个子系统共用,统一约定,避免分散定义。
### 8.1 顶点 ID 持久化与属性插值
网格重网格化(Remesher)/细分/合并会改变顶点 ID。属性必须随顶点保留,否则会出现"颜色错乱""硬化丢失"。
约定:
- **新建顶点**: 在 Remesher 回调 `OnVertexSplit` 中,基于 split alpha 对属性做线性插值
- **最近邻回退**: 回调不可用时,基于位置最近邻查找旧属性(精度损失,仅作降级)
- **不能丢失的关键属性**: InitialPositions、PhaseState、CrackState、AccumulatedStrain
### 8.2 体素 Ping-Pong 双缓冲
温度场、冶金场更新采用 Ping-Pong,避免读写冲突。
```
Buffer A (读) → Compute Shader → Buffer B (写)
下一帧对调
```
### 8.3 体素-顶点采样约定
- **体素 → 顶点**: 三线性插值,顶点位置除以 VoxelSize 得到体素坐标
- **顶点 → 体素**: 加权累加,顶点的应变率按距离权重回写到周围 8 个体素
### 8.4 RDG(Render Dependency Graph)
所有 GPU 计算走 RDG,自动管理资源生命周期与并行调度。
### 8.5 增量式局部处理
锤击只影响局部,所有后续处理(网格优化、应力扩散、疲劳累积)都只处理影响半径内的顶点。这是性能可控的关键。
## 9. 调试与可视化基础设施
各子系统共享一套调试工具,统一在 `ADynamicIronBlock` 上以 `Debug*` 命名:
| 工具 | 用途 |
|---|---|
| `DebugDrawVoxelData` | 体素可视化:温度、冷却速率、相态 |
| `DebugDrawFlowDirections` | 材料流动方向箭头(刀刃形成) |
| `DebugDrawEdgeVertices` | 边缘顶点高亮 |
| `DebugDrawDegenerateTriangles` | 退化三角形红色标记 |
| `DebugDrawQualityHeatmap` | 网格质量热图 |
| `DebugDrawPolishHeatmap` | 打磨度热图 |
| `DebugDrawStressHeatmap` | 应力热图(蓝→红) |
| `DebugDrawFatigueHeatmap` | 疲劳热图 |
| `DebugPrintVertexAttributes` | 顶点属性统计输出(Min/Max/Avg) |
| `LogMeshQualityStats` | 网格质量统计日志 |
材质侧统一加 `DebugMode` 参数:
- 0 = 正常
- 1 = 打磨度
- 2 = 铁锈图案
- 3 = 初始位置
- 4 = 应力
- 5 = 疲劳
- 6 = 相态
## 10. 已知简化假设(技术债务)
当前架构基于以下简化,是有意识的取舍,非缺陷:
1. **应力张量简化为标量**: 真实是 3×3 张量,当前仅用单值。StressDirection 是可选的补丁
2. **晶粒模型极度简化**: 真实晶粒有复杂 3D 形状与取向,当前用标量 GrainSize
3. **相变模型经验化**: 马氏体转变实际需要 CCT 曲线,当前用冷却速率阈值近似
4. **无热-力-电-磁耦合**: 忽略形变生热、磁性、电阻率等二次效应
5. **各向同性假设**: 真实钢有晶粒取向,当前材料各向同性
适用场景:**游戏娱乐级**,足够真实感但非科研级精度。
## 11. 未来扩展接口
以下扩展不需要改动核心架构:
- **多材料支持**: 新增 `MaterialID` 顶点属性,材质侧按 ID 查材料参数表
- **焊接系统**: 多个 `ADynamicIronBlock` 通过焊接约束连接,共享体素边界
- **不同锤头形状**: 在 `OnHammerImpact` 增加 `HammerShape` 参数,影响 ImpactRadius 与形变方向
- **VR 支持**: 锤击输入改为 VR 控制器,核心数据流不变
## 12. 参考资料
### 12.1 技术参考
- Unreal Engine 5.6 Geometry Scripting 文档
- *Real-Time Collision Detection* by Christer Ericson(网格优化)
- *GPU Gems 3: Chapter 39* — Parallel Prefix Sum(GPU 算法)
- *Siggraph 2020: Dynamic Mesh Simplification*(网格优化)
### 12.2 索引
- 总体需求: [requirements/00-锻造系统总体需求.md](../requirements/00-锻造系统总体需求.md)
- 专题设计: [01~07](./)
- 实施记录: [impl/](../impl/)
- 原始设计文档(归档): [_archive/plans/](../_archive/plans/)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,635 @@
# 表面磨损-顶点属性与无漂移采样设计
**项目**: BladeSmith
**文档类型**: 技术设计(专题)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-22-表面磨损系统细节.md`
> 本文档描述表面磨损系统的顶点属性存储、无漂移纹理采样与材质实现。需求见 [requirements/02-表面磨损与外观需求.md](../requirements/02-表面磨损与外观需求.md)。总体架构见 [00-锻造系统总体技术架构.md](00-锻造系统总体技术架构.md)。
---
## 1. 技术背景
铁锈层厚度0.1-2mm,成分为Fe₂O₃/Fe₃O₄,附着强度低易被机械摩擦去除。锤击压力导致摩擦力使铁锈层破碎脱落,塑性形变暴露新鲜金属表面,高温使部分氧化层还原。表面特征必须随形变一起移动,不能漂移。
---
## 2. 技术方案选择
### 2.1 方案对比
| 方案 | 分辨率 | 内存 | 性能 | 漂移问题 | 推荐度 |
|------|--------|------|------|---------|--------|
| **基于顶点** | ★★★☆☆ | ★★★★★ | ★★★★★ | ✅无 | ★★★★★ |
| **基于纹理** | ★★★★★ | ★★☆☆☆ | ★★★☆☆ | ⚠️有扭曲 | ★★★☆☆ |
| **基于体素** | ★★☆☆☆ | ★★★☆☆ | ★★★★☆ | ✅无 | ★★★☆☆ |
**选择**: 基于顶点属性(方案A) + 程序化细节补充
### 2.2 数据通道分配
顶点颜色(RGBA) + UV1通道的完整编码方案:
| 通道 | 用途 | 范围 | 更新频率 | 说明 |
|------|------|------|---------|------|
| **R** | 温度可视化 | 0-1 | 每帧 | 从体素采样,黑体辐射颜色 |
| **G** | 打磨度(Polish) | 0-1 | 锤击时 | 0=完全生锈,1=完全光亮 |
| **B** | 噪声种子(Seed) | 0-1 | 初始化 | 用于程序化噪声,固定不变 |
| **A** | 硬度/应变 | 0-1 | 锤击时 | 可视化累积应变 |
| **UV1.x** | 初始位置X | 0-1 | 初始化 | 编码3D位置的一部分 |
| **UV1.y** | 初始位置Y | 0-1 | 初始化 | 编码3D位置的一部分 |
额外数据通过自定义顶点属性存储。
---
## 3. 数据结构定义
### 3.1 扩展顶点属性
```cpp
class ADynamicIronBlock
{
private:
// ===== 顶点自定义属性层 =====
TDynamicMeshVertexAttribute<FVector>* InitialPositions; // 初始局部位置
TDynamicMeshVertexAttribute<float>* PolishAmount; // 打磨度(0-1)
TDynamicMeshVertexAttribute<float>* RustSeed; // 铁锈噪声种子
TDynamicMeshVertexAttribute<float>* OxideThickness; // 氧化层厚度
// ===== 材质参数 =====
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Surface")
float RustRoughness = 0.9f; // 铁锈粗糙度
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Surface")
float MetalRoughness = 0.2f; // 金属粗糙度
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Surface")
FLinearColor RustBaseColor = FLinearColor(0.6f, 0.3f, 0.1f); // 铁锈基色
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Surface")
FLinearColor MetalBaseColor = FLinearColor(0.8f, 0.8f, 0.85f); // 金属基色
public:
// 初始化顶点属性
void InitializeVertexAttributes();
};
```
### 3.2 初始化逻辑
```cpp
void ADynamicIronBlock::InitializeVertexAttributes()
{
if (!DynamicMesh->HasMesh())
return;
DynamicMesh->EditMesh([&](FDynamicMesh3& Mesh)
{
// 确保属性系统已启用
if (!Mesh.HasAttributes())
{
Mesh.EnableAttributes();
}
// 创建自定义属性层
InitialPositions = new TDynamicMeshVertexAttribute<FVector>(&Mesh);
InitialPositions->Initialize(FVector::ZeroVector);
PolishAmount = new TDynamicMeshVertexAttribute<float>(&Mesh);
PolishAmount->Initialize(0.0f);
RustSeed = new TDynamicMeshVertexAttribute<float>(&Mesh);
RustSeed->Initialize(0.0f);
OxideThickness = new TDynamicMeshVertexAttribute<float>(&Mesh);
OxideThickness->Initialize(1.0f); // 初始完全氧化
// 获取或创建UV1层
FDynamicMeshUVOverlay* UV1 = Mesh.Attributes()->GetUVLayer(1);
if (!UV1)
{
Mesh.Attributes()->SetNumUVLayers(2);
UV1 = Mesh.Attributes()->GetUVLayer(1);
}
// 计算包围盒(用于位置编码)
FAABB3 Box = Mesh.GetBounds();
FVector BoxMin = Box.Min;
FVector BoxMax = Box.Max;
FVector BoxSize = Box.Max - Box.Min;
// 初始化每个顶点
for (int32 VID : Mesh.VertexIndicesItr())
{
FVector LocalPos = Mesh.GetVertex(VID);
// 1. 保存初始位置(不变)
InitialPositions->SetValue(VID, LocalPos);
// 2. 初始化打磨度为0(完全生锈)
PolishAmount->SetValue(VID, 0.0f);
// 3. 分配随机铁锈种子
RustSeed->SetValue(VID, FMath::FRand());
// 4. 编码初始位置到UV1(仅X和Y)
FVector2f EncodedPos;
EncodedPos.X = (LocalPos.X - BoxMin.X) / (BoxSize.X + 1e-6f);
EncodedPos.Y = (LocalPos.Y - BoxMin.Y) / (BoxSize.Y + 1e-6f);
UV1->SetElement(VID, EncodedPos);
// 5. 编码初始位置Z到顶点颜色.B通道(替换随机种子方案)
FColor VertexColor = Mesh.GetVertexColor(VID);
FLinearColor LinearColor(VertexColor);
LinearColor.B = (LocalPos.Z - BoxMin.Z) / (BoxSize.Z + 1e-6f); // Z坐标归一化
LinearColor.G = 0.0f; // 初始打磨度
Mesh.SetVertexColor(VID, LinearColor.ToFColor());
}
});
// 更新材质参数
if (DynamicMaterialInstance)
{
DynamicMaterialInstance->SetScalarParameterValue(TEXT("RustRoughness"), RustRoughness);
DynamicMaterialInstance->SetScalarParameterValue(TEXT("MetalRoughness"), MetalRoughness);
DynamicMaterialInstance->SetVectorParameterValue(TEXT("RustColor"), RustBaseColor);
DynamicMaterialInstance->SetVectorParameterValue(TEXT("MetalColor"), MetalBaseColor);
}
}
```
---
## 4. 锤击更新逻辑
### 4.1 打磨度更新
```cpp
void ADynamicIronBlock::OnHammerImpact(
FVector HitLocation,
FVector HitNormal,
float ImpactRadius,
float ImpactForce)
{
FVector LocalHitPos = GetTransform().InverseTransformPosition(HitLocation);
DynamicMesh->EditMesh([&](FDynamicMesh3& Mesh)
{
for (int32 VID : Mesh.VertexIndicesItr())
{
FVector VertexPos = Mesh.GetVertex(VID);
float Distance = FVector::Dist(VertexPos, LocalHitPos);
// 只更新受击区域
if (Distance < ImpactRadius)
{
// 计算打磨强度
float DistanceRatio = Distance / ImpactRadius;
float FalloffExponent = 2.0f;
float Intensity = FMath::Pow(1.0f - DistanceRatio, FalloffExponent);
// 打磨强度与力度成正比
float PolishIncrease = Intensity * ImpactForce * 0.001f; // 可调系数
// 累积打磨度(不可逆:只能增加,不能减少)
float CurrentPolish = PolishAmount->GetValue(VID);
float NewPolish = FMath::Min(1.0f, CurrentPolish + PolishIncrease);
PolishAmount->SetValue(VID, NewPolish);
// 同步到顶点颜色.G通道
FColor VertexColor = Mesh.GetVertexColor(VID);
FLinearColor LinearColor(VertexColor);
LinearColor.G = NewPolish;
Mesh.SetVertexColor(VID, LinearColor.ToFColor());
// 铁锈种子(顶点颜色.B)保持不变
// 初始位置Z(已在.B中)保持不变
}
}
});
}
```
### 4.2 氧化层更新(可选)
```cpp
void ADynamicIronBlock::UpdateOxideLayer(float DeltaTime)
{
if (!DynamicMesh->HasMesh())
return;
// 简化的氧化模型:
// - 高温(>300°C)时氧化加快
// - 打磨区域氧化较慢(新鲜表面)
DynamicMesh->EditMesh([&](FDynamicMesh3& Mesh)
{
for (int32 VID : Mesh.VertexIndicesItr())
{
float Temperature = SampleTemperatureAtVertex(Mesh, VID);
float Polish = PolishAmount->GetValue(VID);
// 氧化速率
float BaseOxidationRate = 0.01f; // 基础速率
float TemperatureFactor = FMath::Clamp((Temperature - 300.0f) / 1000.0f, 0.0f, 1.0f);
float PolishProtection = 1.0f - Polish * 0.8f; // 打磨后氧化慢
float OxidationRate = BaseOxidationRate * (1.0f + TemperatureFactor * 10.0f) * PolishProtection;
// 更新氧化层厚度
float CurrentOxide = OxideThickness->GetValue(VID);
float NewOxide = FMath::Min(1.0f, CurrentOxide + OxidationRate * DeltaTime);
OxideThickness->SetValue(VID, NewOxide);
}
});
}
```
---
## 5. 材质实现
### 5.1 材质图表结构
```
[VertexColor] ────────┐
├─> [Polish = VertexColor.g]
[TexCoord1] ─────────┘
[Polish] ──> [Lerp]
├─> [RustColor] (Polish=0)
└─> [MetalColor] (Polish=1)
[Polish] ──> [Lerp]
├─> [RustRoughness] (0.9)
└─> [MetalRoughness] (0.2)
[Polish] ──> [Lerp]
├─> [RustMetallic] (0.0)
└─> [MetalMetallic] (1.0)
[TextureCoordinate1] ──> [重建初始位置]
──> [噪声采样]
──> [铁锈图案]
```
### 5.2 HLSL实现(MF_SurfaceWear材质函数)
```hlsl
// 输入参数
float3 WorldPosition; // GetWorldPosition()
float3 WorldNormal; // GetWorldNormal()
float4 VertexColor; // GetVertexColor()
float2 TexCoord1; // GetTexCoord(1)
// 材质参数(从材质实例传入)
float3 RustColor; // 铁锈颜色
float3 MetalColor; // 金属颜色
float RustRoughness; // 铁锈粗糙度
float MetalRoughness; // 金属粗糙度
float RustMetallic; // 铁锈金属度(通常0)
float MetalMetallic; // 金属金属度(通常1)
// ===== 主函数 =====
// 1. 读取打磨度
float Polish = VertexColor.g; // 来自G通道
// 2. 重建初始位置(用于无漂移噪声采样)
// 假设包围盒是 [-50, 50] cm
float3 BoxMin = float3(-50.0, -50.0, -50.0);
float3 BoxMax = float3(50.0, 50.0, 50.0);
float3 BoxSize = BoxMax - BoxMin;
float InitialPosX = TexCoord1.x * BoxSize.x + BoxMin.x;
float InitialPosY = TexCoord1.y * BoxSize.y + BoxMin.y;
float InitialPosZ = VertexColor.b * BoxSize.z + BoxMin.z;
float3 InitialLocalPos = float3(InitialPosX, InitialPosY, InitialPosZ);
// 3. 基于初始位置采样噪声(空间连续,无漂移)
float RustSeedNoise = frac(InitialLocalPos.x * 0.1 + InitialLocalPos.y * 0.1 + InitialLocalPos.z * 0.1);
float RustMacro = PseudoRandom(RustSeedNoise * 100.0); // 宏观铁锈斑块
float RustDetail = Noise(InitialLocalPos * 20.0); // 细节纹理
float RustMicro = Noise(InitialLocalPos * 100.0); // 微观细节
// 组合多层噪声
float RustPattern = RustMacro * 0.6 + RustDetail * 0.3 + RustMicro * 0.1;
// 4. 计算最终颜色、金属度、粗糙度
float3 FinalRustColor = RustColor * (0.8 + RustPattern * 0.4); // 铁锈颜色变化
float3 FinalBaseColor = lerp(FinalRustColor, MetalColor, Polish);
float FinalMetallic = lerp(RustMetallic, MetalMetallic, Polish);
float FinalRoughness = lerp(RustRoughness, MetalRoughness, Polish);
// 5. 可选:添加划痕细节(基于初始位置的高频噪声)
float ScratchNoise = Noise(InitialLocalPos * 200.0) * 0.1;
FinalRoughness += ScratchNoise * (1.0 - Polish); // 划痕在未打磨区域更明显
// 6. 输出
return float4(FinalBaseColor, FinalRoughness, FinalMetallic, 1.0);
```
### 5.3 材质节点连接
```
材质输出:
Base Color ──> FinalBaseColor
Roughness ──> FinalRoughness
Metallic ──> FinalMetallic
Normal ───> [默认法线]
Ambient Occlusion ──> [可选]
```
---
## 6. 无漂移保证机制
### 6.1 问题示例
**错误做法(会漂移)**:
```hlsl
// 基于世界坐标采样噪声
float3 WorldPos = GetWorldPosition();
float Rust = Noise(WorldPos * 10.0);
// 问题:
// 锻打前: 顶点A在(100, 50, 0),Noise → 0.3(铁锈)
// 锻打后: 顶点A移动到(105, 52, 2),Noise → 0.8(变光亮?)
// 铁锈"滑走"了!
```
### 6.2 正确做法(无漂移)
**方案1:初始位置采样**
```hlsl
// 用初始的、不变的位置采样噪声
float3 InitialLocalPos = ReconstructInitialPosition(TexCoord1, VertexColor.b);
float Rust = Noise(InitialLocalPos * 10.0);
// 优点:
// - 顶点移动后,InitialLocalPos不变
// - 铁锈图案"锁定"在材料上
// - 空间连续:相邻顶点采样相似的噪声值
```
**方案2:种子采样**
```hlsl
// 用每个顶点的唯一种子采样
float Seed = VertexColor.b; // 0-1范围
float Rust = PseudoRandom(Seed * 1000.0);
// 优点:
// - 完全无漂移
// - 实现简单
// 缺点:
// - 空间不连续:相邻顶点可能有跳变
// - 需要高网格密度掩盖
```
**推荐**:方案1(初始位置采样)
### 6.3 完整的无漂移采样函数
```hlsl
/**
* 从UV1和顶点颜色重建初始位置
*/
float3 ReconstructInitialPosition(float2 TexCoord1, float EncodedZ)
{
// 假设包围盒 [-50, 50] cm
float3 BoxMin = float3(-50.0, -50.0, -50.0);
float3 BoxSize = float3(100.0, 100.0, 100.0);
float InitialX = TexCoord1.x * BoxSize.x + BoxMin.x;
float InitialY = TexCoord1.y * BoxSize.y + BoxMin.y;
float InitialZ = EncodedZ * BoxSize.z + BoxMin.z;
return float3(InitialX, InitialY, InitialZ);
}
/**
* 采样铁锈图案(无漂移版本)
*/
float3 SampleRustPattern(float2 TexCoord1, float EncodedZ, float3 WorldNormal)
{
// 重建初始位置
float3 InitialLocalPos = ReconstructInitialPosition(TexCoord1, EncodedZ);
// 多层噪声
float Rust1 = Noise(InitialLocalPos * 10.0 + float3(1.0, 2.0, 3.0)); // 低频
float Rust2 = Noise(InitialLocalPos * 30.0 + float3(4.0, 5.0, 6.0)); // 中频
float Rust3 = Noise(InitialLocalPos * 100.0 + float3(7.0, 8.0, 9.0)); // 高频
// 组合
float RustPattern = Rust1 * 0.5 + Rust2 * 0.3 + Rust3 * 0.2;
// 基于法线的变化(侧面铁锈更多)
float VerticalFactor = abs(WorldNormal.z); // z=0表示侧面
RustPattern *= (0.7 + VerticalFactor * 0.3);
return RustPattern;
}
```
---
## 7. 高级特性
### 7.1 大马士革钢层
```cpp
/**
* 标记大马士革层
* 在初始化时分配"材料ID"
*/
void InitializeDamascusLayers(FDynamicMesh3& Mesh)
{
TDynamicMeshVertexAttribute<int32>* MaterialLayerID =
new TDynamicMeshVertexAttribute<int32>(&Mesh);
for (int32 VID : Mesh.VertexIndicesItr())
{
FVector Pos = Mesh.GetVertex(VID);
// 简化的层状分布:基于Z坐标
int32 LayerID = (int32)FMath::Floor(Pos.Z / 2.0f) % 2; // 每2cm一层
MaterialLayerID->SetValue(VID, LayerID);
}
}
// 材质中基于LayerID选择颜色
float3 GetDamascusColor(float3 InitialLocalPos, float LayerID)
{
// 高碳钢层(深色)
float3 HighCarbonColor = float3(0.15, 0.1, 0.08);
// 低碳钢层(浅色)
float3 LowCarbonColor = float3(0.75, 0.7, 0.65);
// 混合过渡
float Mix = SmoothLayerPattern(InitialLocalPos);
return lerp(HighCarbonColor, LowCarbonColor, Mix);
}
```
### 7.2 划痕系统
```hlsl
// 基于初始位置的各向异性噪声(模拟划痕)
float3 InitialPos = ReconstructInitialPosition(TexCoord1, VertexColor.b);
// 方向性划痕(沿着锤击方向)
float ScratchDirection = InitialPos.x * 50.0; // X方向划痕
float ScratchPattern = Noise(float3(ScratchDirection, InitialPos.y * 20.0, 0.0));
float3 ScratchColor = lerp(float3(1.0, 1.0, 1.0), BaseColor, ScratchPattern);
float ScratchRoughness = Roughness * (1.0 + ScratchPattern * 0.5);
// 仅在部分区域应用
float ScratchMask = SmoothNoise(InitialPos * 15.0);
FinalBaseColor = lerp(FinalBaseColor, ScratchColor, ScratchMask * 0.3);
```
### 7.3 水渍和氧化
```hlsl
// 淬火时的水渍痕迹
float WaterStainMask = SampleWaterStainTexture(WorldPos);
float3 PatinaColor = float3(0.3, 0.4, 0.5); // 蓝绿色氧化
// 仅在潮湿区域显示
float HumidityFactor = 0.3; // 可调
FinalBaseColor = lerp(FinalBaseColor, FinalBaseColor * PatinaColor,
WaterStainMask * HumidityFactor);
```
---
## 8. 性能优化
### 8.1 材质优化
```hlsl
// 早期退出优化
float Polish = VertexColor.g;
if (Polish > 0.95)
{
// 完全打磨:直接返回金属色,跳过噪声计算
return MetalColor;
}
// LOD:基于距离减少噪声层数
float DistanceToCamera = length(View.WorldPosition);
int32 NoiseOctaves = DistanceToCamera < 100.0 ? 3 : 1;
```
### 8.2 顶点属性压缩
如果内存紧张,可以压缩属性:
```cpp
// 打磨度:8位精度足够
uint8 CompressedPolish = FMath::RoundToInt(PolishAmount * 255.0f);
PolishAmount->SetValue(VID, CompressedPolish / 255.0f);
// 初始位置:16位量化
FVector QuantizedPos(
FMath::RoundToInt(LocalPos.X * 100.0f) / 100.0f,
FMath::RoundToInt(LocalPos.Y * 100.0f) / 100.0f,
FMath::RoundToInt(LocalPos.Z * 100.0f) / 100.0f
);
```
---
## 9. 调试与可视化
### 9.1 可视化打磨度
```cpp
void ADynamicIronBlock::DebugDrawPolishHeatmap()
{
if (!DynamicMesh->HasMesh())
return;
for (int32 VID : DynamicMesh->VertexIndicesItr())
{
if (VID % 50 != 0) // 稀疏采样
continue;
float Polish = PolishAmount->GetValue(VID);
FVector WorldPos = GetActorTransform().TransformPosition(DynamicMesh->GetVertex(VID));
// 颜色映射:蓝色(0)→ 绿色(0.5)→ 红色(1.0)
FColor DebugColor = FMath::Lerp(
FColor::Blue,
FColor::Red,
Polish
);
DrawDebugPoint(GetWorld(), WorldPos, 5.0f, DebugColor, false, 5.0f);
}
}
```
### 9.2 材质调试模式
在材质中添加调试开关:
```hlsl
// 材质参数
int32 DebugMode; // 0=正常, 1=显示打磨度, 2=显示铁锈图案, 3=显示初始位置
float3 DebugOutput;
switch (DebugMode)
{
case 1: // 打磨度热图
DebugOutput = float3(Polish, 0.0, 1.0 - Polish);
break;
case 2: // 铁锈图案
DebugOutput = RustPattern;
break;
case 3: // 初始位置可视化
DebugOutput = frac(InitialLocalPos * 0.1);
break;
default:
DebugOutput = FinalBaseColor;
break;
}
return DebugOutput;
```
---
## 10. 已知限制与未来改进
### 10.1 当前限制
1. **顶点密度瓶颈**: 20-50万顶点的细节仍不及2048²纹理
2. **通道紧张**: 4个顶点颜色通道不够用,需要UV1补充
3. **无物理反射**: 打磨效果仅通过粗糙度模拟,无真实光线追踪
### 10.2 未来改进方向
1. **混合方案**: 顶点属性(大区域) + 纹理细节(微观)
2. **动态纹理**: 运行时更新高分辨率磨损纹理
3. **程序化细节**: 材质中用噪声补充细节
4. **多层材质**: 支持油污、涂层、水渍等多层效果
5. **法线贴图**: 从打磨度生成动态法线贴图
---
## 11. 引用
- 对应需求: [../requirements/02-表面磨损与外观需求.md](../requirements/02-表面磨损与外观需求.md)
- 总体架构: [00-锻造系统总体技术架构.md](00-锻造系统总体技术架构.md)
- 原始设计文档(归档): [../_archive/plans/2026-01-22-表面磨损系统细节.md](../_archive/plans/2026-01-22-表面磨损系统细节.md)
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,792 @@
# 物理模拟-加工硬化与晶粒演化设计
**项目**: BladeSmith
**文档类型**: 技术设计(专题)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-22-物理模拟架构细节.md`
> 本文档描述加工硬化与晶粒演化的技术实现。需求见 [../requirements/04-加工硬化与晶粒演化需求.md](../requirements/04-加工硬化与晶粒演化需求.md)。总体架构见 [00-锻造系统总体技术架构.md](00-锻造系统总体技术架构.md)。
>
> **注意**: 应力分布系统的详细技术内容见 [06-应力累积系统设计.md](06-应力累积系统设计.md)。淬火退火相变系统的详细技术内容见 [05-淬火退火相变系统设计.md](05-淬火退火相变系统设计.md)。本文档仅简要引用这两部分。
---
## 1. 技术背景
加工硬化(Work Hardening)和晶粒演化是锻造过程中的核心物理现象:
- **加工硬化**: 金属在塑性形变后变硬,屈服强度提高,机理是位错密度增加、晶格畸变。加热到再结晶温度(约600°C)后可软化。
- **晶粒演化**: 温度和应变影响微观组织。细晶粒高强度高韧性(Hall-Petch关系),粗晶粒高温下更容易形变。
---
## 2. 数据结构
### 2.1 扩展体素结构
```cpp
USTRUCT(BlueprintType)
struct FTemperatureVoxel
{
GENERATED_BODY()
// ===== 已有字段(保留) =====
UPROPERTY()
float Temperature; // 温度(°C)
UPROPERTY()
float PlasticityCoefficient; // 塑性系数(0-1)
UPROPERTY()
uint8 Flags; // 标志位(bit 0: 表面体素)
// ===== 新增字段 =====
// 平均应变率(记录形变活跃度)
UPROPERTY()
float AverageStrainRate; // 0-1范围,归一化的应变率
// 冷却速率(用于淬火判断,详见设计文档05)
UPROPERTY()
float CoolingRate; // °C/s
// 相态标记(详见设计文档05)
UPROPERTY()
EPhaseState PhaseState; // 奥氏体/马氏体/珠光体
// 淬火标记(是否经历过快速冷却,详见设计文档05)
UPROPERTY()
bool bHasBeenQuenched; // 淬火状态
FTemperatureVoxel()
: Temperature(20.0f)
, PlasticityCoefficient(0.0f)
, Flags(0)
, AverageStrainRate(0.0f)
, CoolingRate(0.0f)
, PhaseState(EPhaseState::Austenite) // 初始为奥氏体
, bHasBeenQuenched(false)
{}
};
```
### 2.2 相态枚举
```cpp
/**
* 相态枚举
* 相变系统详细内容见设计文档05
*/
UENUM(BlueprintType)
enum class EPhaseState : uint8
{
Austenite UMETA(DisplayName = "奥氏体"), // 高温软相(>800°C)
Martensite UMETA(DisplayName = "马氏体"), // 淬火硬相
Pearlite UMETA(DisplayName = "珠光体"), // 缓冷软相
Bainite UMETA(DisplayName = "贝氏体"), // 中间相
Cracked UMETA(DisplayName = "开裂") // 永久缺陷
};
```
### 2.3 顶点属性结构
```cpp
class ADynamicIronBlock
{
private:
// ===== 顶点自定义属性层 =====
// 初始位置(用于无漂移纹理采样)
TDynamicMeshVertexAttribute<FVector>* InitialPositions;
// 累积塑性应变(0-1,归一化)
TDynamicMeshVertexAttribute<float>* AccumulatedStrain;
// 当前硬度系数(0-1,0=最软,1=最硬)
TDynamicMeshVertexAttribute<float>* HardnessCoefficient;
// 打磨度(表面状态,0=生锈,1=光亮)
TDynamicMeshVertexAttribute<float>* PolishAmount;
// 晶粒尺寸(0-1,归一化,0=细晶粒,1=粗晶粒)
TDynamicMeshVertexAttribute<float>* GrainSize;
// 应力值(简化标量,0-1,0=无应力,1=高应力)
// 应力系统详细内容见设计文档06
TDynamicMeshVertexAttribute<float>* StressValue;
// 应力方向(可选,三维向量)
TDynamicMeshVertexAttribute<FVector>* StressDirection;
public:
// 初始化所有顶点属性
void InitializeVertexAttributes();
};
```
---
## 3. 加工硬化模型
### 3.1 物理原理
加工硬化(Work Hardening):
- **现象**: 金属在塑性形变后变硬,屈服强度提高
- **机理**: 位错密度增加,晶格畸变
- **可逆性**: 加热到再结晶温度(约600°C)后软化
### 3.2 应变-硬度映射
```cpp
/**
* 应变-硬度映射(简化经验公式)
* 基于真实钢的应力-应变曲线拟合
*/
float CalculateHardnessFromStrain(float AccumulatedStrain)
{
// 参数(可调)
const float InitialHardness = 0.2f; // 初始硬度
const float MaxHardness = 1.0f; // 最大硬度
const float SaturationStrain = 0.5f; // 饱和应变
// Ludwik方程简化版:σ = σ₀ + k·εⁿ
float HardnessIncrease = MaxHardness - InitialHardness;
float StrainEffect = FMath::Pow(AccumulatedStrain / SaturationStrain, 0.5f);
return InitialHardness + HardnessIncrease * FMath::Min(StrainEffect, 1.0f);
}
```
### 3.3 温度软化因子
高温下硬度降低(模拟动态回复)。
```cpp
/**
* 温度软化因子
* 高温下硬度降低(模拟动态回复)
*/
float CalculateThermalSoftening(float Temperature, float Hardness)
{
// 再结晶温度(简化)
const float RecrystallizationTemp = 600.0f; // °C
if (Temperature < RecrystallizationTemp)
return Hardness; // 低温:无软化
// 高温:软化
float Overheating = Temperature - RecrystallizationTemp;
float SofteningFactor = FMath::Clamp(Overheating / 400.0f, 0.0f, 0.8f);
return Hardness * (1.0f - SofteningFactor);
}
```
### 3.4 锤击时更新硬度和应变
```cpp
/**
* 锤击时更新硬度和应变
*/
void ADynamicIronBlock::OnHammerImpact(
FVector HitLocation,
float ImpactRadius,
float ImpactForce)
{
FVector LocalHitPos = GetTransform().InverseTransformPosition(HitLocation);
DynamicMesh->EditMesh([&](FDynamicMesh3& Mesh)
{
for (int32 VID : Mesh.VertexIndicesItr())
{
FVector VertexPos = Mesh.GetVertex(VID);
float Distance = FVector::Dist(VertexPos, LocalHitPos);
if (Distance < ImpactRadius)
{
// 1. 计算局部形变量(简化)
float DistanceRatio = Distance / ImpactRadius;
float LocalDeformation = FMath::Pow(1.0f - DistanceRatio, 2.0f);
float StrainIncrease = LocalDeformation * ImpactForce * 0.0001f;
// 2. 累积应变
float CurrentStrain = AccumulatedStrain->GetValue(VID);
float NewStrain = FMath::Min(1.0f, CurrentStrain + StrainIncrease);
AccumulatedStrain->SetValue(VID, NewStrain);
// 3. 从温度体素采样温度
FVector VoxelPos = VertexPos / VoxelSize;
float Temperature = SampleTemperatureFromVoxel(VoxelPos);
// 4. 计算硬度(应变硬化)
float StrainHardness = CalculateHardnessFromStrain(NewStrain);
// 5. 温度软化
float FinalHardness = CalculateThermalSoftening(Temperature, StrainHardness);
// 6. 更新硬度
HardnessCoefficient->SetValue(VID, FinalHardness);
// 7. 硬度影响形变阻力(可选:反馈到形变计算)
// 下一锤击时,高硬度区域形变小
}
}
});
}
```
---
## 4. 晶粒演化模型
### 4.1 物理原理
晶粒尺寸影响材料特性:
- **细晶粒**: 高强度、高韧性(Hall-Petch关系)
- **粗晶粒**: 高温下更容易形变
晶粒演化因素:
- **再结晶**: 高温+应变 → 新晶粒形成
- **晶粒长大**: 高温下晶粒合并
- **晶粒细化**: 大应变+低温 → 细化
### 4.2 晶粒尺寸演化
```cpp
/**
* 晶粒尺寸演化(简化标量模型)
*/
float EvolveGrainSize(
float CurrentGrainSize, // 当前晶粒尺寸(归一化0-1)
float Temperature, // 当前温度(°C)
float Strain, // 累积应变
float DeltaTime) // 时间步长
{
const float RecrystallizationTemp = 600.0f;
const float GrainGrowthTemp = 900.0f;
// 1. 再结晶:大应变+高温 → 晶粒细化
if (Temperature > RecrystallizationTemp && Strain > 0.3f)
{
float RecrystallizationRate = 0.1f; // 可调
return CurrentGrainSize * (1.0f - RecrystallizationRate * DeltaTime);
}
// 2. 晶粒长大:高温 → 晶粒粗化
if (Temperature > GrainGrowthTemp)
{
float GrowthRate = 0.05f * (Temperature - GrainGrowthTemp) / 300.0f;
return FMath::Min(1.0f, CurrentGrainSize * (1.0f + GrowthRate * DeltaTime));
}
// 3. 晶粒细化:大应变 → 晶粒细化
if (Strain > 0.5f)
{
float RefinementRate = 0.02f;
return FMath::Max(0.1f, CurrentGrainSize * (1.0f - RefinementRate * DeltaTime));
}
return CurrentGrainSize;
}
```
### 4.3 更新顶点晶粒尺寸
```cpp
/**
* 更新顶点晶粒尺寸
*/
void ADynamicIronBlock::UpdateGrainStructure(float DeltaTime)
{
DynamicMesh->EditMesh([&](FDynamicMesh3& Mesh)
{
for (int32 VID : Mesh.VertexIndicesItr())
{
float CurrentGrainSize = GrainSize->GetValue(VID);
float Strain = AccumulatedStrain->GetValue(VID);
// 采样温度
FVector Pos = Mesh.GetVertex(VID);
float Temperature = SampleTemperatureFromVoxel(Pos);
// 演化晶粒尺寸
float NewGrainSize = EvolveGrainSize(CurrentGrainSize, Temperature, Strain, DeltaTime);
GrainSize->SetValue(VID, NewGrainSize);
}
});
}
```
### 4.4 大马士革花纹模拟
```cpp
/**
* 初始化层状材料(用于大马士革钢)
*/
void InitializeLayeredMaterialStructure()
{
DynamicMesh->EditMesh([&](FDynamicMesh3& Mesh)
{
TDynamicMeshVertexAttribute<int32>* MaterialLayerID =
new TDynamicMeshVertexAttribute<int32>(&Mesh);
for (int32 VID : Mesh.VertexIndicesItr())
{
FVector Pos = Mesh.GetVertex(VID);
// 简单层状分布:沿Z轴
// 每层厚度2mm
int32 LayerID = (int32)FMath::Floor(Pos.Z / 2.0f) % 2;
MaterialLayerID->SetValue(VID, LayerID);
}
});
}
```
### 4.5 大马士革花纹材质HLSL
```hlsl
// 材质中基于MaterialLayerID采样不同颜色
float LayerID = MaterialLayerAttribute; // 从顶点属性读取
float3 HighCarbonColor = float3(0.15, 0.1, 0.08); // 深色层
float3 LowCarbonColor = float3(0.75, 0.7, 0.65); // 浅色层
float3 BaseColor = lerp(HighCarbonColor, LowCarbonColor, LayerID);
// 添加扭曲(基于形变)
float Distortion = length(AccumulatedStrain) * 5.0;
float3 WarpedPattern = WarpedNoise(BaseColor, Distortion);
FinalColor = BaseColor * (0.8 + WarpedPattern * 0.2);
```
---
## 5. GPU Compute Shader集成
### 5.1 Shader结构
```
MiceShaders/Source/MiceShaders/Private/
├── MetallurgyComputeShader.usf
├── MetallurgyComputeShader.h
└── MetallurgyComputeShader.cpp
```
### 5.2 Metallurgy Compute Shader HLSL
```hlsl
// MetallurgyComputeShader.usf
#define VOXEL_SIZE 50
#define THREAD_COUNT 32
// 输入/输出缓冲区
RWStructuredBuffer<float4> TemperatureBufferA; // 温度 + 塑性系数
RWStructuredBuffer<float4> TemperatureBufferB; // Ping-Pong
RWStructuredBuffer<float4> MetallurgyBuffer; // 应变率 + 冷却速率 + 相态 + 淬火标记
// 参数
cbuffer MetallurgyParams
{
float DeltaTime;
float3 VoxelWorldMin;
float VoxelSize;
float3 Padding;
};
/**
* 计算 Metallurgy Shader 主函数
*/
[numthreads(THREAD_COUNT, THREAD_COUNT, 1)]
void MetallurgyComputeShader(uint3 ThreadId : SV_DispatchThreadID)
{
uint VoxelIndex = ThreadId.x + ThreadId.y * VoxelSize;
// 读取温度
float Temperature = TemperatureBufferA[VoxelIndex].r;
float Plasticity = TemperatureBufferA[VoxelIndex].g;
// 读取应变率
float StrainRate = MetallurgyBuffer[VoxelIndex].r;
// 1. 应变率衰减(模拟时效)
StrainRate *= 0.99;
// 2. 计算冷却速率(相变判断基础,详见设计文档05)
float3 WorldPos = VoxelToWorldPosition(VoxelIndex);
float SurfaceFactor = IsSurfaceVoxel(WorldPos) ? 1.0 : 0.1;
float CoolingRate = SurfaceFactor * (Temperature - 20.0) * 0.1;
// 3. 相态判断(详细相变逻辑见设计文档05)
uint PhaseState = 0; // 奥氏体
if (CoolingRate > 100.0 && Temperature > 800.0)
{
PhaseState = 1; // 马氏体(淬火)
}
else if (Temperature < 600.0)
{
PhaseState = 2; // 珠光体(缓冷)
}
// 写回
MetallurgyBuffer[VoxelIndex] = float4(StrainRate, CoolingRate, PhaseState, 0.0);
}
/**
* 辅助函数:体素索引转世界坐标
*/
float3 VoxelToWorldPosition(uint Index)
{
uint X = Index % VoxelSize;
uint Y = (Index / VoxelSize) % VoxelSize;
uint Z = Index / (VoxelSize * VoxelSize);
return VoxelWorldMin + float3(X, Y, Z) * VoxelSize;
}
/**
* 辅助函数:判断是否为表面体素
*/
bool IsSurfaceVoxel(float3 WorldPos)
{
// 简化:边界体素为表面
// 实际应使用法线判断
return false;
}
```
### 5.3 C++ Shader封装
```cpp
// MetallurgyComputeShader.h
class FMetallurgyComputeShader
{
public:
static void Dispatch(
FRHICommandListImmediate& RHICmdList,
FStructuredBufferRHIRef TemperatureBufferA,
FStructuredBufferRHIRef TemperatureBufferB,
FStructuredBufferRHIRef MetallurgyBuffer,
float DeltaTime,
FIntVector VoxelResolution);
};
```
### 5.4 C++ Shader调用
```cpp
// MetallurgyComputeShader.cpp
void FMetallurgyComputeShader::Dispatch(
FRHICommandListImmediate& RHICmdList,
FStructuredBufferRHIRef TemperatureBufferA,
FStructuredBufferRHIRef TemperatureBufferB,
FStructuredBufferRHIRef MetallurgyBuffer,
float DeltaTime,
FIntVector VoxelResolution)
{
// 设置Shader
TShaderMapRef<FMetallurgyComputeShader> ComputeShader(GetGlobalShaderMap(GMaxRHIFeatureLevel));
// 设置参数
RHICmdList.SetComputeShader(ComputeShader.GetComputeShader());
ComputeShader->SetParameters(RHICmdList, TemperatureBufferA, TemperatureBufferB,
MetallurgyBuffer, DeltaTime, VoxelMin, VoxelSize);
// Dispatch
int32 ThreadGroupCount = (VoxelResolution.X + 31) / 32;
RHICmdList.DispatchComputeShader(ThreadGroupCount, ThreadGroupCount, 1);
}
```
### 5.5 异步Dispatch模式
```cpp
ENQUEUE_RENDER_COMMAND(FMetallurgyComputeDispatch)(
[this, DeltaTime](FRHICommandListImmediate& RHICmdList)
{
FMetallurgyComputeShader::Dispatch(
RHICmdList,
TemperatureBufferA,
TemperatureBufferB,
MetallurgyBuffer,
DeltaTime,
TemperatureResolution
);
bMetallurgyComputeComplete = true;
}
);
// CPU 继续其他工作,不等待GPU
```
---
## 6. 材质可视化
### 6.1 硬度可视化
```hlsl
// 材质中:基于硬度调整颜色
float Hardness = SampleHardnessFromVoxel(WorldPos);
float3 SoftColor = float3(0.6, 0.5, 0.4); // 软:棕色
float3 HardColor = float3(0.8, 0.8, 0.85); // 硬:银白色
float3 HardnessColor = lerp(SoftColor, HardColor, Hardness);
```
### 6.2 应力可视化
**注意**: 应力分布系统的详细可视化见 [06-应力累积系统设计.md](06-应力累积系统设计.md)。此处为简要引用。
```hlsl
// 顶点颜色.A通道存储应力
float Stress = VertexColor.a;
float3 LowStressColor = float3(0.3, 0.5, 0.7); // 低应力:蓝色
float3 HighStressColor = float3(1.0, 0.3, 0.1); // 高应力:红色
float3 StressColor = lerp(LowStressColor, HighStressColor, Stress);
// 混合到基础颜色
BaseColor = lerp(BaseColor, StressColor, Stress * 0.5);
```
### 6.3 相态可视化
**注意**: 淬火相变系统的详细可视化见 [05-淬火退火相变系统设计.md](05-淬火退火相变系统设计.md)。此处为简要引用。
```hlsl
// 从体素采样相态
float PhaseState = SamplePhaseStateFromVoxel(WorldPos);
float3 AusteniteColor = float3(1.0, 0.8, 0.6); // 奥氏体:浅橙色
float3 MartensiteColor = float3(0.9, 0.85, 0.8); // 马氏体:银白色
float3 PearliteColor = float3(0.7, 0.6, 0.5); // 珠光体:深灰色
float3 PhaseColor;
if (PhaseState < 0.5)
PhaseColor = AusteniteColor;
else if (PhaseState < 1.5)
PhaseColor = MartensiteColor;
else
PhaseColor = PearliteColor;
// 根据温度过渡
float Temp = SampleTemperatureFromVoxel(WorldPos);
float MixFactor = smoothstep(600.0, 800.0, Temp);
BaseColor = lerp(PhaseColor, AusteniteColor, MixFactor);
```
---
## 7. 性能优化
### 7.1 GPU优化策略
```cpp
// 1. 使用共享内存(GroupShared)
groupshared float SharedTemperature[THREAD_COUNT * THREAD_COUNT];
// 2. 波前优化(Wave Intrinsics)
uint WaveSize = GetWaveSize();
float WaveSum = WaveActiveSum(StrainRate);
// 3. 避免分支 divergence
if (CoolingRate > 100.0) // 差:条件跳转
PhaseState = 1.0;
PhaseState = step(100.0, CoolingRate); // 好:无分支
```
### 7.2 CPU-GPU异步
```cpp
// 异步Dispatch
ENQUEUE_RENDER_COMMAND(FMetallurgyComputeDispatch)(
[this, DeltaTime](FRHICommandListImmediate& RHICmdList)
{
FMetallurgyComputeShader::Dispatch(
RHICmdList,
TemperatureBufferA,
TemperatureBufferB,
MetallurgyBuffer,
DeltaTime,
TemperatureResolution
);
// 标记完成
bMetallurgyComputeComplete = true;
}
);
// CPU继续其他工作,不用等待GPU
```
### 7.3 LOD策略
```cpp
// 根据摄像机距离调整计算频率
float DistanceToCamera = FVector::Dist(GetActorLocation(), CameraLocation);
int32 ComputeFrequency;
if (DistanceToCamera < 200.0f)
ComputeFrequency = 1; // 每帧计算
else if (DistanceToCamera < 500.0f)
ComputeFrequency = 2; // 每2帧计算
else
ComputeFrequency = 5; // 每5帧计算
static int32 FrameCounter = 0;
if (++FrameCounter % ComputeFrequency == 0)
{
DispatchMetallurgyComputeShader();
}
```
---
## 8. 参数配置示例
### 8.1 碳钢(C105)
```cpp
// 加工硬化参数
InitialHardness = 0.25f;
SaturationStrain = 0.6f;
WorkHardeningExponent = 0.55f;
// 相变参数(详见设计文档05)
AustenitizingTemp = 800.0f;
QuenchingCriticalRate = 120.0f;
MartensiteHardness = 0.95f;
// 晶粒参数
InitialGrainSize = 0.5f;
RecrystallizationTemp = 650.0f;
```
### 8.2 高碳钢(C150)
```cpp
// 更容易硬化
InitialHardness = 0.35f;
SaturationStrain = 0.4f;
// 淬火更敏感(详见设计文档05)
QuenchingCriticalRate = 80.0f; // 更容易淬火
MartensiteHardness = 1.0f; // 更硬
```
### 8.3 低碳钢(C20)
```cpp
// 难硬化
InitialHardness = 0.15f;
SaturationStrain = 0.8f;
// 难淬火(详见设计文档05)
QuenchingCriticalRate = 200.0f; // 很难淬火
MartensiteHardness = 0.7f;
```
---
## 9. 调试工具
### 9.1 体素数据可视化
```cpp
void ADynamicIronBlock::DebugDrawVoxelData()
{
for (int32 Z = 0; Z < TemperatureResolution.Z; ++Z)
{
for (int32 Y = 0; Y < TemperatureResolution.Y; ++Y)
{
for (int32 X = 0; X < TemperatureResolution.X; ++X)
{
FIntVector Coord(X, Y, Z);
int32 Index = GetTemperatureIndex(Coord);
const FTemperatureVoxel& Voxel = TemperatureGrid[Index];
// 只绘制表面体素
if (!(Voxel.Flags & VOXEL_FLAG_SURFACE))
continue;
FVector WorldPos = VoxelCoordToWorldPos(Coord);
// 颜色:温度
FLinearColor Color = FLinearColor(
FMath::Clamp(Voxel.Temperature / 1200.0f, 0.0f, 1.0f),
0.0f,
1.0f - FMath::Clamp(Voxel.Temperature / 1200.0f, 0.0f, 1.0f)
);
DrawDebugPoint(GetWorld(), WorldPos, 3.0f, Color.ToFColor(), false, 0.1f);
}
}
}
}
```
### 9.2 应力热图
**注意**: 应力热图的详细实现见 [06-应力累积系统设计.md](06-应力累积系统设计.md)。此处为简要引用。
```cpp
void ADynamicIronBlock::DebugDrawStressHeatmap()
{
if (!DynamicMesh->HasMesh())
return;
for (int32 VID : DynamicMesh->VertexIndicesItr())
{
if (VID % 50 != 0) // 稀疏采样
continue;
float Stress = StressValue->GetValue(VID);
FVector WorldPos = GetActorTransform().TransformPosition(DynamicMesh->GetVertex(VID));
// 蓝色(低应力)→ 红色(高应力)
FColor HeatColor = FLinearColor::LerpUsingHSV(
FColor::Blue,
FColor::Red,
Stress
).ToFColor();
DrawDebugPoint(GetWorld(), WorldPos, 5.0f, HeatColor, false, 5.0f);
}
}
```
---
## 10. 已知限制与未来改进
### 10.1 当前限制
1. **简化模型**: 所有物理模型均为经验公式,非严格物理计算
2. **无热-力耦合**: 温度场和应力场独立计算,未考虑形变生热
3. **无磁-电效应**: 忽略了电磁场对相变的影响
4. **各向同性**: 假设材料各向同性,真实钢有晶粒取向
5. **晶粒模型极度简化**: 真实晶粒有复杂3D形状与取向,当前用标量GrainSize
### 10.2 适用场景
游戏娱乐级,足够真实感但非科研级精度。
---
## 11. 引用
- 对应需求: [../requirements/04-加工硬化与晶粒演化需求.md](../requirements/04-加工硬化与晶粒演化需求.md)
- 总体架构: [00-锻造系统总体技术架构.md](00-锻造系统总体技术架构.md)
- 原始设计文档(归档): [../_archive/plans/2026-01-22-物理模拟架构细节.md](../_archive/plans/2026-01-22-物理模拟架构细节.md)
- 相关专题(淬火系统): [05-淬火退火相变系统设计.md](05-淬火退火相变系统设计.md)
- 相关专题(应力系统): [06-应力累积系统设计.md](06-应力累积系统设计.md)
@@ -0,0 +1,470 @@
# 淬火退火相变系统设计
**项目**: BladeSmith
**文档类型**: 技术设计(专题)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-23-淬火退火相变系统设计.md`
> 本文档描述淬火退火相变系统的技术实现。需求见 [../requirements/05-淬火退火相变需求.md]。总体架构见 [00-锻造系统总体技术架构.md](00-锻造系统总体技术架构.md)。
---
## 1. 技术背景
淬火退火相变系统模拟热处理过程中的相变行为,基于温度和冷却速率计算材料状态变化。系统通过温度区间判定、冷却速率计算、相态判定、硬度/脆性计算以及三阶段可视化,实现真实的热处理效果模拟。
---
## 2. 温度区间判定
### 2.1 温度阈值定义
**三个关键温度阈值**:
| 阈值名称 | 温度范围 | 效果 |
|---------|---------|------|
| 临界下限 | < 800°C | 淬火无效,硬度无提升 |
| 黄金区间 | 900-1100°C | 最佳淬火,硬度最大提升 |
| 临界上限 | > 1200°C | 材料开裂风险,硬度提升低 |
### 2.2 温度区间修正系数
**TemperatureFactor 公式**:
```
TemperatureFactor =
3.0 (900°C ≤ T ≤ 1100°C, 黄金区间)
1.8 (800°C ≤ T < 900°C 或 1100°C < T ≤ 1200°C, 次优区间)
0.5 (T < 800°C, 温度过低)
0.2 (T > 1200°C, 温度过高且可能开裂)
```
---
## 3. 冷却速率计算
### 3.1 基础冷却速率公式
```
CoolingRate = |T_current - T_previous| / Δt
```
**参数说明**:
- `T_current`: 当前帧体素温度
- `T_previous`: Δt时间前的体素温度
- `Δt`: 采样时间窗口(推荐0.5-1.0秒)
### 3.2 滑动平均平滑
**平滑公式**:
```
CoolingRate_smoothed = Σ(CoolingRate_i) / N (i=1 to N, N=10)
```
使用过去10帧的平均值,消除瞬时波动。
---
## 4. 硬度映射系统
### 4.1 硬度倍数公式
**基于冷却速率的Sigmoid函数**:
```
HardnessMultiplier = BaseMultiplier × Sigmoid(CoolingRate)
```
其中:
```
Sigmoid(CoolingRate) = 1 + 2 / (1 + exp(-k × (CoolingRate - Threshold)))
```
**参数说明**:
- `BaseMultiplier = 1.0`: 基准倍数
- `Threshold = 35°C/s`: 中点冷却速率
- `k = 0.1`: 曲线陡峭度(可调节)
### 4.2 冷却速率分类
| 冷却速率 | 范围 | 淬火方式 | 硬度表现 |
|---------|------|---------|---------|
| 快速冷却 | > 50°C/s | 水淬 | 硬度最高 |
| 中速冷却 | 20-50°C/s | 油淬 | 硬度适中 |
| 慢速冷却 | < 20°C/s | 空冷 | 硬度低(退火) |
### 4.3 最终硬度计算
**综合硬度公式**:
```
FinalHardness = InitialHardness × HardnessMultiplier × TemperatureFactor
```
### 4.4 硬度对形变的影响
**形变阻力公式**:
```
HardnessFactor = 1.0 + (Hardness / MaxHardness) × 2.0
```
硬度越高,形变阻力越大(最大3倍阻力)。
---
## 5. 脆性计算系统
### 5.1 脆性系数公式
**基础脆性公式**:
```
Brittleness = BaseBrittleness + BrittlenessIncrease × CoolingRate_normalized
```
**参数说明**:
- `BaseBrittleness = 0.1`: 基准脆性(未经淬火的钢)
- `BrittlenessIncrease = 0.6`: 最大脆性增加量
- `CoolingRate_normalized`: 归一化冷却速率
**归一化公式**:
```
CoolingRate_normalized = clamp(CoolingRate / 80°C/s, 0, 1)
```
### 5.2 脆性对开裂的影响
脆性系数与开裂概率直接相关,详见应力系统文档。
### 5.3 脆性可视化阈值
| 脆性范围 | 颜色 | 含义 |
|---------|------|------|
| < 0.3 | 绿色 | 韧性良好 |
| 0.3 - 0.6 | 黄色 | 中度脆性 |
| ≥ 0.6 | 红色 | 高度脆性 |
---
## 6. 内部应力公式
### 6.1 应力分量
**热应力分量(温度梯度)**:
```
StressThermal = ThermalStressCoeff × CoolingRate × (T_current - 20°C)
```
**参数说明**:
- `ThermalStressCoeff = 0.005`: 热应力系数(可调)
- `T_current`: 当前温度(°C)
- 20°C: 环境温度
**相变应力分量(马氏体体积膨胀)**:
```
StressPhase = PhaseStressCoeff × MartensiteFraction
```
**参数说明**:
- `PhaseStressCoeff = 50.0`: 相变应力系数
- `MartensiteFraction`: 马氏体转化比例
**马氏体转化比例公式**:
```
MartensiteFraction = clamp(CoolingRate / 80°C/s, 0, 1)
```
### 6.2 总应力
**综合应力公式**:
```
InternalStress = StressThermal + StressPhase
```
### 6.3 应力松弛机制
**温度驱动的松弛公式**:
```
RelaxationFactor =
0.99 (T < 100°C, 常温慢松弛)
0.90 (200°C ≤ T < 400°C, 回火快松弛)
0.85 (T ≥ 400°C, 快速松弛)
```
**每帧更新**:
```
InternalStress = InternalStress × RelaxationFactor
```
---
## 7. 相态系统
### 7.1 相态枚举
**EPhaseState 定义**:
```cpp
UENUM(BlueprintType)
enum class EPhaseState : uint8
{
Austenite = 0, // 奥氏体(软)
Martensite = 1, // 马氏体(硬)
Pearlite = 2, // 珠光体(中)
Cracked = 3 // 开裂(永久缺陷)
};
```
### 7.2 相变判定规则
**奥氏体→马氏体(淬火)**:
```cpp
if (Temperature > 800°C && CoolingRate > 20°C/s)
{
PhaseState = EPhaseState::Martensite;
// 硬度和脆性提升
}
```
**奥氏体→珠光体(退火)**:
```cpp
if (Temperature > 800°C && CoolingRate < 20°C/s)
{
PhaseState = EPhaseState::Pearlite;
// 硬度适中,脆性低
}
```
**重置相态**:
```cpp
if (Temperature > 800°C && TimeAbove800C > 5.0s)
{
PhaseState = EPhaseState::Austenite;
// 材料回到软态,可重新淬火
}
```
---
## 8. 三阶段可视化设计
### 8.1 阶段1:淬火过程(临时高辨识度)
**顶点颜色强制覆盖**:
```hlsl
// R通道:温度的互补色
R = 1.0 - Temperature / MaxTemperature
// G通道:冷却速率(快=绿色,慢=红色)
G = clamp(1.0 - CoolingRate / 80°C/s, 0, 1)
// B通道:硬度倍数(暗色=软,亮色=硬)
B = (Hardness - MinHardness) / (MaxHardness - MinHardness)
// A通道:脆性(透明=韧性,不透明=脆)
A = Brittleness
```
**材质临时参数**:
- 自发光:启用,随温度变化
- 金属度:暂时设为1.0(全金属感)
- 粗糙度:暂时设为0.0(镜面反光)
### 8.2 阶段2:冷却过渡(逐步恢复正常)
**颜色过渡公式**(0.5-1.0秒):
```hlsl
// 插值因子
Alpha = (CurrentTime - QuenchStartTime) / TransitionDuration
// R通道:温度回归到常温
R = Lerp(TemporaryR, 0.0, Alpha)
// G通道:恢复到打磨度
G = Lerp(TemporaryG, PolishAmount, Alpha)
// B通道:恢复到噪声种子
B = Lerp(TemporaryB, NoiseSeed, Alpha)
// A通道:保留相态标记
A = PhaseState // 0=奥氏体, 1=马氏体, 2=珠光体, 3=开裂
```
**材质过渡**:
```hlsl
// 自发光:指数衰减至0
Emissive = TemporaryEmissive × exp(-Alpha × 5.0)
// 金属度/粗糙度:恢复到打磨度驱动
Metallic = 0.5 + PolishAmount × 0.5
Roughness = 0.6 - PolishAmount × 0.4
```
### 8.3 阶段3:最终真实表现(永久保留)
#### 8.3.1 回火色系统
**回火色映射表**:
| 回火温度 | 颜色 | RGB值 |
|---------|------|-------|
| 20-150°C(无回火) | 银灰色 | (0.8, 0.8, 0.8) |
| 150-200°C | 淡黄色 | (0.95, 0.9, 0.7) |
| 200-250°C | 金黄/麦秆色 | (0.95, 0.8, 0.4) |
| 250-300°C | 棕色 | (0.7, 0.5, 0.3) |
| 300-350°C | 紫色 | (0.6, 0.4, 0.7) |
| 350-400°C | 蓝色 | (0.4, 0.5, 0.8) |
| >400°C | 灰色 | (0.6, 0.6, 0.6) |
实现方式: 根据最后回火温度设置顶点TemperColor属性。
#### 8.3.2 氧化层表现
**OxidationLevel 属性定义**(0-1):
| 冷却介质 | OxidationLevel | 视觉效果 |
|---------|---------------|---------|
| 水淬 | 0.8-1.0 | 深色氧化层 |
| 油淬 | 0.4-0.6 | 浅棕色氧化层 |
| 空冷 | 0.1-0.3 | 轻微氧化 |
#### 8.3.3 最终材质组合
**基础颜色公式**:
```hlsl
BaseColor = OxidationColor × (1 - PolishAmount) + TemperColor × PolishAmount
```
**参数说明**:
- `OxidationColor`: 基于OxidationLevel的深灰色
- `TemperColor`: 基于TemperColor的回火色
- `PolishAmount`: 打磨度(打磨后露出金属底色)
#### 8.3.4 相态的微妙影响
虽然马氏体组织肉眼不可见,但通过细微色调表现:
- 马氏体区域: 略微更冷色调(蓝灰倾向)
- 珠光体区域: 略微更暖色调(棕灰倾向)
- 奥氏体区域: 中性灰调
---
## 9. 实现架构
### 9.1 GPU-CPU分工
**GPU Compute Shader职责**:
- 体素层面热力学计算
- 温度场更新
- 冷却速率计算(滑动平均)
- 相态判定
- 热应力计算
**CPU职责**:
- 顶点属性更新
- 硬度/脆性公式应用
- 相态采样到顶点
- 三阶段可视化逻辑
- 材质参数更新
### 9.2 数据流
```
温度更新(GPU)
↓
冷却速率计算(GPU)
↓
相态判定(GPU)
↓
硬度/脆性公式(CPU)
↓
顶点属性更新(CPU)
↓
材质可视化(CPU)
```
### 9.3 性能优化
**冷却速率计算**:
- 使用Ping-Pong双缓冲避免冲突
- 滑动平均使用历史缓冲,减少计算量
**相态判定**:
- 只在温度变化时重新计算
- 使用标志位避免重复判定
**可视化**:
- 临时效果使用简单着色器
- 最终效果复用现有材质系统
---
## 10. 参数配置
### 10.1 可调参数(蓝图可配)
| 参数名 | 默认值 | 范围 | 说明 |
|-------|--------|------|------|
| `CriticalTempLow` | 800.0°C | 600-900 | 临界下限 |
| `CriticalTempHigh` | 1200.0°C | 1100-1400 | 临界上限 |
| `GoldTempMin` | 900.0°C | 800-1000 | 黄金区间下限 |
| `GoldTempMax` | 1100.0°C | 1000-1200 | 黄金区间上限 |
| `CoolingRateThreshold` | 35.0°C/s | 20-50 | Sigmoid中点 |
| `SigmoidK` | 0.1 | 0.05-0.2 | 曲线陡峭度 |
| `ThermalStressCoeff` | 0.005 | 0.001-0.01 | 热应力系数 |
| `PhaseStressCoeff` | 50.0 | 20-100 | 相变应力系数 |
| `RelaxationTimeNormal` | 60.0s | 30-120 | 常温松弛时间 |
| `RelaxationTimeTemper` | 10.0s | 5-20 | 回火松弛时间 |
### 10.2 调试工具
- 体素可视化:显示温度、冷却速率、相态
- 顶点属性检查:硬度、脆性、应力值
- 时间线:记录淬火-回火过程
- 统计面板:覆盖率、平均硬度、最大脆性
---
## 11. 实施计划
### 11.1 第一阶段:核心公式(1天)
- 冷却速率计算
- 硬度/脆性公式
- 相态判定逻辑
- 单元测试
### 11.2 第二阶段:顶点属性(1天)
- 顶点属性扩展
- 公式应用到顶点
- 材质参数更新
- 基础可视化
### 11.3 第三阶段:三阶段可视化(1-2天)
- 淬火过程临时效果
- 冷却过渡动画
- 回火色系统
- 氧化层表现
- UI辅助工具
### 11.4 第四阶段:集成测试(0.5天)
- 完整流程测试
- 性能Profiling
- 参数调优
- 文档更新
---
## 12. 已知限制
1. **相变模型经验化**: 真实马氏体转变需要CCT曲线,当前用冷却速率阈值近似
2. **各向同性假设**: 真实钢有晶粒取向,当前材料各向同性
3. **简化热力学**: 忽略形变生热、磁性等二次效应
---
## 13. 引用
- 对应需求: [../requirements/05-淬火退火相变需求.md](../requirements/05-淬火退火相变需求.md)
- 总体架构: [00-锻造系统总体技术架构.md](00-锻造系统总体技术架构.md)
- 原始设计文档(归档): [../_archive/plans/2026-01-23-淬火退火相变系统设计.md](../_archive/plans/2026-01-23-淬火退火相变系统设计.md)
- 相关专题(物理模拟): [04-物理模拟-加工硬化与晶粒演化设计.md](04-物理模拟-加工硬化与晶粒演化设计.md)
+558
View File
@@ -0,0 +1,558 @@
# 应力累积系统设计
**项目**: BladeSmith
**文档类型**: 技术设计(专题)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-23-应力累积系统设计.md`
> 本文档描述应力累积系统的技术实现。需求见 [../requirements/06-应力累积与开裂需求.md]。总体架构见 [00-锻造系统总体技术架构.md](00-锻造系统总体技术架构.md)。
---
## 1. 技术背景
应力累积系统模拟锻造过程中多来源应力(塑性应力、热应力、相变应力、残余应力)的产生、累积、扩散与松弛机制。系统通过应力对形变阻力的影响、物理表现(弯曲/扭曲/裂纹)以及辅助可视化功能,实现真实应力行为模拟。
---
## 2. 应力来源分类
### 2.1 塑性形变应力
**来源**: 锤击导致材料永久形变
**计算公式**:
```
Stress_plastic = k_plastic × StrainIncrement × Hardness
```
**参数说明**:
- `k_plastic = 10.0`: 塑性应力系数(可调)
- `StrainIncrement`: 本次锤击的应变增量
- `Hardness`: 当前硬度系数
**应用范围**: 锤击影响区域内的所有顶点
### 2.2 热应力
**来源**: 温度梯度导致内部膨胀不均匀
**计算公式**:
```
Stress_thermal = ThermalStressCoeff × CoolingRate × (T_current - 20°C)
```
**参数说明**:
- `ThermalStressCoeff = 0.005`: 热应力系数(可调)
- `CoolingRate`: 冷却速率(°C/s)
- `T_current`: 当前温度(°C)
- 20°C: 环境温度
**应用范围**: 所有体素和顶点
### 2.3 相变应力
**来源**: 马氏体转变导致体积膨胀
**计算公式**:
```
Stress_phase = PhaseStressCoeff × MartensiteFraction
```
**参数说明**:
- `PhaseStressCoeff = 50.0`: 相变应力系数(可调)
- `MartensiteFraction`: 马氏体转化比例
**马氏体转化比例公式**:
```
MartensiteFraction = clamp(CoolingRate / 80°C/s, 0, 1)
```
**应用范围**: 淬火区域的所有顶点
### 2.4 残余应力
**来源**: 锤击时周边材料限制形变
**计算公式**:
```
Stress_residual = k_residual × (TargetStrain - ActualStrain)
```
**参数说明**:
- `k_residual = 5.0`: 残余应力系数(可调)
- `TargetStrain`: 目标应变(基于锤击强度)
- `ActualStrain`: 实际应变(受限后)
**应用范围**: 锤击区域周边的顶点
---
## 3. 应力累积规则
### 3.1 总应力计算
**综合应力公式**:
```
TotalStress = Stress_plastic + Stress_thermal + Stress_phase + Stress_residual
```
**顶点更新**:
```
InternalStress += TotalStress × DeltaTime
```
### 3.2 应力限制
```
InternalStress = clamp(InternalStress, 0.0, MaxStress)
```
其中`MaxStress`为材料极限应力,可配置。
### 3.3 应力扩散机制
**目的**: 应力向周围顶点扩散,模拟真实物理行为
**拉普拉斯平滑**:
```
Stress_diffused = Stress_original + α × (AverageNeighborStress - Stress_original)
```
**参数说明**:
- `α`: 扩散系数(0.1-0.3,可调)
- `AverageNeighborStress`: 相邻顶点的平均应力
**实现方式**:
每帧对每个顶点执行扩散,迭代1-2次。
### 3.4 应力松弛机制
**温度驱动的松弛**:
**松弛因子**:
```
RelaxationFactor =
0.99 (T < 100°C, 常温慢松弛)
0.90 (200°C ≤ T < 400°C, 回火快松弛)
0.85 (T ≥ 400°C, 快速松弛)
```
**每帧更新**:
```
InternalStress = InternalStress × RelaxationFactor
```
**时间常数公式**:
```
InternalStress = InternalStress × exp(-t / τ)
```
**参数说明**:
- `t`: 时间(秒)
- `τ`: 松弛时间常数
- τ = 60秒(常温)
- τ = 10秒(回火温度)
---
## 4. 应力对形变阻力的影响
### 4.1 形变阻力公式
**DeformationResistance(形变阻力)**:
```
DeformationResistance = BaseResistance × HardnessFactor × StressFactor × TemperatureFactor
```
### 4.2 各因子详细公式
**基础阻力**:
```
BaseResistance = 1.0
```
**硬度因子**:
```
HardnessFactor = 1.0 + (Hardness / MaxHardness) × 2.0
```
硬度越高,形变阻力越大(最大3倍阻力)。
**应力因子**:
```
StressFactor = 1.0 + (InternalStress / StressLimit) × 1.5
```
应力越高,材料越难形变(最大2.5倍阻力)。
**温度因子**:
```
TemperatureFactor =
3.0 (T > 800°C, 高温软)
1.5 (500°C < T ≤ 800°C, 中温)
1.0 (T ≤ 500°C, 常温)
```
### 4.3 顶点位移计算
**锤击位移**:
```
Displacement = BaseDisplacement / DeformationResistance
```
**应力高的区域**:
- 更难锻打
- 需要更用力
- 或重复锤击
---
## 5. 应力物理表现
### 5.1 弯曲/扭曲机制
**弯曲角度公式**:
```
BendAngle = (StressLocal - StressAverage) × BendSensitivity
BendDirection = CrossProduct(HammerDirection, Normal)
```
**实现步骤**:
1. 计算应力梯度:
```
∇Stress = Stress_neighbor - Stress_center
```
2. 应用顶点位移:
```
VertexPosition += BendDirection × BendAngle × DistanceFromCenter
```
**扭曲公式**:
当材料两侧应力不均匀时:
```
TwistAngle = (Stress_Left - Stress_Right) × TwistSensitivity
VertexPosition = RotateAroundAxis(VertexPosition, Axis, TwistAngle)
```
**视觉效果**:
- 刀身沿应力梯度方向自然弯曲
- 应力集中区域出现扭曲
- 大幅应力差导致明显形变
### 5.2 裂纹起始判定
**临界应力阈值**:
```
CriticalStressThreshold = MaterialStrength × SafetyFactor
```
**参数说明**:
- `MaterialStrength`: 材料强度(可配置,默认100.0)
- `SafetyFactor`: 安全系数(默认1.2)
**开裂条件**:
```cpp
if (InternalStress > CriticalStressThreshold)
{
CreateCrack(Vertex);
}
```
**概率开裂**:
为避免一次性开裂过多,引入概率:
```
CrackProbability = (InternalStress / CriticalStressThreshold) - 1.0
if (Random() < CrackProbability)
{
CreateCrack(Vertex);
}
```
### 5.3 裂纹扩展机制
**裂纹生长方向**:
优先沿应力梯度方向扩展(应力最大方向)
**每帧检查**:
```cpp
if (Vertex.IsCracked)
{
// 裂纹扩展概率
ExtendProbability = (InternalStress / CriticalStressThreshold) - 0.8
if (Random() < ExtendProbability)
{
// 找到应力最高的相邻顶点
TargetNeighbor = FindMaxStressNeighbor();
CrackTo(TargetNeighbor);
}
}
```
**裂纹合并**:
当两条裂纹相交时:
- 大块材料脱落
- 网格拓扑断裂
- 几何处理: 删除被包围的顶点和三角形
### 5.4 裂纹视觉表现
**几何表现**:
1. **裂缝开口**:
```
CrackVertex.Position += Normal × CrackOpeningWidth
```
其中`CrackOpeningWidth`为裂缝开口宽度(可配置)
2. **边缘抖动**:
裂纹边缘顶点位置随机抖动,模拟粗糙断裂
**材质表现**:
1. **锈迹**:
- 裂纹区域显示RustTexture
- 锈迹深度基于裂纹时间
2. **内部氧化**:
- 裂缝深处更暗
- 模拟内部氧化
3. **纹理扰动**:
使用顶点法线扰动模拟裂纹纹理
**物理影响**:
- 裂纹区域的硬度系数降为0.3
- 裂纹顶点不再参与后续锻打形变(断裂)
### 5.5 应力释放事件
**开裂后应力释放**:
```cpp
if (CrackCreated)
{
InternalStress = InternalStress × 0.3 // 应力释放
// 释放应力用于下次计算
}
```
**回火对应力的影响**:
加热至回火温度(200-400°C):
- 加速应力松弛(详见松弛机制)
- 但如果已经开裂,裂纹无法愈合
---
## 6. 应力可视化(辅助功能)
### 6.1 应力扫描模式
**触发方式**:
- 按住特定键切换到"应力视图"
- 或在UI中选择"应力扫描"工具
### 6.2 视觉效果
**顶点颜色着色**(彩虹色谱):
```hlsl
// 蓝色:低应力(< 30% StressLimit)
if (Stress < 0.3 × StressLimit)
{
Color = Lerp(Blue, Green, StressRatio);
}
// 绿色:中等应力(30-60% StressLimit)
else if (Stress < 0.6 × StressLimit)
{
Color = Lerp(Green, Yellow, StressRatio);
}
// 黄色:高应力(60-90% StressLimit)
else if (Stress < 0.9 × StressLimit)
{
Color = Lerp(Yellow, Red, StressRatio);
}
// 红色:接近开裂(≥ 90% StressLimit)
else
{
Color = Red;
// 叠加闪烁效果
Emissive = Flicker();
}
```
**应力流线**(可选):
- 显示应力传导路径
- 从高应力区域流向低应力区域
- 帮助理解应力分布
### 6.3 UI面板
- 实时显示最大应力值
- 平均应力值
- 超阈值顶点数量
- 裂纹数量
### 6.4 退出可视化
释放辅助功能键后,完全恢复正常视觉表现:
- 顶点颜色恢复到正常状态(打磨度、回火色等)
- 材质参数恢复
- 无任何残留效果
---
## 7. 实现架构
### 7.1 GPU-CPU分工
**GPU Compute Shader职责**:
- 热应力计算
- 应力扩散(简化版)
**CPU职责**:
- 塑性应力计算
- 相变应力应用
- 残余应力计算
- 应力累积
- 形变阻力计算
- 弯曲/扭曲应用
- 裂纹判定与扩展
- 应力扫描可视化
### 7.2 数据结构
**顶点属性扩展**:
```cpp
TDynamicMeshVertexAttribute<float>* InternalStress; // 内部应力值
TDynamicMeshVertexAttribute<uint8>* CrackState; // 裂纹状态(0=无, 1=有)
```
**裂纹数据结构**:
```cpp
USTRUCT(BlueprintType)
struct FCrackData
{
GENERATED_BODY()
UPROPERTY()
int32 StartVertex; // 裂纹起始顶点ID
UPROPERTY()
int32 EndVertex; // 裂纹结束顶点ID
UPROPERTY()
float CrackWidth; // 裂纹宽度
UPROPERTY()
float CrackDepth; // 裂纹深度
UPROPERTY()
float CreationTime; // 创建时间
};
```
### 7.3 性能优化
**应力扩散**:
- 只在锤击后更新,每帧不需要
- 局部扩散,仅受影响区域
**裂纹判定**:
- 仅在高应力区域检查
- 使用空间分区加速
**可视化**:
- 应力扫描模式按需启用
- 使用简化着色器
---
## 8. 参数配置
### 8.1 可调参数(蓝图可配)
| 参数名 | 默认值 | 范围 | 说明 |
|-------|--------|------|------|
| `MaxStress` | 150.0 | 100-200 | 最大应力值 |
| `k_plastic` | 10.0 | 5-20 | 塑性应力系数 |
| `ThermalStressCoeff` | 0.005 | 0.001-0.01 | 热应力系数 |
| `PhaseStressCoeff` | 50.0 | 20-100 | 相变应力系数 |
| `k_residual` | 5.0 | 2-10 | 残余应力系数 |
| `DiffusionAlpha` | 0.2 | 0.1-0.3 | 扩散系数 |
| `BendSensitivity` | 0.001 | 0.0005-0.002 | 弯曲敏感度 |
| `TwistSensitivity` | 0.0005 | 0.0002-0.001 | 扭曲敏感度 |
| `CriticalStressThreshold` | 120.0 | 80-150 | 临界应力 |
| `CrackOpeningWidth` | 0.05 | 0.01-0.1 | 裂纹宽度 |
| `RelaxationTimeNormal` | 60.0 | 30-120 | 常温松弛时间 |
| `RelaxationTimeTemper` | 10.0 | 5-20 | 回火松弛时间 |
### 8.2 调试工具
- 应力热图:实时显示应力分布
- 裂纹追踪:记录裂纹生成和扩展
- 应力时间线:记录应力变化历史
- 统计面板:最大应力、平均应力、裂纹数量
---
## 9. 实施计划
### 9.1 第一阶段:应力计算(1天)
- 四种应力来源实现
- 应力累积规则
- 应力扩散机制
- 应力松弛机制
- 单元测试
### 9.2 第二阶段:形变阻力(0.5天)
- 形变阻力公式
- 顶点位移计算
- 参数调优
- 集成测试
### 9.3 第三阶段:物理表现(1.5天)
- 弯曲/扭曲机制
- 裂纹起始判定
- 裂纹扩展逻辑
- 裂纹视觉表现
- 几何处理(裂纹开口、抖动)
- 材质表现(锈迹、氧化)
### 9.4 第四阶段:辅助功能(0.5天)
- 应力扫描模式
- 顶点颜色着色
- UI面板
- 应力流线(可选)
### 9.5 第五阶段:集成测试(0.5天)
- 完整流程测试
- 性能Profiling
- 参数调优
- 文档更新
---
## 10. 已知限制
1. **应力张量简化**: 真实是3×3张量,当前仅用单值
2. **各向同性假设**: 真实钢有晶粒取向,当前材料各向同性
3. **简化扩散**: 真实应力扩散是复杂偏微分方程,当前用拉普拉斯近似
---
## 11. 引用
- 对应需求: [../requirements/06-应力累积与开裂需求.md](../requirements/06-应力累积与开裂需求.md)
- 总体架构: [00-锻造系统总体技术架构.md](00-锻造系统总体技术架构.md)
- 原始设计文档(归档): [../_archive/plans/2026-01-23-应力累积系统设计.md](../_archive/plans/2026-01-23-应力累积系统设计.md)
- 相关专题(物理模拟): [04-物理模拟-加工硬化与晶粒演化设计.md](04-物理模拟-加工硬化与晶粒演化设计.md)
- 相关专题(淬火系统): [05-淬火退火相变系统设计.md](05-淬火退火相变系统设计.md)
- 相关专题(疲劳系统): [07-疲劳与耐久度系统设计.md](07-疲劳与耐久度系统设计.md)
@@ -0,0 +1,659 @@
# 疲劳与耐久度系统设计
**项目**: BladeSmith
**文档类型**: 技术设计(专题)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-23-疲劳累积与耐久度系统设计.md`
> 本文档描述疲劳累积与耐久度系统的技术实现。需求见 [../requirements/07-疲劳与刀具耐久度需求.md]。总体架构见 [00-锻造系统总体技术架构.md](00-锻造系统总体技术架构.md)。
---
## 1. 技术背景
疲劳累积与耐久度系统模拟材料在反复锻打和使用过程中的疲劳累积、裂纹产生与扩展,以及刀具整体耐久度变化。系统通过疲劳值计算、疲劳裂纹机制、耐久度综合评估、使用中损伤累积、恢复机制以及失效判定,实现真实材料疲劳行为模拟。
---
## 2. 疲劳累积机制
### 2.1 疲劳值定义
**疲劳值(Fatigue)**:
- 范围:0(完好)到 1(完全疲劳/失效)
- 每个顶点独立维护
- 累积式,不可逆(除非回火)
### 2.2 疲劳累积规则
**基础公式**:
```
Fatigue += BaseFatigueRate × StressFactor × TemperatureFactor × DeltaTime
```
### 2.3 各因子详细说明
#### 2.3.1 基础疲劳率(BaseFatigueRate)
| 锻打类型 | BaseFatigueRate | 说明 |
|---------|---------------|------|
| 正常锻打 | 0.001 | 标准锤击 |
| 过度锻打 | 0.005 | 形变过大(超过阈值) |
| 应力集中 | 0.010 | 高应力区域 |
#### 2.3.2 判定过度锻打
```cpp
if (StrainIncrement > CriticalStrainThreshold)
{
BaseFatigueRate = 0.005; // 过度锻打
}
```
#### 2.3.3 应力因子
```
StressFactor = clamp(InternalStress / StressLimit, 1.0, 3.0)
```
应力越高,疲劳累积越快:
- 应力 < 1.0 × StressLimit: StressFactor = 1.0
- 应力 = 1.5 × StressLimit: StressFactor = 1.5
- 应力 ≥ 3.0 × StressLimit: StressFactor = 3.0
#### 2.3.4 温度因子
```
TemperatureFactor =
0.1 (T > 800°C, 高温疲劳慢)
1.0 (常温)
2.0 (T < 200°C, 低温疲劳快)
```
高温时材料更"柔软",疲劳较慢;低温时更"脆",疲劳快。
### 2.4 疲劳限制
```
Fatigue = clamp(Fatigue, 0.0, 1.0)
```
疲劳值达到1.0后不再增加,但可能触发失效。
---
## 3. 疲劳可视化(辅助功能)
### 3.1 疲劳扫描模式
**触发方式**:
- 按住特定键切换到"疲劳视图"
- 或在UI中选择"疲劳扫描"工具
### 3.2 视觉效果
**顶点颜色着色**:
```hlsl
// 蓝色:疲劳值 < 0.3
if (Fatigue < 0.3)
{
Color = Lerp(Blue, Green, Fatigue / 0.3);
}
// 绿色:疲劳值 0.3-0.7
else if (Fatigue < 0.7)
{
Color = Lerp(Green, Yellow, (Fatigue - 0.3) / 0.4);
}
// 黄色:疲劳值 0.7-0.9
else if (Fatigue < 0.9)
{
Color = Lerp(Yellow, Orange, (Fatigue - 0.7) / 0.2);
}
// 红色:疲劳值 > 0.9(危险区)
else
{
Color = Red;
// 叠加脉冲效果
Pulse = sin(Time × 5.0) × 0.5 + 0.5;
Emissive = Pulse × Red;
}
```
### 3.3 UI面板
- 平均疲劳值
- 最大疲劳值
- 危险区域数量(Fatigue > 0.9)
- 预估寿命
### 3.4 退出可视化
释放辅助功能键后,完全恢复正常视觉表现。
---
## 4. 疲劳裂纹系统
### 4.1 疲劳裂纹起始
**触发条件**:
```cpp
if (Fatigue > 0.9 && InternalStress > 0.5 × StressLimit)
{
// 触发疲劳开裂
if (Random() < CrackProbability)
{
CreateFatigueCrack(Vertex);
}
}
```
**疲劳开裂概率**:
```
CrackProbability = (Fatigue - 0.9) × 10.0 // 最大1.0
```
疲劳值越高,开裂概率越大:
- Fatigue = 0.9: CrackProbability = 0.0
- Fatigue = 0.95: CrackProbability = 0.5
- Fatigue = 1.0: CrackProbability = 1.0
### 4.2 疲劳裂纹扩展
**每次锻打检查**:
```cpp
if (Vertex.IsCracked && CrackType == Fatigue)
{
// 裂纹扩展概率
ExtendProbability = (Fatigue - 0.7) × 2.0
if (Random() < ExtendProbability)
{
// 找到疲劳值最高的相邻顶点
TargetNeighbor = FindMaxFatigueNeighbor();
CrackTo(TargetNeighbor);
}
}
```
**疲劳裂纹特点**:
- 沿高疲劳值方向扩展
- 扩展速度与疲劳值成正比
- 可能产生多条细小裂纹(应力裂纹通常是单条)
### 4.3 疲劳裂纹视觉表现
**几何表现**:
1. **细小裂缝**:
- 开口宽度较小(0.01-0.02)
- 多条裂纹可能交织
2. **边缘锯齿**:
- 裂纹边缘不光滑
- 顶点位置随机抖动
**材质表现**:
1. **表面氧化**:
- 显示轻微锈迹
- 氧化程度与时间相关
2. **内部损伤**:
- 深处 darker
- 模拟材料损伤
---
## 5. 耐久度系统
### 5.1 耐久度定义
**耐久度(Durability)**:
- 范围:0(损坏)到 1.0(完好)
- 基于整个刀具计算
- 影响刀具使用效果
### 5.2 耐久度计算公式
**综合耐久度**:
```
Durability = 1.0 - (AverageFatigue + CrackPenalty + StressPenalty)
```
### 5.3 各分量说明
#### 5.3.1 平均疲劳
```
AverageFatigue = Σ(Fatigue_i) / VertexCount
```
#### 5.3.2 裂纹惩罚
```
CrackPenalty = CrackCount × 0.1 // 每条裂纹扣10%耐久
```
裂纹包括:
- 应力裂纹(由应力超阈值产生)
- 疲劳裂纹(由疲劳累积产生)
#### 5.3.3 应力惩罚
```
StressPenalty = (MaxStress / StressLimit) × 0.2
```
高应力区域最高扣除20%耐久度。
### 5.4 耐久度限制
```
Durability = clamp(Durability, 0.0, 1.0)
```
耐久度降到0后刀具可能失效。
---
## 6. 使用中的损伤累积
### 6.1 刀具使用场景
**切割/砍击**:
- 每次使用造成冲击
- 冲击点附近疲劳增加
**抛光/打磨**:
- 减少疲劳(回火效果)
- 恢复部分耐久度
### 6.2 冲击疲劳计算
**冲击应力**:
```
ImpactStress = ImpactForce × MaterialStiffness × (1 - ImpactAngle)
```
**参数说明**:
- `ImpactForce`: 冲击力(来自物理引擎)
- `MaterialStiffness`: 材料刚度
- `ImpactAngle`: 冲击角度(0-1,垂直=1.0)
**疲劳增量**:
```
Fatigue += ImpactStress / Durability × FatigueRate
```
**参数说明**:
- `FatigueRate`: 疲劳率(可配置,默认0.0001)
**局部更新**:
冲击影响半径内的顶点更新疲劳值。
### 6.3 耐久度实时更新
**每次使用后**:
```cpp
// 重新计算耐久度
Durability = CalculateDurability();
// 更新UI
UpdateDurabilityUI();
```
---
## 7. 耐久度恢复机制
### 7.1 回火恢复
**加热至回火温度**(200-400°C):
**疲劳恢复**:
```cpp
if (Temperature > 200°C && Temperature < 400°C)
{
Fatigue -= 0.1 × DeltaTime; // 慢慢消除疲劳
Fatigue = clamp(Fatigue, 0.0, 1.0);
}
```
**耐久度恢复**:
```cpp
if (Temperature > 200°C && Temperature < 400°C)
{
Durability += 0.05 × DeltaTime;
Durability = clamp(Durability, 0.0, 1.0);
}
```
**注意事项**:
- 疲劳可部分恢复
- 但裂纹无法愈合
- 裂纹惩罚永久存在
### 7.2 打磨恢复
**打磨操作**:
**表面损伤修复**:
- 打磨可去除表面疲劳痕迹
- 减少视觉上的"老伤"
**疲劳影响**:
```cpp
if (PolishAmount > OldPolishAmount)
{
Fatigue -= (PolishAmount - OldPolishAmount) × 0.5;
Fatigue = clamp(Fatigue, 0.0, 1.0);
}
```
**耐久度影响**:
- 打磨不恢复耐久度
- 但可以改善外观
---
## 8. 刀具失效判定
### 8.1 失效条件
**条件1: 耐久度耗尽**:
```cpp
if (Durability < 0.0)
{
BreakWeapon();
}
```
**条件2: 主裂纹存在**:
```cpp
if (MajorCrackExists)
{
// 主裂纹判定:长度超过阈值或穿过关键区域
if (CrackLength > MajorCrackThreshold || CrackThroughCriticalArea)
{
BreakWeapon();
}
}
```
**条件3: 瞬时过载**:
```cpp
if (ImpactForce > UltimateStrength)
{
// 瞬间断裂
InstantBreakWeapon();
}
```
### 8.2 失效表现
**几何表现**:
1. **断裂**:
- 刀身分离成两段
- 网格拓扑断裂
- 删除断裂部分的顶点和三角形
2. **破碎**:
- 多个小碎片
- 适合薄刃刀具
**材质表现**:
1. **断口**:
- 显示粗糙断裂面
- 颜色暗淡
- 无光泽
2. **音效**:
- 断裂音效
- 碎片掉落声
**物理表现**:
- 断裂部分掉落
- 受重力影响
- 碰撞地面产生音效
---
## 9. 实现架构
### 9.1 数据结构
**顶点属性扩展**:
```cpp
TDynamicMeshVertexAttribute<float>* FatigueValue; // 疲劳值(0-1)
```
**裂纹数据结构**:
```cpp
UENUM(BlueprintType)
enum class ECrackType : uint8
{
Stress = 0, // 应力裂纹
Fatigue = 1, // 疲劳裂纹
Impact = 2 // 冲击裂纹
};
USTRUCT(BlueprintType)
struct FCrackData
{
GENERATED_BODY()
UPROPERTY()
int32 StartVertex; // 裂纹起始顶点ID
UPROPERTY()
int32 EndVertex; // 裂纹结束顶点ID
UPROPERTY()
TEnumAsByte<ECrackType> CrackType; // 裂纹类型
UPROPERTY()
float CrackWidth; // 裂纹宽度
UPROPERTY()
float CrackDepth; // 裂纹深度
UPROPERTY()
float CreationTime; // 创建时间
UPROPERTY()
bool bIsMajor; // 是否主裂纹
};
```
**刀具耐久度数据**:
```cpp
USTRUCT(BlueprintType)
struct FWeaponDurability
{
GENERATED_BODY()
UPROPERTY()
float Durability; // 耐久度(0-1)
UPROPERTY()
float AverageFatigue; // 平均疲劳
UPROPERTY()
int32 CrackCount; // 裂纹数量
UPROPERTY()
float MaxStress; // 最大应力
UPROPERTY()
int32 MajorCrackCount; // 主裂纹数量
};
```
### 9.2 GPU-CPU分工
**GPU Compute Shader职责**:
- 无(疲劳计算纯CPU)
**CPU职责**:
- 疲劳累积计算
- 疲劳裂纹判定
- 裂纹扩展逻辑
- 耐久度计算
- 使用中的损伤累积
- 回火/打磨恢复
- 刀具失效判定
- 疲劳扫描可视化
---
## 10. 性能优化
### 10.1 疲劳计算优化
**局部更新**:
- 锤击时仅更新受影响区域
- 使用空间分区加速查询
**批量更新**:
- 每帧最多更新N个顶点
- 使用优先级队列(高疲劳优先)
### 10.2 裂纹判定优化
**阈值检查**:
```cpp
// 仅检查接近阈值的顶点
if (Fatigue > 0.8 && InternalStress > 0.5 × StressLimit)
{
// 检查裂纹
}
```
**空间分区**:
- 使用八叉树或BVH
- 快速查询相邻顶点
### 10.3 可视化优化
**疲劳扫描**:
- 按需启用
- 使用简化着色器
- 降低更新频率
---
## 11. 参数配置
### 11.1 可调参数(蓝图可配)
| 参数名 | 默认值 | 范围 | 说明 |
|-------|--------|------|------|
| `BaseFatigueRateNormal` | 0.001 | 0.0005-0.002 | 正常锻打疲劳率 |
| `BaseFatigueRateOverwork` | 0.005 | 0.002-0.01 | 过度锻打疲劳率 |
| `BaseFatigueRateStress` | 0.010 | 0.005-0.02 | 应力集中疲劳率 |
| `CriticalStrainThreshold` | 0.1 | 0.05-0.2 | 临界应变阈值 |
| `TemperatureFactorHigh` | 0.1 | 0.05-0.2 | 高温疲劳因子 |
| `TemperatureFactorNormal` | 1.0 | 0.8-1.2 | 常温疲劳因子 |
| `TemperatureFactorLow` | 2.0 | 1.5-2.5 | 低温疲劳因子 |
| `CrackPenalty` | 0.1 | 0.05-0.2 | 单条裂纹惩罚 |
| `StressPenalty` | 0.2 | 0.1-0.3 | 应力惩罚系数 |
| `FatigueRecoveryRate` | 0.1 | 0.05-0.2 | 回火疲劳恢复率 |
| `DurabilityRecoveryRate` | 0.05 | 0.02-0.1 | 回火耐久恢复率 |
| `ImpactFatigueRate` | 0.0001 | 0.00005-0.0002 | 冲击疲劳率 |
| `MajorCrackThreshold` | 10.0 | 5.0-20.0 | 主裂纹长度阈值 |
### 11.2 调试工具
- 疲劳热图:实时显示疲劳分布
- 疲劳时间线:记录疲劳变化历史
- 裂纹追踪:记录裂纹生成和扩展
- 耐久度面板:实时显示耐久度
- 预估寿命:基于当前疲劳率预估
---
## 12. 实施计划
### 12.1 第一阶段:疲劳累积(1天)
- 疲劳值属性系统
- 疲劳累积规则
- 应力和温度因子
- 疲劳限制
- 单元测试
### 12.2 第二阶段:疲劳裂纹(1天)
- 疲劳裂纹起始判定
- 疲劳裂纹扩展逻辑
- 疲劳裂纹视觉表现
- 集成测试
### 12.3 第三阶段:耐久度系统(1天)
- 耐久度计算公式
- 使用中的损伤累积
- 回火/打磨恢复
- 耐久度UI
- 集成测试
### 12.4 第四阶段:刀具失效(0.5天)
- 失效条件判定
- 失效表现(几何/材质/音效)
- 集成测试
### 12.5 第五阶段:辅助功能(0.5天)
- 疲劳扫描模式
- 疲劳热图
- UI面板
- 调试工具
### 12.6 第六阶段:集成测试(0.5天)
- 完整流程测试
- 性能Profiling
- 参数调优
- 文档更新
---
## 13. 风险评估
### 13.1 技术风险
| 风险 | 概率 | 影响 | 缓解措施 |
|------|------|------|---------|
| 疲劳计算性能不足 | 中 | 中 | 局部更新,批量处理 |
| 裂纹判定过于频繁 | 低 | 高 | 提高阈值,减少检查 |
| 耐久度平衡困难 | 中 | 中 | 参数可调,快速迭代 |
### 13.2 设计风险
| 风险 | 概率 | 影响 | 缓解措施 |
|------|------|------|---------|
| 疲劳积累过快 | 中 | 高 | 降低基础疲劳率,提供恢复机制 |
| 刀具失效过于突然 | 低 | 中 | 增加预警,渐进式失效 |
| 辅助功能滥用 | 低 | 低 | 限制使用时长,增加冷却 |
---
## 14. 已知限制
1. **疲劳模型简化**: 真实疲劳涉及复杂循环载荷,当前用近似模型
2. **裂纹机制简化**: 真实裂纹扩展遵循断裂力学,当前用概率模型
3. **各向同性假设**: 真实钢有晶粒取向,当前材料各向同性
---
## 15. 引用
- 对应需求: [../requirements/07-疲劳与刀具耐久度需求.md](../requirements/07-疲劳与刀具耐久度需求.md)
- 总体架构: [00-锻造系统总体技术架构.md](00-锻造系统总体技术架构.md)
- 原始设计文档(归档): [../_archive/plans/2026-01-23-疲劳累积与耐久度系统设计.md](../_archive/plans/2026-01-23-疲劳累积与耐久度系统设计.md)
- 相关专题(应力系统): [06-应力累积系统设计.md](06-应力累积系统设计.md)
+5 -1
View File
@@ -1,4 +1,8 @@
# 锤击形变系统
# 锤击形变系统(已交付功能说明)
> 本文档是锤击形变系统的**功能交付说明**,描述已实现的能力、参数与使用方法。
> 完整需求见 [requirements/01-锤击形变与刀刃形成需求.md](../requirements/01-锤击形变与刀刃形成需求.md);
> 完整技术设计见 [design/01-刀刃形成-各向异性流动设计.md](../design/01-刀刃形成-各向异性流动设计.md)。
## 概述
@@ -0,0 +1,218 @@
# 锻造系统总体需求
**项目**: BladeSmith
**文档类型**: 需求文档(总体)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-22-高真实度锻造系统设计.md` 与 `2026-01-23-淬火退火相变与应力疲劳系统总览.md`
> 本文档从玩家与游戏体验视角描述锻造系统要"做成什么样",不涉及算法、代码、shader 等技术实现细节。技术实现见 [design/00-锻造系统总体技术架构.md](../design/00-锻造系统总体技术架构.md)。
---
## 1. 项目定位
BladeSmith 是一款基于 Unreal Engine 5.6 的真实打铁模拟游戏。玩家在游戏中体验锻造刀具的完整流程,刀具的成型过程通过物理计算还原真实锻造效果——**每一把刀具的造型、纹路、性能都是独特的**。
锻造系统是玩法的核心,负责把"玩家敲锤子"这个动作转化为:
- 看得见的金属形变与表面变化
- 影响后续表现的内部材料状态(硬度、应力、相态、疲劳等)
- 最终决定刀具强度、韧性、耐久度的物理属性
## 2. 核心体验目标
| 目标 | 含义 | 验收信号 |
|---|---|---|
| **游戏娱乐级真实感** | 物理模型简化但保留核心机制,玩家直觉上"像真打铁" | 玩家测试中能凭常识判断结果 |
| **每一刀都独特** | 锻造路径决定刀具数据,同样的初始材料能产出截然不同的成品 | 同批次的两次锻造产出差异显著 |
| **可读的反馈** | 玩家在任何时刻都能"看懂"金属当前状态,做下一步决策 | 不依赖外部文档即可理解表层状态 |
| **稳定 60 FPS** | 锤击操作期间帧率不掉,操作延迟不可察觉 | 详见 §5 性能与质量目标 |
| **渐进式可实现** | 系统可分阶段交付,每阶段独立可玩 | 详见 §6 实施阶段 |
## 3. 玩家可见的核心物理过程
整个锻造系统要让玩家**直观感知**以下 7 类冶金学物理现象。这些现象构成 7 个专题需求文档的主题。
### 3.1 锤击形变与刀刃形成
玩家用锤子敲击锻材时:
- 受击处材料被压紧、向四周流动
- 材料优先沿"最小阻力方向"流动,而非均匀扩散
- 在边缘附近锻打时,材料沿边缘延展,逐渐形成平整锐利的刀刃
- 连续锻打能逐步把铁块变形成目标形状
详见 [01-锤击形变与刀刃形成需求.md](01-锤击形变与刀刃形成需求.md)。
### 3.2 表面磨损与外观
锻材的表面状态会随锻造过程演变:
- 新铁块表面是生锈/氧化层(橙红色、粗糙)
- 锤击区域铁锈脱落,露出光亮金属本体
- 表面特征(铁锈图案、纹路)**必须随形变一起移动**,不能"漂移"或"贴在屏幕上"
- 支持铁锈、氧化层、酸蚀痕迹、划痕等多种表面状态
详见 [02-表面磨损与外观需求.md](02-表面磨损与外观需求.md)。
### 3.3 网格质量(隐形但关键)
玩家不应感知到网格退化,因此:
- 连续锻打 50+ 次后,刀刃仍然平整,无明显锯齿
- 表面着色无条纹、无闪烁、无"空洞"
- 锻打不会让金属"莫名其妙"地出现奇怪形状
详见 [03-网格质量与性能需求.md](03-网格质量与性能需求.md)。
### 3.4 加工硬化与晶粒演化
反复锻打会让金属变硬:
- 同一块金属连续锻打会越来越难变形(需要更用力或更多锤)
- 加热到一定温度后金属软化,可继续加工(回火机制)
- 微观上,晶粒尺寸、形状、取向影响材料特性与视觉花纹
- 大马士革钢的层状花纹是可见的视觉表达
详见 [04-加工硬化与晶粒演化需求.md](04-加工硬化与晶粒演化需求.md)。
### 3.5 淬火退火相变
热处理是决定刀具最终性能的关键步骤:
- 把高温金属快速冷却(水/油)会显著提升硬度,但同时增加脆性
- **温度区间**决定淬火效果:黄金区间(900-1100°C)最佳,过低无效,过高有开裂风险
- **冷却速率**决定结果:水淬硬而脆、油淬适中、空冷近似退火
- 缓慢冷却(退火)反而让金属变软但韧性提高
- 视觉上要有清晰的三阶段反馈(详见专题)
详见 [05-淬火退火相变需求.md](05-淬火退火相变需求.md)。
### 3.6 应力累积与开裂
不均匀的形变和热处理会在金属内部累积应力:
- 高应力区域更难锻打(需要更用力)
- 应力梯度会让刀身在锻打中自然弯曲或扭曲
- 应力超过材料强度时会产生裂纹
- 裂纹会沿应力梯度扩展,最终导致刀具断裂
- 玩家可通过"应力扫描"辅助功能主动查看应力分布
详见 [06-应力累积与开裂需求.md](06-应力累积与开裂需求.md)。
### 3.7 疲劳累积与刀具耐久度
长期使用让刀具性能衰减:
- 反复锻打累积疲劳,过锻或高应力区加速疲劳
- 疲劳到达阈值后产生疲劳裂纹
- 刀具的耐久度由平均疲劳、裂纹数量、最大应力共同决定
- 使用刀具(切割、砍击)进一步累积损伤
- 回火可部分恢复疲劳,但裂纹无法愈合
- 耐久度归零或主裂纹出现时,刀具失效(断裂)
详见 [07-疲劳与刀具耐久度需求.md](07-疲劳与刀具耐久度需求.md)。
## 4. 玩家可执行的核心操作
这些操作来自游戏顶层玩法设计,锻造系统必须对其做出物理响应。
| 操作 | 锻造系统需要响应的行为 |
|---|---|
| **加热** | 提升温度,增加塑性,软化已硬化的金属,触发回火/相变重置 |
| **捶打** | 形变、表面去锈、累积应变/硬化/应力/疲劳、维护网格质量 |
| **切割**(电锯) | 快速改变锻材形状(独立子系统) |
| **打磨** | 改变表面粗糙度、微调形状、修复表面损伤 |
| **淬火** | 快速冷却触发马氏体相变,提升硬度/脆性,留下氧化层 |
| **强度测试** | 提供场地与道具,验证刀具性能(独立玩法场景) |
## 5. 性能与质量目标
### 5.1 帧率与延迟
| 指标 | 目标 |
|---|---|
| 锤击操作期间帧率 | 稳定 60 FPS |
| 单次锤击响应时间 | < 10 ms(玩家不可察觉) |
| 锤击形变计算预算 | 2-3 ms |
| 网格质量优化预算 | 1-2 ms |
| GPU 物理计算预算 | 0.5-1 ms(异步) |
| 顶点属性/材质更新预算 | 0.5-1 ms |
| **总锤击开销上限** | **≤ 7 ms** |
### 5.2 规模
| 维度 | 目标 |
|---|---|
| 单铁块网格顶点数 | 20-50 万(基础),刀刃区域可局部加密到 100 万/cm² |
| 体素分辨率 | 50×50×50(典型),可配置 30³-80³ |
| 单铁块内存 | ~30 MB |
| 连续锻打次数 | 连续 50-100 次锤击后网格质量仍良好 |
### 5.3 质量验收原则
- **网格质量**: 连续锻打 50 次后无明显细长三角形(长宽比 > 10:1),无明显锯齿
- **表面稳定性**: 形变后表面纹理(铁锈图案)不漂移
- **可调性**: 所有可调参数可在编辑器实时调节
- **可调试性**: 提供体素场可视化、应力热图、属性统计等调试工具
## 6. 设计原则
| 原则 | 含义 |
|---|---|
| **游戏娱乐级精度** | 简化物理模型,保留核心机制与真实感,不做科研级精度 |
| **YAGNI** | 避免过度设计,专注核心功能,不为假想需求预留 |
| **渐进式实现** | 分阶段交付,每阶段可独立运行与验收 |
| **架构扩展性** | 为未来功能(多材料、焊接、VR 等)预留接口,但不提前实现 |
| **过程高辨识,结果真物理** | 热处理等关键时刻给玩家强反馈,平时展示真实物理表现 |
| **辅助功能可选** | 应力扫描、疲劳扫描等"作弊视图"按需启用,不污染真实视觉 |
## 7. 验收路径(实施阶段)
按以下阶段交付,每阶段独立验收。详细任务排期见各专题需求文档。
| 阶段 | 范围 | 主要验收 |
|---|---|---|
| **阶段 1** | 锤击形变(各向异性) + 表面磨损 + 基础网格平滑 | 锻造边缘材料沿边缘流动;表面铁锈脱落;形变无漂移 |
| **阶段 2** | 完整网格质量系统(边翻转/平滑/重网格) | 连续锻打 50 次网格仍均匀,无细长三角形 |
| **阶段 3** | 物理模拟扩展(加工硬化/淬火/退火) | 连续锻打变硬;加热软化;淬火硬度显著提升 |
| **阶段 4** | 晶粒与视觉(晶粒演化/大马士革/应力可视化/开裂) | 高应变区可视化;支持大马士革花纹;应力过大出现裂纹 |
| **阶段 5** | 疲劳与耐久度 | 反复锻打累积疲劳;耐久度下降;刀具最终可失效 |
| **阶段 6** | 优化与打磨 | Unreal Insights 验证 60 FPS;所有参数蓝图可调;文档齐全 |
## 8. 风险(玩家可感知的失败模式)
这些是锻造系统做错时玩家会直接感受到的问题,设计阶段需重点规避:
| 风险 | 玩家感受 | 严重度 |
|---|---|---|
| 物理模型过于简化 | "假"、"不像打铁" | 中 |
| 系统过度复杂,周期失控 | 长期无新版可玩 | 高 |
| 顶点属性在网格重建时丢失 | 锻打中途表面颜色/状态错乱 | 高 |
| 大马士革花纹实现困难 | 阶段 4 可选功能,可降级或推迟 | 中 |
| 网格重建开销过大 | 锤击延迟突增、掉帧 | 高 |
| 参数难调 | 不同硬件表现差异大 | 中 |
## 9. 未来扩展方向(超出当前需求范围)
以下方向**不在**当前需求内,但系统设计不应阻止未来加入:
- 多材料支持(铜、青铜、钛合金)
- 焊接系统(多块金属连接与材料混合)
- 锻造工具多样性(平锤、圆锤、凿子等不同锤头形状)
- 多人协作锻造(网络同步动态网格)
- VR 支持(空间交互与力反馈)
## 10. 参考资料
### 10.1 物理基础
- 《金属塑性成形原理》(清华大学出版社)
- 《材料科学基础》(上海交通大学出版社)
- 《金属热处理原理与工艺》(机械工业出版社)
- *Metals Handbook: Forging and Forming / Heat Treating* (ASM International)
### 10.2 游戏案例
- *My Summer Car* — 机械装配真实度
- *BeamNG.drive* — 动态网格形变
- *Dwarf Fortress* — 材料属性系统
### 10.3 索引
- 技术实现总览: [design/00-锻造系统总体技术架构.md](../design/00-锻造系统总体技术架构.md)
- 专题需求: [01~07](./)
- 原始设计文档(归档): [_archive/plans/](../_archive/plans/)
@@ -0,0 +1,153 @@
# 锤击形变与刀刃形成需求
**项目**: BladeSmith
**文档类型**: 需求文档(专题)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-22-刀刃形成技术细节.md`
> 本文档从玩家视角描述锤击形变与刀刃形成的需求。技术实现见 [design/01-刀刃形成-各向异性流动设计.md](../design/01-刀刃形成-各向异性流动设计.md)。总体需求见 [00-锻造系统总体需求.md](00-锻造系统总体需求.md)。
---
## 1. 玩家可见行为
### 1.1 材料流动方向
玩家用锤子敲击锻材时,材料会优先沿着"阻力最小的方向"流动,而不是均匀向四周扩散。
在边缘附近锻打时,材料会沿着边缘方向延展,逐渐形成平整锐利的刀刃。这符合真实锻造的物理直觉。
### 1.2 锻造过程可视化
从玩家视角看,锻造刀刃的形变过程如下:
```
初始状态:圆柱形铁块
███████████
███████████
第一次锻打:
▼锤击
███████████ ← 受击处变扁
████████████ ← 材料向侧面流动
多次锻打:
██ ← 继续变薄
██████
███████████ ← 逐渐形成锥形
最终成刃:
▲ ← 边缘平整锐利
█████
████████
```
关键视觉特征:材料优先沿着边缘方向流动(垂直于锤击方向 + 朝向边缘)。
### 1.3 边缘平整效果
锻造形成的刀刃应当保持平整锐利,而不是波浪状凸起:
```
理想边缘: ▲
████
██████
实际边缘: ▲▲▲
████
██████ ← 波纹状(不理想)
```
玩家不应看到明显的波纹或不规则边缘。
### 1.4 形变连续性
连续锻打能逐步把铁块变形成目标形状。每次锤击的形变应当是连续的、可预测的,不会出现突变或奇怪形状。
---
## 2. 玩家可调参数
| 参数功能名 | 默认值 | 范围 | 玩家感受 |
|-----------|--------|------|---------|
| 材料流动方向强度 | 3.0 | 1.0-10.0 | 控制材料沿边缘流动的程度。值越大,边缘拉伸越明显 |
| 凸起高度强度 | 0.5 | 0.1-2.0 | 控制锤击处材料凸起的高度。需要配合影响半径调整 |
| 锤击影响半径 | 5.0 | 1.0-20.0 | 单次锤击影响到的区域大小(单位:厘米) |
| 边缘过渡平滑度 | 2.0 | 1.0-4.0 | 控制形变边界过渡的平滑程度。值越大,边界越锐利 |
| 边缘平整约束开关 | 关闭 | 开启/关闭 | 是否启用边缘平整约束,保证刀刃锐利 |
| 边缘检测范围 | 1.0 | 0.5-2.0 | 距离边界多少厘米内的顶点被视为边缘顶点 |
### 推荐参数配置
**锻造平面(打铁块顶面)**:
- 材料流动方向强度 = 1.0(均匀流动)
- 锤击影响半径 = 5.0 cm
- 凸起高度强度 = 0.5
- 边缘平整约束开关 = 关闭
**锻造边缘(形成刀刃)**:
- 材料流动方向强度 = 4.0(强方向性)
- 锤击影响半径 = 3.0 cm(小范围)
- 凸起高度强度 = 0.3(较小凸起)
- 边缘平整约束开关 = 开启
- 边缘检测范围 = 1.0 cm
**精细整形(最后修整)**:
- 材料流动方向强度 = 8.0(极端定向)
- 锤击影响半径 = 1.5 cm(很小范围)
- 凸起高度强度 = 0.1(微调)
- 边缘平整约束开关 = 开启
- 边缘检测范围 = 0.5 cm
---
## 3. 视觉/听觉反馈
### 3.1 视觉反馈
- **形变实时可见**: 锤击瞬间,受击处材料立即产生形变
- **方向性流动**: 在边缘附近锻打时,玩家能清楚看到材料沿着边缘方向流动
- **边缘锐利度**: 刀刃区域保持平整锐利,无明显波纹
### 3.2 听觉反馈
- **金属撞击声**: 锤击时发出真实的金属撞击声
- **形变强度提示**: 不同形变程度可能伴随不同音效
---
## 4. 边界与限制(玩家不应期望的行为)
### 4.1 形变限制
- **极端形变**: 当边缘厚度 < 1mm 时,材料流动的假设可能失效,形变效果可能不符合直觉
- **拓扑变化**: 当前系统无法处理网格撕裂或融合(如锻打折叠金属)
- **复杂形状**: 对于叉状等复杂形状,方向检测可能不够准确
### 4.2 不可达效果
- 玩家不能期待系统支持"熔化后重新塑形"等超出现实锻造范围的行为
- 系统不会自动"修复"玩家不当锻打造成的形状错误
---
## 5. 验收清单
- [ ] 锤击处材料被压紧、向四周流动
- [ ] 材料优先沿"最小阻力方向"流动(而非均匀扩散)
- [ ] 在边缘附近锻打时,材料沿边缘延展,逐渐形成平整锐利的刀刃
- [ ] 连续锻打能逐步把铁块变形成目标形状
- [ ] 刀刃边缘平整锐利,无明显波纹(锯齿长宽比不超过 10:1)
- [ ] 形变实时可见,无延迟
- [ ] 锤击期间帧率稳定 60 FPS
- [ ] 玩家能通过调整参数控制材料流动方向强度
- [ ] 边缘平整约束功能可有效改善边缘质量
---
## 6. 引用
- 对应技术设计: [../design/01-刀刃形成-各向异性流动设计.md](../design/01-刀刃形成-各向异性流动设计.md)
- 总体需求: [00-锻造系统总体需求.md](00-锻造系统总体需求.md)
- 原始设计文档(归档): [../_archive/plans/2026-01-22-刀刃形成技术细节.md](../_archive/plans/2026-01-22-刀刃形成技术细节.md)
@@ -0,0 +1,183 @@
# 表面磨损与外观需求
**项目**: BladeSmith
**文档类型**: 需求文档(专题)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-22-表面磨损系统细节.md`
> 本文档从玩家视角描述表面磨损与外观的需求。技术实现见 [design/02-表面磨损-顶点属性与无漂移采样设计.md](../design/02-表面磨损-顶点属性与无漂移采样设计.md)。总体需求见 [00-锻造系统总体需求.md](00-锻造系统总体需求.md)。
---
## 1. 玩家可见行为
### 1.1 表面状态变化
锻材的表面状态会随锻造过程自然演变:
- **新铁块**: 表面是生锈/氧化层,颜色呈橙红色,表面粗糙
- **锤击区域**: 铁锈脱落,露出光亮金属本体
- **金属光泽**: 打磨后金属度增加(从哑光到镜面),粗糙度降低
- **表面状态**: 支持铁锈、氧化层、酸蚀痕迹、划痕等多种表面状态
### 1.2 铁锈的物理特性(玩家可感知)
真实铁锈层的视觉特征:
| 特性 | 表现 | 玩家可感知度 |
|------|------|------------|
| 厚度 | 0.1-2mm(可视严重程度) | 厚铁锈显得更深色、更粗糙 |
| 成分 | 红锈、黑锈混合 | 颜色从橙红到深褐 |
| 附着强度 | 低,易被机械摩擦去除 | 锤击时铁锈容易脱落 |
| 颜色 | 橙红到深褐 | 不同锈蚀程度颜色不同 |
| 粗糙度 | 高(微观凹凸不平) | 表面摸起来粗糙不平 |
锻造去锈原理(玩家可见):
- 锤击压力产生摩擦力,铁锈层破碎脱落
- 塑性形变暴露新鲜金属表面
- 高温时部分氧化层会还原
### 1.3 表面特征跟随性(关键要求)
**表面特征必须随形变一起移动,不能"漂移"或"贴在屏幕上"。**
这是玩家最容易察觉的问题:
- 铁锈图案应该"锁定"在材料上,随材料一起移动
- 锻打前某个位置的铁锈,锻打后仍应在该材料部位(只是位置随形变改变)
- 不能出现铁锈"滑走"或原地消失又突然出现的情况
正确行为示例:
```
锻打前: 位置A有铁锈(表面颜色深)
锻打后: 位置A移动到新位置B,铁锈仍在该材料部位
```
错误行为示例(玩家会感到不自然):
```
锻打前: 位置A有铁锈
锻打后: 位置A移动了,但铁锈还在原地(漂移)
或铁锈突然消失(表面颜色变亮)
```
### 1.4 高级表面效果
#### 大马士革花纹
支持大马士革钢的层状花纹:
- 高碳钢层:深色
- 低碳钢层:浅色
- 层状分布:基于材料结构
#### 划痕系统
表面可见方向性划痕:
- 沿着锤击方向的划痕
- 划痕在未打磨区域更明显
- 划痕影响表面粗糙度和反光
#### 水渍和氧化
淬火时的水渍痕迹:
- 蓝绿色氧化色调
- 油渍、灰尘等表面污渍
- 时间累积的氧化层变化
---
## 2. 玩家可调参数
| 参数功能名 | 默认值 | 范围 | 玩家感受 |
|-----------|--------|------|---------|
| 铁锈粗糙度 | 0.9 | 0.5-1.0 | 铁锈表面的粗糙程度。值越大,铁锈越粗糙 |
| 金属粗糙度 | 0.2 | 0.1-0.5 | 打磨后金属表面的粗糙程度。值越小,金属越光滑 |
| 铁锈基色 | (0.6, 0.3, 0.1) | RGB颜色 | 铁锈的基本颜色 |
| 金属基色 | (0.8, 0.8, 0.85) | RGB颜色 | 金属本体(钢材)的颜色 |
| 铁锈金属度 | 0.0 | 0.0-0.3 | 铁锈的金属反射程度。0为完全不反光 |
| 金属金属度 | 1.0 | 0.8-1.0 | 打磨后金属的反射程度。1为完全反光 |
| 大马士革图层开关 | 关闭 | 开启/关闭 | 是否启用大马士革层状花纹 |
### 推荐参数配置
**新铁块(完全生锈)**:
- 铁锈粗糙度 = 0.95
- 金属粗糙度 = 0.15
- 铁锈基色 = 橙红色 (0.7, 0.35, 0.15)
- 金属基色 = 钢铁色 (0.75, 0.75, 0.8)
**半旧铁块(部分打磨)**:
- 铁锈粗糙度 = 0.85
- 金属粗糙度 = 0.25
- 铁锈基色 = 深褐色 (0.5, 0.25, 0.1)
- 金属基色 = 亮钢铁色 (0.8, 0.8, 0.85)
**高碳钢(大马士革)**:
- 铁锈粗糙度 = 0.9
- 金属粗糙度 = 0.2
- 铁锈基色 = 深色层 (0.3, 0.15, 0.1)
- 金属基色 = 浅色层 (0.6, 0.55, 0.5)
- 大马士革图层开关 = 开启
---
## 3. 视觉/听觉反馈
### 3.1 视觉反馈
- **实时表面变化**: 锤击时,受击区域铁锈实时脱落,露出金属光泽
- **颜色渐变**: 从生锈的橙红色 → 打磨后的钢灰色,颜色过渡自然
- **粗糙度变化**: 从粗糙的哑光表面 → 平滑的金属表面,视觉质感明显
- **金属反光**: 打磨后表面能反射环境光,有真实的金属质感
### 3.2 表面细节
- **铁锈图案**: 随机的铁锈斑块分布,自然不重复
- **划痕细节**: 方向性划痕,增加真实感
- **氧化层**: 蓝绿色调的氧化痕迹
- **水渍**: 淬火后可见的水渍图案
### 3.3 听觉反馈
- **摩擦声**: 锤击时金属与金属的摩擦声
- **铁锈脱落声**: 可选的铁锈破碎声效
---
## 4. 边界与限制(玩家不应期望的行为)
### 4.1 表面细节限制
- **顶点密度瓶颈**: 当前系统使用顶点属性存储表面状态,细节程度受限于网格密度(20-50万顶点)
- **无物理反射**: 打磨效果通过粗糙度模拟,无法达到光线追踪级别的真实反射
- **纹理细节**: 表面细节(铁锈图案、划痕)是程序化生成的,不是真实纹理贴图
### 4.2 不可达效果
- 玩家不能期待系统支持"油污涂层"、"漆面"等超出锻造范围的表面处理
- 系统不会模拟"长期户外氧化"等时间跨度极大的效果
- 表面特征跟随性依赖于顶点属性,极端形变时可能出现轻微不连续
---
## 5. 验收清单
- [ ] 锤击后表面从"生锈"变"光亮",露出金属本体
- [ ] 金属度从 0.0 增加到 1.0(可视化)
- [ ] 粗糙度从 0.9 降低到 0.2(可视化)
- [ ] 支持铁锈、氧化层、酸蚀痕迹、划痕等多种表面状态
- [ ] **表面特征随形变一起移动,无漂移现象**(关键验收点)
- [ ] 铁锈图案自然不重复,空间连续
- [ ] 支持大马士革钢的层状花纹(可选)
- [ ] 支持方向性划痕效果(可选)
- [ ] 支持水渍和氧化痕迹(可选)
- [ ] 锤击期间帧率稳定 60 FPS
- [ ] 玩家能通过调整参数控制铁锈颜色、粗糙度等外观
- [ ] 不同材质(新铁块、半旧、高碳钢)有明显的视觉差异
---
## 6. 引用
- 对应技术设计: [../design/02-表面磨损-顶点属性与无漂移采样设计.md](../design/02-表面磨损-顶点属性与无漂移采样设计.md)
- 总体需求: [00-锻造系统总体需求.md](00-锻造系统总体需求.md)
- 原始设计文档(归档): [../_archive/plans/2026-01-22-表面磨损系统细节.md](../_archive/plans/2026-01-22-表面磨损系统细节.md)
@@ -0,0 +1,179 @@
# 网格质量与性能需求
**项目**: BladeSmith
**文档类型**: 需求文档(专题)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-22-网格质量优化细节.md`
> 本文档从玩家视角描述网格质量与性能的需求。技术实现见 [design/03-网格质量-增量式优化设计.md](../design/03-网格质量-增量式优化设计.md)。总体需求见 [00-锻造系统总体需求.md](00-锻造系统总体需求.md)。
---
## 1. 玩家可见行为
### 1.1 正常网格质量
玩家应该看不到网格退化现象。连续锻打后,金属表面应当保持平滑、连续,不会出现奇怪形状。
```
初始均匀网格(良好,玩家看不见网格,只看到平滑表面):
/\ /\ /\
/__\/__\/__\
/\ /\ /\
/__\/__\/__\
```
### 1.2 网格退化现象(玩家不应看到)
如果网格质量下降,玩家会直接感受到以下问题:
#### 视觉影响
| 现象 | 玩家感受 | 严重度 |
|------|---------|--------|
| 着色异常 | 表面出现条纹、色块 | 高 |
| 闪烁问题 | 出现"空洞"或闪烁 | 高 |
| 边缘锯齿 | 刀刃呈锯齿状不平整 | 高 |
| 法线扭曲 | 表面反光不自然 | 中 |
```
锤击后网格退化(玩家看到的是视觉缺陷):
/\ /|\ /\ ← 细长三角形导致条纹
/__\ /_|_\ /__\
^^ 过小 ^^ ← 极小三角形导致闪烁
```
#### 性能影响
| 现象 | 玩家感受 | 严重度 |
|------|---------|--------|
| 帧率下降 | 锤击时掉帧,操作延迟 | 高 |
| 响应变慢 | 锤击到形变有明显延迟 | 高 |
| 碰撞检测失效 | 锤击检测不准确,"打空" | 高 |
#### 数值稳定性问题(影响碰撞)
| 现象 | 玩家感受 | 严重度 |
|------|---------|--------|
| 浮点误差累积 | 形变计算不准确 | 中 |
| 碰撞检测不稳定 | 锤击位置判定错误 | 高 |
### 1.3 玩家承诺
**连续锻打 50-100 次后,网格质量仍应保持良好。**
具体表现为:
- 刀刃仍然平整,无明显锯齿
- 表面着色无条纹、无闪烁、无"空洞"
- 锻打不会让金属"莫名其妙"地出现奇怪形状
- 锤击响应时间 < 10ms(玩家不可察觉)
- 锤击期间帧率稳定 60 FPS
---
## 2. 玩家可调参数
| 参数功能名 | 默认值 | 范围 | 玩家感受 |
|-----------|--------|------|---------|
| 自动网格优化开关 | 开启 | 开启/关闭 | 是否自动优化网格质量 |
| 优化区域范围倍数 | 1.5 | 1.0-2.0 | 锤击影响区域的多少倍范围会被优化 |
| 边缘过渡平滑强度 | 0.5 | 0.1-1.0 | 控制顶点平滑的强度。值越大,表面越平滑 |
| 平滑迭代次数 | 2 | 1-5 | 平滑操作的重复次数。次数越多,效果越好但越慢 |
| 重网格频率 | 5 | 3-20 | 每几次锤击执行一次完整重网格。值越小质量越好但越慢 |
| 平滑优化总耗时预算 | 2.0 | 1.0-5.0 | 单次锤击的网格优化时间预算(毫秒) |
### 推荐参数配置
**锻造平面(大范围形变)**:
- 优化区域范围倍数 = 2.0(大范围优化)
- 边缘过渡平滑强度 = 0.5
- 平滑迭代次数 = 2
- 重网格频率 = 10(低频重网格)
**锻造边缘(精细形变)**:
- 优化区域范围倍数 = 1.2(局部优化)
- 边缘过渡平滑强度 = 0.5
- 平滑迭代次数 = 3
- 重网格频率 = 5(高频重网格)
**性能优先模式**:
- 优化区域范围倍数 = 1.0
- 边缘过渡平滑强度 = 0.3
- 平滑迭代次数 = 1
- 重网格频率 = 20(极低频重网格)
### 自动调参
系统会根据当前帧率自动调整优化强度:
- **帧率低(< 30 FPS)**: 降低优化频率,扩大优化区域
- **帧率高(> 55 FPS)**: 提高优化质量,增加优化频率
---
## 3. 视觉/听觉反馈
### 3.1 视觉反馈
- **平滑形变**: 网格优化是透明的,玩家只看到平滑的形变
- **无闪烁**: 表面不会出现闪烁或空洞
- **无条纹**: 表面颜色连续,无明显条纹或色块
### 3.2 性能反馈
- **响应迅速**: 锤击到形变响应时间 < 10ms
- **帧率稳定**: 锤击期间帧率保持 60 FPS
### 3.3 调试模式(可选)
开发者可启用调试视图:
- **退化三角形热图**: 显示网格质量低下的区域(红色)
- **质量热图**: 显示网格质量分布(蓝色=好,红色=差)
- **性能统计**: 显示每次锤击的优化耗时
---
## 4. 边界与限制(玩家不应期望的行为)
### 4.1 网格质量限制
- **极端形变**: 当形变超过 50% 时,优化效果显著下降,玩家可能看到表面质量下降
- **拓扑变化**: 系统无法处理网格撕裂、融合等拓扑变化(如锻打折叠金属)
- **细节损失**: 重网格化时,顶点属性需要插值,可能有轻微精度损失
### 4.2 性能限制
- **内存占用**: 高网格密度(100万+顶点)会增加内存占用
- **硬件依赖**: 低端硬件可能需要降低重网格频率或优化质量
### 4.3 不可达效果
- 玩家不能期待系统支持"无限形变"而不产生网格质量下降
- 系统不会在低端硬件上保持 60 FPS(需要自动降低质量)
- 网格优化是自动的,玩家不能手动控制每个顶点的移动
---
## 5. 验收清单
- [ ] 连续锻打 50 次后网格质量仍良好
- [ ] 无明显细长三角形(长宽比 > 10:1)
- [ ] 刀刃边缘无明显锯齿
- [ ] 表面着色无条纹、无闪烁、无"空洞"
- [ ] 锻打不会让金属"莫名其妙"地出现奇怪形状
- [ ] 锤击响应时间 < 10ms(玩家不可察觉)
- [ ] 锤击期间帧率稳定 60 FPS
- [ ] 网格优化过程透明,不影响形变视觉效果
- [ ] 玩家能通过调整参数控制优化强度和频率
- [ ] 系统能根据帧率自动调整优化设置
- [ ] 单次锤击总耗时(形变+优化)≤ 7ms
- [ ] 碰撞检测稳定,不会出现"打空"或检测错误
---
## 6. 引用
- 对应技术设计: [../design/03-网格质量-增量式优化设计.md](../design/03-网格质量-增量式优化设计.md)
- 总体需求: [00-锻造系统总体需求.md](00-锻造系统总体需求.md)
- 原始设计文档(归档): [../_archive/plans/2026-01-22-网格质量优化细节.md](../_archive/plans/2026-01-22-网格质量优化细节.md)
@@ -0,0 +1,174 @@
# 加工硬化与晶粒演化需求
**项目**: BladeSmith
**文档类型**: 需求文档(专题)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-22-物理模拟架构细节.md`
> 本文档从玩家视角描述加工硬化与晶粒演化的需求。技术实现见 [design/04-物理模拟-加工硬化与晶粒演化设计.md](../design/04-物理模拟-加工硬化与晶粒演化设计.md)。总体需求见 [00-锻造系统总体需求.md](00-锻造系统总体需求.md)。
---
## 1. 玩家可见行为
### 1.1 加工硬化现象
**金属越打越硬**:
- 反复锻打同一块金属区域时,该区域会逐渐变硬
- 变硬的区域需要更大的锤击力量才能继续形变
- 或需要更多次锤击才能达到同样的形变效果
- 连续锻打会让形变变得越来越困难
**加热软化**:
- 将金属加热到高温后,已硬化的区域会软化
- 软化后的金属可以继续容易锻打
- 这就是"回火"机制的核心
### 1.2 晶粒演化影响
**细晶粒材料**:
- 细晶粒的材料强度更高
- 更难锻打,但成品质量更好
- 表面更光滑,性能更稳定
**粗晶粒材料**:
- 粗晶粒的材料更容易形变
- 锻打相对容易,但成品强度较低
- 适合需要大量形变的粗加工阶段
### 1.3 大马士革花纹
**层状材料**:
- 大马士革钢由多层不同材料交替堆叠
- 锻打时这些层次会扭曲流动
- 形成独特的波浪形花纹
**花纹可见性**:
- 花纹会随着锻打过程自然演化
- 锻打越多,花纹越复杂
- 酸蚀处理后花纹会更加清晰
---
## 2. 玩家可调参数
| 参数功能名 | 默认值 | 范围 | 玩家感受 |
|-----------|--------|------|----------|
| 硬化速率 | 0.5 | 0.2-1.0 | 控制金属变硬的速度,值越大变硬越快 |
| 软化温度阈值 | 600°C | 500-700°C | 超过此温度金属开始软化 |
| 最大硬化程度 | 1.0 | 0.8-1.2 | 金属能达到的最硬程度 |
| 晶粒初始尺寸 | 0.5 | 0.2-0.8 | 初始材料的晶粒粗细 |
| 晶粒细化速率 | 0.1 | 0.05-0.2 | 锻打让晶粒变细的速度 |
| 层状材料层数 | 10 | 5-20 | 大马士革钢的层次数量 |
| 层状材料厚度 | 2mm | 1-5mm | 每一层的厚度 |
---
## 3. 视觉/听觉反馈
### 3.1 硬度可视化
**颜色变化**:
- 软金属: 棕色调
- 硬金属: 银白色调
- 硬度渐变: 从棕到白的过渡反映硬度分布
**形变阻力反馈**:
- 锤击时,高硬度区域反弹更明显
- 锤击音效会因硬度变化而略有不同
- 锤击动画可能在高硬度区域略微减慢
### 3.2 晶粒影响表现
**表面质感**:
- 细晶粒: 表面更光滑,反射更均匀
- 粗晶粒: 表面略粗糙,反射不规则
### 3.3 大马士革花纹视觉
**颜色对比**:
- 深色层: 深棕或近黑色
- 浅色层: 浅灰或银白色
- 交替出现形成波纹效果
**扭曲效果**:
- 花纹随形变自然扭曲
- 锻打方向影响花纹走向
- 边缘区域花纹可能更密集
---
## 4. 边界与限制(玩家不应期望的行为)
### 4.1 硬化限制
- 金属不会无限变硬,存在饱和上限
- 软化不是瞬间完成,需要时间加热
- 已开裂区域无法通过软化恢复
### 4.2 晶粒演化限制
- 晶粒不会无限细化或长大
- 超过一定温度后晶粒可能突然长大(过度加热)
- 晶粒状态不会自动逆转
### 4.3 大马士革花纹限制
- 花纹仅在有层状材料时出现
- 普通钢无法产生类似花纹
- 花纹完全取决于锻打路径,无法"绘制"或预设
---
## 5. 验收清单
### 5.1 加工硬化
- [ ] 连续锻打同一区域10次,形变明显变难
- [ ] 加热到600°C后,形变难度降低至初始状态
- [ ] 硬度分布可视化清晰可见
- [ ] 不同材料的硬化速率有可感知差异
### 5.2 晶粒演化
- [ ] 细晶粒材料比粗晶粒更难锻打
- [ ] 过度加热后晶粒变粗,材料变软
- [ ] 晶粒状态影响表面质感可见
### 5.3 大马士革花纹
- [ ] 层状材料显示清晰的颜色对比
- [ ] 锻打后花纹自然扭曲
- [ ] 酸蚀处理后花纹更加明显
- [ ] 花纹随锻打过程不断演化
---
## 6. 引用
### 6.1 相关需求文档
- [00-锻造系统总体需求.md](00-锻造系统总体需求.md) - 系统总览
- [03-网格质量与性能需求.md](03-网格质量与性能需求.md) - 网格性能约束
### 6.2 原始设计文档
- [_archive/plans/2026-01-22-物理模拟架构细节.md](../_archive/plans/2026-01-22-物理模拟架构细节.md) - 技术实现细节
### 6.3 物理基础
- 《金属塑性成形原理》 - 加工硬化机理
- 《材料科学基础》 - 晶粒结构对材料性能影响
- 《大马士革钢制造工艺》 - 层状材料与花纹形成
@@ -0,0 +1,236 @@
# 淬火退火相变需求
**项目**: BladeSmith
**文档类型**: 需求文档(专题)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-23-淬火退火相变系统设计.md`
> 本文档从玩家视角描述淬火退火相变的需求。技术实现见 [design/05-淬火退火相变系统设计.md](../design/05-淬火退火相变系统设计.md)。总体需求见 [00-锻造系统总体需求.md](00-锻造系统总体需求.md)。
---
## 1. 玩家可见行为
### 1.1 温度区间影响
**黄金区间(900-1100°C)**:
- 最佳淬火效果,硬度提升最大
- 淬火成功率最高
- 风险最低,不易开裂
**次优区间(800-900°C 或 1100-1200°C)**:
- 硬度有一定提升,但不如黄金区间
- 效果中等,需要玩家技巧把握
**无效区间(< 800°C)**:
- 淬火几乎无效,硬度无明显变化
- 浪费淬火机会
**危险区间(> 1200°C)**:
- 硬度提升很低
- 材料有较高开裂风险
- 应避免在此温度淬火
### 1.2 冷却速率差异
**水淬(快速冷却)**:
- 硬度提升最大
- 脆性也最大
- 氧化层深色,可能需要打磨去除
**油淬(中速冷却)**:
- 硬度适中
- 脆性中等
- 氧化层浅棕色,相对美观
**空冷(慢速冷却)**:
- 硬度提升小,近似退火
- 脆性低
- 仅轻微氧化
### 1.3 硬度与脆性变化
**硬度提升**:
- 成功淬火后刀具硬度显著提高
- 硬度越高的刀具越难切割硬物
- 但也能保持刃口更久
**脆性累积**:
- 快速冷却会增加材料脆性
- 高脆性刀具容易在强力冲击下开裂
- 玩家需要在硬度和韧性之间权衡
---
## 2. 玩家可调参数
| 参数功能名 | 默认值 | 范围 | 玩家感受 |
|-----------|--------|------|----------|
| 黄金温度下限 | 900°C | 800-1000°C | 低于此温度淬火效果变差 |
| 黄金温度上限 | 1100°C | 1000-1200°C | 高于此温度淬火风险增加 |
| 临界温度下限 | 800°C | 600-900°C | 低于此温度淬火基本无效 |
| 临界温度上限 | 1200°C | 1100-1400°C | 高于此温度开裂风险高 |
| 水淬硬度倍数 | 2.5 | 2.0-3.0 | 水淬能提升的硬度倍数 |
| 油淬硬度倍数 | 1.8 | 1.5-2.2 | 油淬能提升的硬度倍数 |
| 空冷硬度倍数 | 1.2 | 1.0-1.4 | 空冷能提升的硬度倍数 |
| 淬火脆性增益 | 0.6 | 0.4-0.8 | 淬火增加的最大脆性 |
| 应力松弛速度 | 0.5 | 0.2-0.8 | 回火时应力释放速度 |
---
## 3. 视觉/听觉反馈
### 3.1 脆性颜色反馈
**脆性等级颜色**:
- 绿色(脆性 < 0.3): 韧性良好,安全
- 黄色(脆性 0.3-0.6): 中度脆性,需注意
- 红色(脆性 ≥ 0.6): 高度脆性,易开裂
**显示方式**:
- 脆性扫描时顶点颜色着色
- 高脆性区域闪烁预警
- UI面板实时显示平均脆性
### 3.2 三阶段淬火视觉
**阶段1: 淬火过程(临时高辨识度)**:
- 材质自发光随温度变化
- 屏幕边缘显示"淬火进行中"提示
- 顶点统计显示淬火覆盖率
- 品质评分实时更新
**阶段2: 冷却过渡(逐步恢复正常)**:
- 颜色从临时反馈平滑过渡到真实颜色
- 自发光逐渐消失
- 材质参数逐步恢复常态
- 过渡时长0.5-1.0秒
**阶段3: 最终真实表现(永久保留)**:
- 显示真实的物理热处理效果
- 回火色系统激活
- 氧化层视觉效果呈现
### 3.3 回火色系统
**温度-颜色映射**:
| 回火温度 | 颜色 | 视觉描述 |
|---------|------|----------|
| 20-150°C(无回火) | 银灰色 | 金属原色,无明显变化 |
| 150-200°C | 淡黄色 | 轻微发黄,柔和光泽 |
| 200-250°C | 金黄/麦秆色 | 金黄色泽,温暖感 |
| 250-300°C | 棕色 | 深棕色,沉稳质感 |
| 300-350°C | 紫色 | 紫色调,独特外观 |
| 350-400°C | 蓝色 | 蓝色调,精致感 |
| >400°C | 灰色 | 失去光泽,灰色调 |
### 3.4 氧化层表现
**不同冷却介质的氧化差异**:
- 水淬: 深色氧化层(0.8-1.0氧化度)
- 油淬: 浅棕色氧化层(0.4-0.6氧化度)
- 空冷: 轻微氧化(0.1-0.3氧化度)
**氧化层与打磨**:
- 打磨可以去除部分氧化层
- 打磨后露出金属底色
- 回火色在打磨区域减弱
---
## 4. 边界与限制(玩家不应期望的行为)
### 4.1 温度限制
- 无法在低温(< 800°C)获得显著淬火效果
- 超高温(> 1200°C)淬火不会增加硬度,只会增加风险
- 温度不在最佳区间时淬火效果可能不均匀
### 4.2 冷却限制
- 冷却速率受介质限制,无法超越物理极限
- 水淬无法让所有材料达到最大硬度(低碳钢难淬硬)
- 冷却不均匀会导致硬度分布不均
### 4.3 脆性限制
- 淬火增加的脆性无法完全消除
- 回火可以部分恢复脆性,但无法恢复到未淬火状态
- 高脆性刀具在高冲击下必定开裂
### 4.4 视觉限制
- 回火色需要一定时间才能稳定呈现
- 氧化层颜色会随时间轻微变化
- 不同材料的回火色可能略有差异
---
## 5. 验收清单
### 5.1 温度区间判定
- [ ] 在黄金区间淬火,硬度提升最大
- [ ] 在无效区间淬火,硬度无变化
- [ ] 在危险区间淬火,开裂风险显著增加
### 5.2 冷却速率差异
- [ ] 水淬硬度最高,脆性最大
- [ ] 油淬硬度适中,脆性中等
- [ ] 空冷硬度提升小,脆性低
### 5.3 三阶段可视化
- [ ] 淬火过程有强视觉反馈
- [ ] 冷却过渡平滑自然
- [ ] 最终效果真实可信
### 5.4 回火色系统
- [ ] 不同回火温度产生不同颜色
- [ ] 回火色随温度变化连续过渡
- [ ] 打磨后回火色减弱
### 5.5 氧化层表现
- [ ] 不同冷却介质产生不同氧化层颜色
- [ ] 水淬氧化层最深色
- [ ] 打磨可去除部分氧化层
---
## 6. 引用
### 6.1 相关需求文档
- [00-锻造系统总体需求.md](00-锻造系统总体需求.md) - 系统总览
- [06-应力累积与开裂需求.md](06-应力累积与开裂需求.md) - 应力与脆性交互
### 6.2 原始设计文档
- [_archive/plans/2026-01-23-淬火退火相变系统设计.md](../_archive/plans/2026-01-23-淬火退火相变系统设计.md) - 技术实现细节
### 6.3 物理基础
- 《金属热处理原理与工艺》 - 淬火退火原理
- 《钢的热处理》 - 回火色机理
- 《金属材料学》 - 相变与组织结构
@@ -0,0 +1,256 @@
# 应力累积与开裂需求
**项目**: BladeSmith
**文档类型**: 需求文档(专题)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-23-应力累积系统设计.md`
> 本文档从玩家视角描述应力累积与开裂的需求。技术实现见 [design/06-应力累积系统设计.md](../design/06-应力累积系统设计.md)。总体需求见 [00-锻造系统总体需求.md](00-锻造系统总体需求.md)。
---
## 1. 玩家可见行为
### 1.1 应力来源
**锤击产生应力**:
- 锤击时,材料被迫形变,相邻区域产生内部应力
- 锤击越用力,产生的应力越大
- 高硬度区域锤击产生的应力更高
**淬火产生应力**:
- 快速冷却时,材料内外温度不均
- 温度差异导致膨胀不均,产生热应力
- 水淬产生的应力最大,油淬次之,空冷最小
**温度梯度产生应力**:
- 材料不同区域温度不同时产生应力
- 加热不均匀或冷却不均匀都会累积应力
### 1.2 应力对锻打的影响
**形变阻力增加**:
- 高应力区域更难锻打
- 需要更大的锤击力量
- 或需要更多次锤击才能达到同样的形变效果
**手感反馈**:
- 锤击高应力区域时,锤击感觉更"硬"
- 音效可能略有不同
- 锤击动画可能略微减慢
### 1.3 应力导致形变
**刀身弯曲**:
- 应力分布不均时,刀身会自然弯曲
- 弯曲方向与应力梯度相关
- 应力差越大,弯曲越明显
**扭曲变形**:
- 刀身两侧应力不均时,刀身会扭曲
- 扭曲程度与应力差成正比
- 需要通过平衡锻打来避免
### 1.4 裂纹生成与扩展
**裂纹起始**:
- 应力超过材料强度时产生裂纹
- 高应力区域优先开裂
- 开裂有一定随机性(避免每次完全相同)
**裂纹扩展**:
- 裂纹沿应力梯度方向扩展
- 优先向应力最高的方向生长
- 应力差越大,扩展越快
**裂纹合并**:
- 多条裂纹可能相交
- 相交后可能形成大块材料脱落
- 网格拓扑可能断裂
---
## 2. 玩家可调参数
| 参数功能名 | 默认值 | 范围 | 玩家感受 |
|-----------|--------|------|----------|
| 最大应力值 | 150.0 | 100-200 | 材料能承受的最大应力 |
| 锤击应力系数 | 10.0 | 5-20 | 控制锤击产生应力的速率 |
| 热应力系数 | 0.005 | 0.001-0.01 | 控制淬火产生应力的速率 |
| 残余应力系数 | 5.0 | 2-10 | 控制形变受限产生应力的速率 |
| 应力扩散系数 | 0.2 | 0.1-0.3 | 控制应力向周围扩散的速度 |
| 弯曲敏感度 | 0.001 | 0.0005-0.002 | 控制应力导致弯曲的程度 |
| 扭曲敏感度 | 0.0005 | 0.0002-0.001 | 控制应力导致扭曲的程度 |
| 临界应力阈值 | 120.0 | 80-150 | 超过此值可能开裂 |
| 裂纹宽度 | 0.05 | 0.01-0.1 | 裂纹开口的视觉宽度 |
| 应力松弛时间(常温) | 60.0s | 30-120s | 常温下应力自然释放的时间 |
| 应力松弛时间(回火) | 10.0s | 5-20s | 回火温度下应力释放的时间 |
---
## 3. 视觉/听觉反馈
### 3.1 应力扫描(辅助功能)
**触发方式**:
- 按住Alt键切换到"应力视图"
- 或在UI中选择"应力扫描"工具
**颜色着色**:
- 蓝色: 低应力区域(< 30% 应力极限)
- 绿色: 中等应力区域(30-60% 应力极限)
- 黄色: 高应力区域(60-90% 应力极限)
- 红色: 接近开裂区域(≥ 90% 应力极限)
**红色区域特殊效果**:
- 闪烁效果,预警即将开裂
- 自发光增强,吸引玩家注意
**应力流线(可选)**:
- 显示应力传导路径
- 从高应力区域流向低应力区域
- 帮助玩家理解应力分布
**UI面板**:
- 实时显示最大应力值
- 显示平均应力值
- 显示超阈值顶点数量
- 显示已产生裂纹数量
### 3.2 裂纹视觉表现
**几何表现**:
- 裂缝开口: 裂纹两侧顶点略微分离
- 边缘抖动: 裂纹边缘不光滑,粗糙断裂
- 深度变化: 裂纹深处更暗
**材质表现**:
- 锈迹: 裂纹区域显示氧化痕迹
- 内部氧化: 裂缝深处更暗,模拟内部氧化
- 纹理扰动: 裂纹区域表面纹理混乱
**裂纹扩展动画**:
- 裂纹逐帧缓慢生长
- 生长速度与应力相关
- 方向沿应力梯度
### 3.3 应力释放反馈
**开裂后应力释放**:
- 开裂瞬间,裂纹区域应力大幅降低
- 周围区域应力重新分布
- 视觉上裂纹区域颜色变浅
**回火后应力释放**:
- 加热至回火温度(200-400°C)
- 应力逐渐降低
- 但裂纹无法愈合
---
## 4. 边界与限制(玩家不应期望的行为)
### 4.1 应力累积限制
- 应力不会无限累积,存在上限
- 应力上限由材料强度决定
- 不同材料的应力上限可能不同
### 4.2 应力释放限制
- 常温下应力释放很慢(需要分钟级时间)
- 回火可以加速释放,但仍需要时间
- 开裂释放应力最快,但造成永久损伤
### 4.3 裂纹限制
- 裂纹一旦产生无法愈合
- 回火和打磨无法消除裂纹
- 裂纹永久降低刀具性能
### 4.4 应力扫描限制
- 应力扫描是辅助功能,不影响真实物理
- 退出扫描模式后完全恢复正常视觉
- 无任何残留效果
---
## 5. 验收清单
### 5.1 应力累积
- [ ] 连续锤击同一区域,应力不断累积
- [ ] 高硬度区域锤击产生更多应力
- [ ] 淬火时产生明显热应力
### 5.2 形变阻力
- [ ] 高应力区域锤击更困难
- [ ] 锤击手感明显变"硬"
- [ ] 音效和动画有细微变化
### 5.3 弯曲/扭曲
- [ ] 应力不均导致刀身自然弯曲
- [ ] 弯曲方向与应力梯度一致
- [ ] 应力差越大,弯曲越明显
### 5.4 裂纹生成
- [ ] 应力超过阈值时产生裂纹
- [ ] 裂纹在高应力区域优先出现
- [ ] 开裂有一定随机性
### 5.5 裂纹扩展
- [ ] 裂纹沿应力梯度方向生长
- [ ] 生长速度与应力相关
- [ ] 多条裂纹可以合并
### 5.6 应力扫描
- [ ] 按Alt键清晰显示应力分布
- [ ] 颜色分级准确反映应力等级
- [ ] UI面板实时更新应力统计
---
## 6. 引用
### 6.1 相关需求文档
- [00-锻造系统总体需求.md](00-锻造系统总体需求.md) - 系统总览
- [05-淬火退火相变需求.md](05-淬火退火相变需求.md) - 淬火产生应力
- [07-疲劳与刀具耐久度需求.md](07-疲劳与刀具耐久度需求.md) - 疲劳与应力交互
### 6.2 原始设计文档
- [_archive/plans/2026-01-23-应力累积系统设计.md](../_archive/plans/2026-01-23-应力累积系统设计.md) - 技术实现细节
### 6.3 物理基础
- 《材料力学》 - 应力分布与形变
- 《金属塑性成形原理》 - 残余应力
- 《断裂力学》 - 裂纹生成与扩展
@@ -0,0 +1,263 @@
# 疲劳与刀具耐久度需求
**项目**: BladeSmith
**文档类型**: 需求文档(专题)
**版本**: 2.0
**最后更新**: 2026-08-11
**状态**: 整合自原 `2026-01-23-疲劳累积与耐久度系统设计.md`
> 本文档从玩家视角描述疲劳累积与刀具耐久度的需求。技术实现见 [design/07-疲劳与耐久度系统设计.md](../design/07-疲劳与耐久度系统设计.md)。总体需求见 [00-锻造系统总体需求.md](00-锻造系统总体需求.md)。
---
## 1. 玩家可见行为
### 1.1 疲劳累积
**反复锻打累积疲劳**:
- 每次锻打都会让材料累积疲劳
- 同一区域锻打次数越多,疲劳越高
- 疲劳累积是渐进式的,不会突然跳变
**过度锻打加速疲劳**:
- 单次形变过大时,疲劳累积加速
- 高应力区域疲劳累积更快
- 温度过低时疲劳累积加速
**温度影响疲劳**:
- 高温(> 800°C): 疲劳累积很慢
- 常温: 疲劳累积正常速度
- 低温(< 200°C): 疲劳累积加速
### 1.2 疲劳裂纹
**疲劳裂纹起始**:
- 疲劳值接近极限时可能产生裂纹
- 高应力区域更容易产生疲劳裂纹
- 开裂有一定随机性
**疲劳裂纹特点**:
- 与应力裂纹不同,可能产生多条细小裂纹
- 裂纹沿高疲劳值方向扩展
- 扩展速度与疲劳值成正比
**疲劳裂纹扩展**:
- 每次锻打都可能让裂纹扩展
- 疲劳值越高,扩展概率越大
- 裂纹可能交织成网状
### 1.3 刀具耐久度
**耐久度构成**:
- 平均疲劳: 整个刀具的平均疲劳程度
- 裂纹惩罚: 已有裂纹的数量
- 应力惩罚: 最大应力区域的影响
**耐久度影响**:
- 耐久度高的刀具使用寿命长
- 耐久度低的刀具容易损坏
- 耐久度归零时刀具失效
### 1.4 使用中的损伤累积
**切割/砍击**:
- 每次使用都会造成微小损伤
- 冲击点附近疲劳增加
- 冲击力越大,损伤越大
**抛光/打磨**:
- 减少表面疲劳痕迹
- 改善外观,但不恢复耐久度
- 让刀具看起来更"新"
---
## 2. 玩家可调参数
| 参数功能名 | 默认值 | 范围 | 玩家感受 |
|-----------|--------|------|----------|
| 正常锻打疲劳率 | 0.001 | 0.0005-0.002 | 控制正常锻打的疲劳累积速度 |
| 过度锻打疲劳率 | 0.005 | 0.002-0.01 | 控制过锻的疲劳累积速度 |
| 应力集中疲劳率 | 0.010 | 0.005-0.02 | 控制高应力区的疲劳累积速度 |
| 临界应变阈值 | 0.1 | 0.05-0.2 | 超过此值为过度锻打 |
| 高温疲劳因子 | 0.1 | 0.05-0.2 | 高温时疲劳减缓程度 |
| 常温疲劳因子 | 1.0 | 0.8-1.2 | 常温时疲劳正常速度 |
| 低温疲劳因子 | 2.0 | 1.5-2.5 | 低温时疲劳加速程度 |
| 单条裂纹惩罚 | 0.1 | 0.05-0.2 | 每条裂纹扣除的耐久度 |
| 应力惩罚系数 | 0.2 | 0.1-0.3 | 高应力扣除的耐久度 |
| 回火疲劳恢复率 | 0.1 | 0.05-0.2 | 回火时疲劳恢复速度 |
| 回火耐久恢复率 | 0.05 | 0.02-0.1 | 回火时耐久恢复速度 |
| 冲击疲劳率 | 0.0001 | 0.00005-0.0002 | 使用时的疲劳累积速度 |
| 主裂纹长度阈值 | 10.0 | 5.0-20.0 | 超过此长度的裂纹可导致刀具失效 |
---
## 3. 视觉/听觉反馈
### 3.1 疲劳扫描(辅助功能)
**触发方式**:
- 按住Shift键切换到"疲劳视图"
- 或在UI中选择"疲劳扫描"工具
**颜色着色**:
- 蓝色: 低疲劳值(< 0.3)
- 绿色: 中低疲劳值(0.3-0.7)
- 黄色: 中高疲劳值(0.7-0.9)
- 橙色: 接近极限(0.9-0.95)
- 红色: 危险区(> 0.95)
**红色区域特殊效果**:
- 脉冲效果,危险预警
- 自发光闪烁,吸引注意
**UI面板**:
- 平均疲劳值
- 最大疲劳值
- 危险区域数量(疲劳 > 0.9)
- 预估剩余寿命
### 3.2 疲劳裂纹视觉
**几何表现**:
- 细小裂缝: 开口宽度较小
- 边缘锯齿: 裂纹边缘不光滑,粗糙
**材质表现**:
- 表面氧化: 显示轻微锈迹
- 内部损伤: 深处更暗,模拟材料损伤
**裂纹扩展动画**:
- 裂纹逐帧缓慢生长
- 生长速度与疲劳值相关
- 可能产生多条细小裂纹
### 3.3 耐久度UI
**耐久度显示**:
- 进度条或百分比显示
- 颜色随耐久度变化(绿→黄→红)
- 实时更新
**耐久度预警**:
- 耐久度低于30%时显示警告
- 低于10%时闪烁警示
- 接近0时红屏闪烁
---
## 4. 边界与限制(玩家不应期望的行为)
### 4.1 疲劳累积限制
- 疲劳值不会超过1.0
- 疲劳累积到极限后可能触发失效
- 不同材料的疲劳特性可能不同
### 4.2 耐久度恢复限制
- 回火可以部分恢复疲劳
- 但裂纹无法愈合,裂纹惩罚永久存在
- 打磨不恢复耐久度,只改善外观
### 4.3 刀具失效限制
- 耐久度归零后刀具必定失效
- 主裂纹存在时刀具必定失效
- 瞬间强力冲击可能导致刀具断裂
- 失效的刀具无法修复
### 4.4 疲劳扫描限制
- 疲劳扫描是辅助功能,不影响真实物理
- 退出扫描模式后完全恢复正常视觉
- 无任何残留效果
---
## 5. 验收清单
### 5.1 疲劳累积
- [ ] 连续锻打同一区域,疲劳不断增加
- [ ] 过度锻打时疲劳累积加速
- [ ] 高应力区域疲劳累积更快
- [ ] 高温时疲劳累积减缓
- [ ] 低温时疲劳累积加速
### 5.2 疲劳裂纹
- [ ] 疲劳接近极限时产生裂纹
- [ ] 疲劳裂纹可能有多条
- [ ] 裂纹沿高疲劳值方向扩展
- [ ] 裂纹扩展速度与疲劳相关
### 5.3 耐久度计算
- [ ] 耐久度准确反映疲劳、裂纹、应力状态
- [ ] 裂纹越多,耐久度越低
- [ ] 高应力区域耐久度降低
### 5.4 使用损伤
- [ ] 切割/砍击造成疲劳累积
- [ ] 冲击力越大,损伤越大
- [ ] 抛光/打磨改善外观
### 5.5 耐久度恢复
- [ ] 回火可部分恢复疲劳
- [ ] 回火不消除裂纹
- [ ] 打磨不恢复耐久度
### 5.6 刀具失效
- [ ] 耐久度归零时刀具断裂
- [ ] 主裂纹存在时刀具断裂
- [ ] 瞬间强力冲击可能导致断裂
- [ ] 断裂有清晰的视觉和音效
### 5.7 疲劳扫描
- [ ] 按Shift键清晰显示疲劳分布
- [ ] 颜色分级准确反映疲劳等级
- [ ] UI面板实时更新疲劳统计
- [ ] 退出扫描后恢复正常视觉
---
## 6. 引用
### 6.1 相关需求文档
- [00-锻造系统总体需求.md](00-锻造系统总体需求.md) - 系统总览
- [06-应力累积与开裂需求.md](06-应力累积与开裂需求.md) - 疲劳与应力交互
### 6.2 原始设计文档
- [_archive/plans/2026-01-23-疲劳累积与耐久度系统设计.md](../_archive/plans/2026-01-23-疲劳累积与耐久度系统设计.md) - 技术实现细节
### 6.3 物理基础
- 《材料疲劳与断裂》 - 疲劳累积机理
- 《金属物理学》 - 耐久度与疲劳关系
- 《工程材料力学》 - 刀具失效判据
+10
View File
@@ -0,0 +1,10 @@
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"unreal-mcp": {
"type": "remote",
"url": "http://127.0.0.1:8000/mcp",
"enabled": true
}
}
}