调试计算形变的shader,执行了,但是初始贴图数据就不对。
This commit is contained in:
Binary file not shown.
@@ -53,6 +53,7 @@ void MainCompute( // 注意: 建议使用 MainCompute,如果 C++ 注册的是
|
|||||||
{
|
{
|
||||||
// 虽然我们调度时已经只调度了需要的区域,但为了安全起见,保留检查。
|
// 虽然我们调度时已经只调度了需要的区域,但为了安全起见,保留检查。
|
||||||
// 理论上,如果 C++ 端调度正确,这个检查应该很少触发。
|
// 理论上,如果 C++ 端调度正确,这个检查应该很少触发。
|
||||||
|
OutputTexture[PixelCoord] = float4(100,100,100,100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,90 +0,0 @@
|
|||||||
// DeformationCS.usf
|
|
||||||
|
|
||||||
#include "/Engine/Public/Platform.ush"
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// 1. 输入输出定义
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// 必须与 C++ 的 SHADER_PARAMETER_RDG_TEXTURE_SRV 匹配
|
|
||||||
Texture2D<float4> InputTexture;
|
|
||||||
// 必须与 C++ 的 SHADER_PARAMETER_RDG_TEXTURE_UAV 匹配
|
|
||||||
RWTexture2D<float4> OutputTexture;
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// 2. 参数缓冲区 (必须与 C++ FParameters 结构体严格匹配)
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
cbuffer Parameters
|
|
||||||
{
|
|
||||||
float3 ImpactPoint;
|
|
||||||
float ImpactForce;
|
|
||||||
float3 ImpactNormal;
|
|
||||||
float DeformationRadius;
|
|
||||||
float Plasticity;
|
|
||||||
int3 TextureSize;
|
|
||||||
|
|
||||||
// 修正后的参数:对应 C++ 的 FIntVector4 UpdateRegionParam
|
|
||||||
// 分量顺序: (Min.X, Min.Y, Max.X, Max.Y)
|
|
||||||
int4 UpdateRegionParam;
|
|
||||||
};
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// 3. 线程组大小和入口点
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
#define THREADGROUP_SIZE_X 8
|
|
||||||
#define THREADGROUP_SIZE_Y 8
|
|
||||||
[numthreads(THREADGROUP_SIZE_X, THREADGROUP_SIZE_Y, 1)]
|
|
||||||
void MainCompute( // 注意: 建议使用 MainCompute,如果 C++ 注册的是 MainCompute
|
|
||||||
uint3 GroupID : SV_GroupID,
|
|
||||||
uint3 GroupThreadID : SV_GroupThreadID,
|
|
||||||
uint3 DispatchThreadID : SV_DispatchThreadID // 全局线程 ID
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// 4. 坐标计算与边界检查
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// DispatchThreadID 从 0 开始,代表在调度区域内的偏移量。
|
|
||||||
// 我们将其加上 UpdateRegionParam.xy (Min.X, Min.Y) 得到全局像素坐标。
|
|
||||||
int2 PixelCoord = DispatchThreadID.xy + int2(UpdateRegionParam.x, UpdateRegionParam.y);
|
|
||||||
|
|
||||||
// 边界检查:检查是否超出 UpdateRegionParam.zw (Max.X, Max.Y)
|
|
||||||
if (PixelCoord.x < UpdateRegionParam.x || PixelCoord.x >= UpdateRegionParam.z ||
|
|
||||||
PixelCoord.y < UpdateRegionParam.y || PixelCoord.y >= UpdateRegionParam.w)
|
|
||||||
{
|
|
||||||
// 虽然我们调度时已经只调度了需要的区域,但为了安全起见,保留检查。
|
|
||||||
// 理论上,如果 C++ 端调度正确,这个检查应该很少触发。
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
// 5. 变形计算逻辑 (与之前相同)
|
|
||||||
// -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// 从输入纹理读取位置
|
|
||||||
// Load 需要 int3,第三个分量 (MipLevel) 设为 0
|
|
||||||
float4 OriginalPos = InputTexture.Load(int3(PixelCoord, 0));
|
|
||||||
|
|
||||||
// 计算到碰撞点的距离
|
|
||||||
float dist = distance(OriginalPos.xyz, ImpactPoint);
|
|
||||||
|
|
||||||
// 在变形半径内处理
|
|
||||||
if (dist < DeformationRadius)
|
|
||||||
{
|
|
||||||
// 计算变形衰减 (高斯衰减)
|
|
||||||
float falloff = exp(-(dist * dist) / (2.0 * DeformationRadius * DeformationRadius));
|
|
||||||
|
|
||||||
// 计算变形量 (考虑法线方向)
|
|
||||||
float3 deformation = ImpactNormal * ImpactForce * falloff * 0.01;
|
|
||||||
|
|
||||||
// 应用塑性变形
|
|
||||||
float3 newPos = OriginalPos.xyz + deformation * Plasticity;
|
|
||||||
|
|
||||||
// 写入新位置
|
|
||||||
OutputTexture[PixelCoord] = float4(newPos, OriginalPos.w);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// 保持原位置
|
|
||||||
OutputTexture[PixelCoord] = OriginalPos;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -153,7 +153,7 @@ void AIronBlock::InitializePositionTexture()
|
|||||||
LocalBounds.Min.Z // 假设初始是一个平面
|
LocalBounds.Min.Z // 假设初始是一个平面
|
||||||
);
|
);
|
||||||
|
|
||||||
InitialData[Index] = FLinearColor(LocalPos.X, LocalPos.Y, LocalPos.Z, 1.0f);
|
InitialData[Index] = FLinearColor(LocalPos.X * 1000, LocalPos.Y * 1000, LocalPos.Z * 1000, 1.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ void AIronBlock::InitializePositionTexture()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 设置变形材质
|
// 设置变形材质
|
||||||
SetupDeformationMaterial();
|
SetupDeformationMaterial(TempTexture);
|
||||||
UE_LOG(LogTemp, Log, TEXT("Position textures initialized"));
|
UE_LOG(LogTemp, Log, TEXT("Position textures initialized"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,7 +229,7 @@ void AIronBlock::CalculateLocalBounds()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIronBlock::SetupDeformationMaterial()
|
void AIronBlock::SetupDeformationMaterial(UTexture2D* OrigTex)
|
||||||
{
|
{
|
||||||
// 创建动态材质实例
|
// 创建动态材质实例
|
||||||
if (StaticMeshComp)
|
if (StaticMeshComp)
|
||||||
@@ -250,7 +250,8 @@ void AIronBlock::SetupDeformationMaterial()
|
|||||||
if (DynMaterial)
|
if (DynMaterial)
|
||||||
{
|
{
|
||||||
// 初始时读取 RT0
|
// 初始时读取 RT0
|
||||||
DynMaterial->SetTextureParameterValue(TEXT("PositionTexture"), PositionRenderTarget0);
|
DynMaterial->SetTextureParameterValue(TEXT("PositionTexture"), OrigTex);
|
||||||
|
//DynMaterial->SetTextureParameterValue(TEXT("PositionTexture"), PositionRenderTarget0);
|
||||||
DynMaterial->SetVectorParameterValue(TEXT("LocalBoundsMin"), FLinearColor(LocalBounds.Min));
|
DynMaterial->SetVectorParameterValue(TEXT("LocalBoundsMin"), FLinearColor(LocalBounds.Min));
|
||||||
DynMaterial->SetVectorParameterValue(TEXT("LocalBoundsMax"), FLinearColor(LocalBounds.Max));
|
DynMaterial->SetVectorParameterValue(TEXT("LocalBoundsMax"), FLinearColor(LocalBounds.Max));
|
||||||
DynMaterial->SetScalarParameterValue(TEXT("DeformationStrength"), 1.0f);
|
DynMaterial->SetScalarParameterValue(TEXT("DeformationStrength"), 1.0f);
|
||||||
@@ -275,13 +276,14 @@ void AIronBlock::OnHammerHit(const FHitResult& HitResult)
|
|||||||
|
|
||||||
// 默认冲击力
|
// 默认冲击力
|
||||||
if (ImpactForce < 10.0f) ImpactForce = 500.0f;
|
if (ImpactForce < 10.0f) ImpactForce = 500.0f;
|
||||||
|
|
||||||
// 转换到本地空间
|
// 转换到本地空间
|
||||||
FVector ImpactPoint = HitResult.ImpactPoint;
|
FVector ImpactPoint = HitResult.ImpactPoint;
|
||||||
FVector ImpactNormal = HitResult.ImpactNormal;
|
FVector ImpactNormal = HitResult.ImpactNormal;
|
||||||
FVector LocalImpactPoint = GetTransform().InverseTransformPosition(ImpactPoint);
|
FVector LocalImpactPoint = GetTransform().InverseTransformPosition(ImpactPoint);
|
||||||
FVector LocalImpactNormal = GetTransform().InverseTransformVector(ImpactNormal);
|
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);
|
UpdateComputeShaderParams(LocalImpactPoint, LocalImpactNormal, ImpactForce);
|
||||||
|
|
||||||
ExecuteDeformationCS();
|
ExecuteDeformationCS();
|
||||||
@@ -311,6 +313,8 @@ void AIronBlock::UpdateComputeShaderParams(FVector LocalImpactPoint, FVector Loc
|
|||||||
|
|
||||||
// 切换纹理缓冲索引
|
// 切换纹理缓冲索引
|
||||||
CurrentTextureIndex = 1 - CurrentTextureIndex;
|
CurrentTextureIndex = 1 - CurrentTextureIndex;
|
||||||
|
UE_LOG(LogTemp,Display,TEXT("[AIronBlock::OnHammerHitUpdateComputeShaderParams]CurrentImpactForce:%f, CurrentImpactPoint:%s,CurrentImpactNormal:%s,CurrentDeformationRadius:%f,CurrentPlasticity:%f")
|
||||||
|
,CurrentImpactForce,*CurrentImpactPoint.ToString(),*CurrentImpactNormal.ToString(),CurrentDeformationRadius,CurrentPlasticity);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AIronBlock::ExecuteDeformationCS()
|
void AIronBlock::ExecuteDeformationCS()
|
||||||
@@ -343,9 +347,24 @@ void AIronBlock::ExecuteDeformationCS()
|
|||||||
(CurrentImpactPoint.X - LocalBounds.Min.X) / LocalBounds.GetSize().X,
|
(CurrentImpactPoint.X - LocalBounds.Min.X) / LocalBounds.GetSize().X,
|
||||||
(CurrentImpactPoint.Y - LocalBounds.Min.Y) / LocalBounds.GetSize().Y
|
(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();
|
//const float RadiusRatio = CurrentDeformationRadius / LocalBounds.GetExtent().GetMax();
|
||||||
FIntRect UpdateRegion;
|
FIntRect UpdateRegion;
|
||||||
UpdateRegion.Min.X = FMath::Clamp(FMath::FloorToInt((ImpactUV.X - RadiusRatio) * TexSize), 0, TexSize - 1);
|
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.Min.Y = FMath::Clamp(FMath::FloorToInt((ImpactUV.Y - RadiusRatio) * TexSize), 0, TexSize - 1);
|
||||||
@@ -356,6 +375,12 @@ void AIronBlock::ExecuteDeformationCS()
|
|||||||
if (UpdateRegion.Min.X >= UpdateRegion.Max.X) UpdateRegion.Max.X = UpdateRegion.Min.X + 1;
|
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;
|
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 ---
|
// --- 关键修改:使用 RDG ---
|
||||||
ENQUEUE_RENDER_COMMAND(ExecuteDeformationCS_RDG)(
|
ENQUEUE_RENDER_COMMAND(ExecuteDeformationCS_RDG)(
|
||||||
[
|
[
|
||||||
@@ -394,6 +419,9 @@ void AIronBlock::ExecuteDeformationCS()
|
|||||||
Params->Plasticity = CurrentPlasticity;
|
Params->Plasticity = CurrentPlasticity;
|
||||||
Params->UpdateRegionParam = FIntVector4(UpdateRegion.Min.X, UpdateRegion.Min.Y, UpdateRegion.Max.X, UpdateRegion.Max.Y);
|
Params->UpdateRegionParam = FIntVector4(UpdateRegion.Min.X, UpdateRegion.Min.Y, UpdateRegion.Max.X, UpdateRegion.Max.Y);
|
||||||
Params->TextureSize = FIntVector(TexSize, TexSize, 1);
|
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
|
// 5. ✨ 魔法发生的地方:RDG 为我们创建 SRV 和 UAV
|
||||||
// 这就是解决你 nullptr 问题的核心
|
// 这就是解决你 nullptr 问题的核心
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ protected:
|
|||||||
void GetStaticMeshVertexPositions(TArray<FVector3f>& OutPositions);
|
void GetStaticMeshVertexPositions(TArray<FVector3f>& OutPositions);
|
||||||
|
|
||||||
/** 设置动态材质实例和参数 */
|
/** 设置动态材质实例和参数 */
|
||||||
void SetupDeformationMaterial();
|
void SetupDeformationMaterial(UTexture2D* OrigTex);
|
||||||
|
|
||||||
/** 安全地获取 RenderTarget 的 RHI 资源 */
|
/** 安全地获取 RenderTarget 的 RHI 资源 */
|
||||||
FTextureRHIRef GetRenderTargetRHI(UTextureRenderTarget2D* RT);
|
FTextureRHIRef GetRenderTargetRHI(UTextureRenderTarget2D* RT);
|
||||||
|
|||||||
Reference in New Issue
Block a user