diff --git a/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset b/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset index 37a6aa3..d4c9225 100644 Binary files a/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset and b/Content/FirstPerson/Blueprints/BP_FirstPersonCharacter.uasset differ diff --git a/Content/FirstPerson/Input/IMC_Hammer.uasset b/Content/FirstPerson/Input/IMC_Hammer.uasset index 09a0074..8cbc9ca 100644 Binary files a/Content/FirstPerson/Input/IMC_Hammer.uasset and b/Content/FirstPerson/Input/IMC_Hammer.uasset differ diff --git a/Content/FirstPerson/Maps/_GENERATED/Administrator/IronBlock_UVFixed1.uasset b/Content/FirstPerson/Maps/_GENERATED/Administrator/IronBlock_UVFixed1.uasset index 1ba457e..5872468 100644 Binary files a/Content/FirstPerson/Maps/_GENERATED/Administrator/IronBlock_UVFixed1.uasset and b/Content/FirstPerson/Maps/_GENERATED/Administrator/IronBlock_UVFixed1.uasset differ diff --git a/Content/Materials/M_HitCal.uasset b/Content/Materials/M_HitCal.uasset index 81a1666..d053629 100644 Binary files a/Content/Materials/M_HitCal.uasset and b/Content/Materials/M_HitCal.uasset differ diff --git a/Content/Materials/M_Iron.uasset b/Content/Materials/M_Iron.uasset index 80bf45b..2ca34a2 100644 Binary files a/Content/Materials/M_Iron.uasset and b/Content/Materials/M_Iron.uasset differ diff --git a/Content/Materials/M_Iron_Inst.uasset b/Content/Materials/M_Iron_Inst.uasset index 72aff19..d2c8a11 100644 Binary files a/Content/Materials/M_Iron_Inst.uasset and b/Content/Materials/M_Iron_Inst.uasset differ diff --git a/Content/__ExternalActors__/FirstPerson/Maps/FirstPersonMap/4/21/IS377PW86F39YE9IWWQYVI.uasset b/Content/__ExternalActors__/FirstPerson/Maps/FirstPersonMap/4/21/IS377PW86F39YE9IWWQYVI.uasset deleted file mode 100644 index 8c1f49a..0000000 Binary files a/Content/__ExternalActors__/FirstPerson/Maps/FirstPersonMap/4/21/IS377PW86F39YE9IWWQYVI.uasset and /dev/null differ diff --git a/Content/__ExternalActors__/FirstPerson/Maps/FirstPersonMap/D/P3/7RMZUF7GCYTVARB8G5S3OB.uasset b/Content/__ExternalActors__/FirstPerson/Maps/FirstPersonMap/D/P3/7RMZUF7GCYTVARB8G5S3OB.uasset deleted file mode 100644 index 30f5cc3..0000000 Binary files a/Content/__ExternalActors__/FirstPerson/Maps/FirstPersonMap/D/P3/7RMZUF7GCYTVARB8G5S3OB.uasset and /dev/null differ diff --git a/Source/BladeSmith/IronBlock.cpp b/Source/BladeSmith/IronBlock.cpp index d7bd91f..6155ed1 100644 --- a/Source/BladeSmith/IronBlock.cpp +++ b/Source/BladeSmith/IronBlock.cpp @@ -23,9 +23,7 @@ // Sets default values AIronBlock::AIronBlock() : StaticMeshComp(nullptr), PositionRenderTarget0(nullptr), PositionRenderTarget1(nullptr), -DynMaterial(nullptr), -CurrentImpactPoint(), -CurrentImpactNormal() +DynMaterial(nullptr) { // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. PrimaryActorTick.bCanEverTick = true; @@ -57,47 +55,6 @@ void AIronBlock::BeginPlay() InitializePositionTexture(); } - -void AIronBlock::EndPlay(const EEndPlayReason::Type EndPlayReason) -{ - // RenderTargets 会被 UPROPERTY 自动 GC,无需手动释放 RHI 资源 - - Super::EndPlay(EndPlayReason); -} - -// 安全的渲染目标获取 -FTextureRHIRef AIronBlock::GetRenderTargetRHI(UTextureRenderTarget2D* RT) -{ - if (!RT || !RT->GetResource()) return nullptr; - return RT->GetResource()->TextureRHI; -} - -void AIronBlock::GetStaticMeshVertexPositions(TArray& OutPositions) -{ - OutPositions.Empty(); - - if (!StaticMeshComp || !StaticMeshComp->GetStaticMesh()) - return; - - // 获取静态网格资源 - UStaticMesh* StaticMesh = StaticMeshComp->GetStaticMesh(); - // 确保有有效的 RenderData 和 LOD - if (StaticMesh->GetRenderData() && StaticMesh->GetRenderData()->LODResources.Num() > 0) - { - // 获取LOD0的顶点数据 - FStaticMeshLODResources& LOD = StaticMesh->GetRenderData()->LODResources[0]; - const FPositionVertexBuffer& VertexBuffer = LOD.VertexBuffers.PositionVertexBuffer; - - const int32 VertexCount = VertexBuffer.GetNumVertices(); - OutPositions.SetNum(VertexCount); - - for (int32 i = 0; i < VertexCount; i++) - { - OutPositions[i] = VertexBuffer.VertexPosition(i); - } - } -} - /** * 核心修复:创建一个配置好用于变形计算的 RenderTarget */ @@ -119,7 +76,7 @@ UTextureRenderTarget2D* AIronBlock::CreateDeformRT(const FString& RTName, int32 RenderTarget->bAutoGenerateMips = false; RenderTarget->AddressX = TA_Clamp; RenderTarget->AddressY = TA_Clamp; - FLinearColor ClearColor = FLinearColor(0.25f, 0.25f, 0.25f, 1.0f); + FLinearColor ClearColor = FLinearColor(0.5f, 0.5f, 0.5f, 1.0f); RenderTarget->ClearColor = ClearColor; // 立即创建RHI资源 RenderTarget->UpdateResource(); @@ -141,108 +98,18 @@ UTextureRenderTarget2D* AIronBlock::CreateDeformRT(const FString& RTName, int32 void AIronBlock::InitializePositionTexture() { - CalculateLocalBounds(); - - // // 获取顶点位置 (用于计算初始UV->WorldPos) - // TArray VertexPositions; - // GetStaticMeshVertexPositions(VertexPositions); - // 创建位置纹理 const int32 TextureSize = TexSize; // 纹理尺寸 - // TArray InitialData; - // InitialData.SetNum(TextureSize * TextureSize); - // - // // 初始化纹理数据 (将UV映射到本地包围盒的XY平面) - // for (int32 Y = 0; Y < TextureSize; ++Y) - // { - // for (int32 X = 0; X < TextureSize; ++X) - // { - // int32 Index = Y * TextureSize + X; - // FVector2D UV(FVector2D(X, Y) / (TextureSize - 1.0f)); // 使用 255.0 或 (Size-1) - // - // // 将UV坐标转换为本地空间位置 (XY平面) - // FVector LocalPos( - // FMath::Lerp(LocalBounds.Min.X, LocalBounds.Max.X, UV.X), - // FMath::Lerp(LocalBounds.Min.Y, LocalBounds.Max.Y, UV.Y), - // LocalBounds.Min.Z // 假设初始是一个平面 - // ); - // - // InitialData[Index] = FLinearColor(LocalPos.X * 1000, LocalPos.Y * 1000, LocalPos.Z * 1000, 1.0f); - // } - // } // --- 关键修复: 创建两个 RenderTarget --- PositionRenderTarget0 = CreateDeformRT(TEXT("PositionRT0"), TextureSize); PositionRenderTarget1 = CreateDeformRT(TEXT("PositionRT1"), TextureSize); - // --- 将初始数据写入GPU --- - // 我们需要将CPU端的 InitialData 写入到GPU纹理中 - // 最简单的方法是创建一个临时的UTexture2D,用BulkData上传,然后拷贝到RT - - // UTexture2D* TempTexture = UTexture2D::CreateTransient(TextureSize, TextureSize, PF_A32B32G32R32F); // 必须匹配格式 - // if (TempTexture && PositionRenderTarget0 && PositionRenderTarget1) - // { - // // 锁定 Mip 并拷贝数据 - // FTexture2DMipMap& Mip = TempTexture->GetPlatformData()->Mips[0]; - // void* MipData = Mip.BulkData.Lock(LOCK_READ_WRITE); - // FMemory::Memcpy(MipData, InitialData.GetData(), InitialData.Num() * sizeof(FLinearColor)); - // Mip.BulkData.Unlock(); - // TempTexture->UpdateResource(); // 提交到GPU - // - // // 获取RHI资源 - // FTextureRHIRef DestRT0_RHI = GetRenderTargetRHI(PositionRenderTarget0); - // FTextureRHIRef DestRT1_RHI = GetRenderTargetRHI(PositionRenderTarget1); - // FTextureRHIRef SrcTex_RHI = TempTexture->GetResource() ? TempTexture->GetResource()->TextureRHI : nullptr; - // - // if (DestRT0_RHI && DestRT1_RHI && SrcTex_RHI) - // { - // // 在渲染线程上执行拷贝 - // ENQUEUE_RENDER_COMMAND(InitializeDeformRTs)( - // [DestRT0_RHI, DestRT1_RHI, SrcTex_RHI](FRHICommandListImmediate& RHICmdList) - // { - // // 将初始数据拷贝到两个RT - // RHICmdList.CopyTexture(SrcTex_RHI, DestRT0_RHI, {}); - // RHICmdList.CopyTexture(SrcTex_RHI, DestRT1_RHI, {}); - // }); - // - // // 确保拷贝完成 - // FlushRenderingCommands(); - // } - // } - // 设置变形材质 SetupDeformationMaterial(nullptr); UE_LOG(LogTemp, Log, TEXT("Position textures initialized")); } -void AIronBlock::CalculateLocalBounds() -{ - if (!StaticMeshComp) - { - StaticMeshComp = GetComponentByClass(); - } - if (StaticMeshComp && StaticMeshComp->GetStaticMesh()) - { - // 获取本地空间包围盒 - LocalBounds = StaticMeshComp->GetStaticMesh()->GetBoundingBox(); - } - else - { - // 智能默认值 - float Extent = 50.0f; - LocalBounds = FBox( - FVector(-Extent, -Extent, 0), - FVector(Extent, Extent, Extent * 0.2f) - ); - } - - // 确保包围盒有效 - if (LocalBounds.GetVolume() <= 0) - { - LocalBounds = FBox(FVector(-50, -50, 0), FVector(50, 50, 10)); - } -} - void AIronBlock::SetupDeformationMaterial(UTexture2D* OrigTex) { // 创建动态材质实例 @@ -285,7 +152,7 @@ void AIronBlock::OnHammerHit(const FHitResult& HitResult) FVector2D HitUV; UGameplayStatics::FindCollisionUV(HitResult,0,HitUV); FVector ImpactNormal = -HitResult.ImpactNormal; - CurrentDeformationRadius = ImpactAffectRange/TexSize; + float DeformationRadius = ImpactAffectRange/TexSize; UTextureRenderTarget2D* LastTex = nullptr; UTextureRenderTarget2D* CurTex = nullptr; if(CurrentTextureIndex == 0) @@ -302,7 +169,7 @@ void AIronBlock::OnHammerHit(const FHitResult& HitResult) { DynCalMaterial->SetVectorParameterValue(TEXT("ImpactUV"), FLinearColor(HitUV.X,HitUV.Y,0,0)); DynCalMaterial->SetScalarParameterValue(TEXT("ImpactForce"),ImpactForce); - DynCalMaterial->SetScalarParameterValue(TEXT("ImpactRadius"),CurrentDeformationRadius); + DynCalMaterial->SetScalarParameterValue(TEXT("ImpactRadius"), DeformationRadius); DynCalMaterial->SetVectorParameterValue(TEXT("ImpactNormal"),ImpactNormal); DynCalMaterial->SetTextureParameterValue(TEXT("LastPosition"),LastTex); UKismetRenderingLibrary::DrawMaterialToRenderTarget(this->GetWorld(),CurTex,DynCalMaterial); @@ -312,243 +179,6 @@ void AIronBlock::OnHammerHit(const FHitResult& HitResult) DynMaterial->SetTextureParameterValue(TEXT("PositionTexture"),CurTex); CurrentTextureIndex = 1 - CurrentTextureIndex; } - // // 转换到本地空间 - // FVector ImpactPoint = HitResult.ImpactPoint; - // FVector ImpactNormal = HitResult.ImpactNormal; - // FVector LocalImpactPoint = GetTransform().InverseTransformPosition(ImpactPoint); - // FVector LocalImpactNormal = GetTransform().InverseTransformVector(ImpactNormal); - // UE_LOG(LogTemp,Display,TEXT("[AIronBlock::OnHammerHit] ImpactForce:%f,ImpactPoint:%s,ImpactNormal:%s,LocalImpactPoint:%s,LocalImpactNormal:%s") - // ,ImpactForce,*ImpactPoint.ToString(),*ImpactNormal.ToString(),*LocalImpactPoint.ToString(),*LocalImpactNormal.ToString()); - // UpdateComputeShaderParams(LocalImpactPoint, LocalImpactNormal, ImpactForce); - - //ExecuteDeformationCS(); -} - - -void AIronBlock::UpdateComputeShaderParams(FVector LocalImpactPoint, FVector LocalImpactNormal, float _ImpactForce) -{ - // 更新碰撞参数 - CurrentImpactPoint = LocalImpactPoint; - CurrentImpactNormal = LocalImpactNormal.GetSafeNormal(); - CurrentImpactForce = FMath::Clamp(ImpactForce, 0.0f, 5000.0f); - - // 根据冲击力计算动态变形半径 - CurrentDeformationRadius = FMath::Lerp(5.0f, 30.0f, CurrentImpactForce / 2000.0f); - - // 根据材质类型调整塑性系数 (示例) - UMaterialInterface* Material = StaticMeshComp->GetMaterial(0); - if (Material && Material->GetName().Contains("Steel")) - { - CurrentPlasticity = 0.4f; // 钢材塑性较低 - } - else - { - CurrentPlasticity = 0.8f; // 默认高塑性 - } - - // 切换纹理缓冲索引 - CurrentTextureIndex = 1 - CurrentTextureIndex; -} - -void AIronBlock::ExecuteDeformationCS() -{ - // 确保纹理资源有效 - if (!PositionRenderTarget0 || !PositionRenderTarget0->GetResource() || - !PositionRenderTarget1 || !PositionRenderTarget1->GetResource()) - { - UE_LOG(LogTemp, Error, TEXT("Position render targets not initialized!")); - return; - } - - // --- 关键修复: 决定哪个是读取RT,哪个是写入RT --- - UTextureRenderTarget2D* ReadTarget = (CurrentTextureIndex == 0) ? PositionRenderTarget0 : PositionRenderTarget1; - UTextureRenderTarget2D* WriteTarget = (CurrentTextureIndex == 1) ? PositionRenderTarget0 : PositionRenderTarget1; // Flipped - - // --- 关键修复: 在游戏线程只获取 Input RHI Texture 句柄 --- - FTextureRHIRef InputRHI = GetRenderTargetRHI(ReadTarget); - FTextureRHIRef WriteRHI = GetRenderTargetRHI(WriteTarget); // 必须获取写入目标的RHI - - if (!InputRHI.IsValid() || !WriteRHI.IsValid()) - { - UE_LOG(LogTemp, Error, TEXT("Invalid texture RHI resources!")); - return; - } - - // 计算纹理UV坐标 - const int32 _TexSize = ReadTarget->SizeX; - FVector2D ImpactUV( - (CurrentImpactPoint.X - LocalBounds.Min.X) / LocalBounds.GetSize().X, - (CurrentImpactPoint.Y - LocalBounds.Min.Y) / LocalBounds.GetSize().Y - ); - UE_LOG(LogTemp,Display,TEXT("[AIronBlock::ExecuteDeformationCS]LocalBounds:%s") - ,*LocalBounds.ToString()); - - // 假设 LocalBounds 仍然是未缩放的原始包围盒 - // 获得 Actor 的缩放 - FVector ComponentScale = StaticMeshComp->GetComponentScale(); - - // 1. 计算缩放后包围盒的最大延伸 (在 X/Y 平面上) - // 假设您的形变发生在 XY 平面 - float MaxLocalExtentX = LocalBounds.GetExtent().X * ComponentScale.X; - float MaxLocalExtentY = LocalBounds.GetExtent().Y * ComponentScale.Y; - float MaxScaledExtent = FMath::Max(MaxLocalExtentX, MaxLocalExtentY); - - // 2. 使用这个缩放后的最大延伸进行比例计算 - // 这里的 CurrentDeformationRadius 应该是一个世界空间的值。 - const float RadiusRatio = CurrentDeformationRadius / MaxScaledExtent; - // 计算更新区域 (只更新受影响部分) - //const float RadiusRatio = CurrentDeformationRadius / LocalBounds.GetExtent().GetMax(); - FIntRect UpdateRegion; - UpdateRegion.Min.X = FMath::Clamp(FMath::FloorToInt((ImpactUV.X - RadiusRatio) * _TexSize), 0, _TexSize - 1); - UpdateRegion.Min.Y = FMath::Clamp(FMath::FloorToInt((ImpactUV.Y - RadiusRatio) * _TexSize), 0, _TexSize - 1); - UpdateRegion.Max.X = FMath::Clamp(FMath::CeilToInt((ImpactUV.X + RadiusRatio) * _TexSize), 1, _TexSize); - UpdateRegion.Max.Y = FMath::Clamp(FMath::CeilToInt((ImpactUV.Y + RadiusRatio) * _TexSize), 1, _TexSize); - - // 确保 Min < Max - if (UpdateRegion.Min.X >= UpdateRegion.Max.X) UpdateRegion.Max.X = UpdateRegion.Min.X + 1; - if (UpdateRegion.Min.Y >= UpdateRegion.Max.Y) UpdateRegion.Max.Y = UpdateRegion.Min.Y + 1; - - // 临时代码,先更新全部区域 - UpdateRegion.Min.X = 0; - UpdateRegion.Min.Y = 0; - UpdateRegion.Max.X = _TexSize; - UpdateRegion.Max.Y = _TexSize; - - // --- 关键修改:使用 RDG --- - ENQUEUE_RENDER_COMMAND(ExecuteDeformationCS_RDG)( - [ - // 捕获所有需要的参数 - InputRHI, - WriteRHI, - CurrentImpactPoint = this->CurrentImpactPoint, // 拷贝一份 - CurrentImpactNormal = this->CurrentImpactNormal, - CurrentImpactForce = this->CurrentImpactForce, - CurrentDeformationRadius = this->CurrentDeformationRadius, - CurrentPlasticity = this->CurrentPlasticity, - UpdateRegion, // - _TexSize // - ](FRHICommandListImmediate& RHICmdList) - { - // 1. 创建 RDG Builder - FRDGBuilder builder(RHICmdList); - - // 2. 将我们的外部 RT 注册到 RDG 中 - // 注意:我们使用 WriteRHI->GetDesc() 来获取纹理描述 - FRDGTextureRef RDGReadTexture = builder.RegisterExternalTexture( - CreateRenderTarget(InputRHI, TEXT("DeformInputTex")) - ); - FRDGTextureRef RDGWriteTexture = builder.RegisterExternalTexture( - CreateRenderTarget(WriteRHI, TEXT("DeformOutputTex")) - ); - - // 3. 分配着色器参数 - FDeformComputeShader::FParameters* Params = builder.AllocParameters(); - - // 4. 填充 CPU 参数 - Params->ImpactPoint = FVector3f(CurrentImpactPoint); // 注意:从 FVector 转为 FVector3f - Params->ImpactNormal = FVector3f(CurrentImpactNormal); - Params->ImpactForce = CurrentImpactForce; - Params->DeformationRadius = CurrentDeformationRadius; - Params->Plasticity = CurrentPlasticity; - Params->UpdateRegionParam = FIntVector4(UpdateRegion.Min.X, UpdateRegion.Min.Y, UpdateRegion.Max.X, UpdateRegion.Max.Y); - Params->TextureSize = FIntVector(_TexSize, _TexSize, 1); - UE_LOG(LogTemp,Display,TEXT("[AIronBlock::ExecuteDeformationCS]ImpactForce:%f, ImpactPoint:%s,ImpactNormal:%s,DeformationRadius:%f,Plasticity:%f,UpdateRegion:%s") - ,Params->ImpactForce,*Params->ImpactPoint.ToString(),*Params->ImpactNormal.ToString(),Params->DeformationRadius,Params->Plasticity,*Params->UpdateRegionParam.ToString()); - - - // 5. ✨ 魔法发生的地方:RDG 为我们创建 SRV 和 UAV - // 这就是解决你 nullptr 问题的核心 - Params->InputTexture = builder.CreateSRV(RDGReadTexture); - Params->OutputTexture = builder.CreateUAV(RDGWriteTexture); - - // 6. 获取着色器实例 - TShaderMapRef ComputeShader(GetGlobalShaderMap(GMaxRHIFeatureLevel)); - if (!ComputeShader.IsValid()) - { - UE_LOG(LogTemp, Error, TEXT("FDeformComputeShader is not valid!")); - return; - } - - // 7. 计算线程组数量 - // (注意:你的USF需要处理 UpdateRegion,这里我们调度整个区域) - FIntVector NumGroups = FIntVector::DivideAndRoundUp( - FIntVector(UpdateRegion.Width(), UpdateRegion.Height(), 1), - FDeformComputeShader::GetGroupSize() - ); - // 如果你的shader总是处理整个纹理,请使用: - // FIntVector NumGroups = FIntVector::DivideAndRoundUp( - // Params->TextureSize, FDeformComputeShader::GetGroupSize() - // ); - - // 8. 添加 Compute Pass - FComputeShaderUtils::AddPass( - builder, - RDG_EVENT_NAME("ExecuteDeformationCS"), - ComputeShader, - Params, - NumGroups - ); - - // 9. 执行 RDG (这会处理所有屏障和调度) - builder.Execute(); - }); - - // --- 结束 RDG 修改 --- - - // 确保渲染命令完成 (如果你需要立即更新碰撞体) - // FlushRenderingCommands(); - // UpdateCollisionAsync(UpdateRegion, WriteTarget); - - // --- 关键修复: 更新材质参数,使其下一帧读取我们刚刚写入的纹理 --- - if (DynMaterial) - { - DynMaterial->SetTextureParameterValue(TEXT("PositionTexture"), WriteTarget); - DynMaterial->SetVectorParameterValue(TEXT("LocalBoundsMin"), FLinearColor(LocalBounds.Min)); - DynMaterial->SetVectorParameterValue(TEXT("LocalBoundsMax"), FLinearColor(LocalBounds.Max)); - } -} - -// 异步更新物理碰撞体 (示例,未优化) -void AIronBlock::UpdateCollisionAsync(const FIntRect& UpdateRegion, UTextureRenderTarget2D* FromTarget) -{ - // 注意:ReadPixels 是一项非常慢的操作 (GPU->CPU 同步) - // 更好的方法是使用另一个Compute Shader将顶点数据简化并读回到一个小的StructuredBuffer中 - - if (!FromTarget || !FromTarget->GetResource()) - { - return; - } - // 从GPU读取关键区域数据 - TArray SampledData; // 使用 FLinearColor - FReadSurfaceDataFlags Flags; - Flags.SetLinearToGamma(false); - - FRenderTarget* RTResource = FromTarget->GameThread_GetRenderTargetResource(); - if (!RTResource) return; - - RTResource->ReadLinearColorPixels( - SampledData, - Flags, - UpdateRegion // FIntRect - ); - - // 创建临时碰撞体 - TArray CollisionVerts; - for (const FLinearColor& Pixel : SampledData) - { - // 像素数据已经是 FLinearColor (即 FVector) - CollisionVerts.Add(FVector(Pixel.R, Pixel.G, Pixel.B)); - } - - if (CollisionVerts.Num() == 0) return; - - // 更新简单碰撞体 - UBodySetup* BodySetup = StaticMeshComp->GetBodySetup(); - if (BodySetup && BodySetup->AggGeom.ConvexElems.Num() > 0) - { - BodySetup->AggGeom.ConvexElems[0].VertexData = CollisionVerts; - BodySetup->CreatePhysicsMeshes(); // 重新创建物理网格体 - } } // Called every frame diff --git a/Source/BladeSmith/IronBlock.h b/Source/BladeSmith/IronBlock.h index f8430e9..c72ef4e 100644 --- a/Source/BladeSmith/IronBlock.h +++ b/Source/BladeSmith/IronBlock.h @@ -53,7 +53,6 @@ public: protected: // Called when the game starts or when spawned virtual void BeginPlay() override; - virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; virtual void PostInitProperties(); /** 初始化两个渲染目标和它们的初始数据 */ void InitializePositionTexture(); @@ -61,38 +60,10 @@ protected: /** 创建一个配置好用于变形计算的 RenderTarget */ UTextureRenderTarget2D* CreateDeformRT(const FString& RTName, int32 Size); - /** 获取静态网格体的顶点位置 (用于计算初始纹理) */ - void GetStaticMeshVertexPositions(TArray& OutPositions); - /** 设置动态材质实例和参数 */ void SetupDeformationMaterial(UTexture2D* OrigTex); - /** 安全地获取 RenderTarget 的 RHI 资源 */ - FTextureRHIRef GetRenderTargetRHI(UTextureRenderTarget2D* RT); - private: - /** 更新 Compute Shader 所需的参数 */ - void UpdateComputeShaderParams(FVector LocalImpactPoint, FVector LocalImpactNormal, float ImpactForce); - - /** 在渲染线程上执行 Compute Shader */ - void ExecuteDeformationCS(); - - /** (可选) 异步更新物理碰撞体 */ - void UpdateCollisionAsync(const FIntRect& UpdateRegion, UTextureRenderTarget2D* FromTarget); - - /** 计算网格体的本地包围盒 */ - void CalculateLocalBounds(); - - // 网格体的本地包围盒 - FBox LocalBounds; - - // --- 碰撞参数 --- - FVector CurrentImpactPoint; - FVector CurrentImpactNormal; - float CurrentImpactForce = 0.0f; - float CurrentDeformationRadius = 10.0f; - float CurrentPlasticity = 0.7f; - /** * 双缓冲纹理索引 * 0: 读 RT0, 写 RT1 * 1: 读 RT1, 写 RT0