90 lines
3.5 KiB
Plaintext
90 lines
3.5 KiB
Plaintext
// 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;
|
|
}
|
|
} |