调试shader
This commit is contained in:
@@ -2,4 +2,6 @@
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AAdpcmAudioDecoder_002EBuild_002Ecs_002Fl_003AD_0021_003FProgram_0020Files_003FEpic_0020Games_003FUE_005F5_002E5_003FEngine_003FSource_003FRuntime_003FAdpcmAudioDecoder_003FModule_003FAdpcmAudioDecoder_002EBuild_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AGajuzad_002Easm_002Fl_003AC_0021_003FUsers_003Fstarm_003FAppData_003FLocal_003FTemp_003FSandboxFiles_003FXexaveh_003FGajuzad_002Easm/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AJicekul_002Easm_002Fl_003AC_0021_003FUsers_003Fstarm_003FAppData_003FLocal_003FTemp_003FSandboxFiles_003FLeqybub_003FJicekul_002Easm/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ATemuhyh_002Easm_002Fl_003AC_0021_003FUsers_003Fstarm_003FAppData_003FLocal_003FTemp_003FSandboxFiles_003FCyfibag_003FTemuhyh_002Easm/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AWorujoq_002Easm_002Fl_003AC_0021_003FUsers_003Fstarm_003FAppData_003FLocal_003FTemp_003FSandboxFiles_003FJakoqel_003FWorujoq_002Easm/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AZilegoz_002Easm_002Fl_003AC_0021_003FUsers_003Fstarm_003FAppData_003FLocal_003FTemp_003FSandboxFiles_003FZucifip_003FZilegoz_002Easm/@EntryIndexedValue">ForceIncluded</s:String></wpf:ResourceDictionary>
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,90 @@
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
// DeformationCS.usf
|
||||
#include "/Engine/Public/Platform.ush"
|
||||
// 输入输出定义
|
||||
Texture2D<float4> InputTexture;
|
||||
RWTexture2D<float4> OutputTexture;
|
||||
// 参数缓冲区
|
||||
cbuffer Parameters
|
||||
{
|
||||
float3 ImpactPoint;
|
||||
float ImpactForce;
|
||||
float3 ImpactNormal;
|
||||
float DeformationRadius;
|
||||
float Plasticity;
|
||||
int3 TextureSize;
|
||||
int3 UpdateRegionMin;
|
||||
int3 UpdateRegionSize;
|
||||
};
|
||||
// 线程组大小
|
||||
#define THREADGROUP_SIZE_X 8
|
||||
#define THREADGROUP_SIZE_Y 8
|
||||
[numthreads(THREADGROUP_SIZE_X, THREADGROUP_SIZE_Y, 1)]
|
||||
void MainCS(
|
||||
uint3 GroupID : SV_GroupID,
|
||||
uint3 GroupThreadID : SV_GroupThreadID,
|
||||
uint3 DispatchThreadID : SV_DispatchThreadID
|
||||
)
|
||||
{
|
||||
// 计算全局像素坐标
|
||||
int2 PixelCoord = DispatchThreadID.xy + int2(UpdateRegionMin.xy);
|
||||
|
||||
// 检查是否在有效区域内
|
||||
if (PixelCoord.x >= UpdateRegionMin.x + UpdateRegionSize.x ||
|
||||
PixelCoord.y >= UpdateRegionMin.y + UpdateRegionSize.y)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 从输入纹理读取位置
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,8 @@ public class BladeSmith : ModuleRules
|
||||
{
|
||||
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
// 如果你的模块类型是 Runtime 或 Gameplay 相关的,则添加这行:
|
||||
// bFasterWithoutUnity = false; // 确保非 Unity 构建也能正确加载
|
||||
PublicDependencyModuleNames.AddRange(new string[] {
|
||||
"Core",
|
||||
"CoreUObject",
|
||||
@@ -16,11 +18,13 @@ public class BladeSmith : ModuleRules
|
||||
"EnhancedInput",
|
||||
"RenderCore",
|
||||
"RHI",
|
||||
"RenderCore",
|
||||
"Renderer",
|
||||
"PhysicsCore",
|
||||
"AudioExtensions",
|
||||
"AudioMixer",
|
||||
"AudioPlatformConfiguration"
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,41 +12,7 @@
|
||||
FThreadSafeDeformationParams GDeformationParams;
|
||||
|
||||
// 实现Compute Shader
|
||||
IMPLEMENT_GLOBAL_SHADER(FDeformationCS, "/Shaders/Private/DeformationCS.usf", "MainCS", SF_Compute);
|
||||
|
||||
// 分派函数实现
|
||||
void FDeformationCS::Dispatch(
|
||||
FRHICommandListImmediate& RHICmdList,
|
||||
const FDeformationCSDispatchParams& Params)
|
||||
{
|
||||
// 创建参数结构
|
||||
FParameters Parameters;
|
||||
Parameters.ImpactPoint = FVector3f(Params.ImpactPoint);
|
||||
Parameters.ImpactNormal = FVector3f(Params.ImpactNormal);
|
||||
Parameters.ImpactForce = Params.ImpactForce;
|
||||
Parameters.DeformationRadius = Params.DeformationRadius;
|
||||
Parameters.Plasticity = Params.Plasticity;
|
||||
Parameters.InputTexture = Params.InputTexture;
|
||||
Parameters.OutputTexture = Params.OutputTexture;
|
||||
Parameters.TextureSize = Params.TextureSize;
|
||||
Parameters.UpdateRegionMin = FIntVector(Params.UpdateRegion.Min.X, Params.UpdateRegion.Min.Y, 0);
|
||||
Parameters.UpdateRegionSize = FIntVector(Params.UpdateRegion.Width(), Params.UpdateRegion.Height(), 1);
|
||||
|
||||
// 计算线程组数量
|
||||
const int32 ThreadGroupSizeX = 8;
|
||||
const int32 ThreadGroupSizeY = 8;
|
||||
const int32 ThreadGroupSizeZ = 1;
|
||||
|
||||
const int32 GroupCountX = FMath::DivideAndRoundUp(Params.UpdateRegion.Width(), ThreadGroupSizeX);
|
||||
const int32 GroupCountY = FMath::DivideAndRoundUp(Params.UpdateRegion.Height(), ThreadGroupSizeY);
|
||||
const int32 GroupCountZ = 1;
|
||||
|
||||
// 分派Compute Shader
|
||||
TShaderMapRef<FDeformationCS> ComputeShader(GetGlobalShaderMap(GMaxRHIFeatureLevel));
|
||||
SetComputePipelineState(RHICmdList, ComputeShader.GetComputeShader());
|
||||
SetShaderParameters(RHICmdList, ComputeShader, ComputeShader.GetComputeShader(), Parameters);
|
||||
RHICmdList.DispatchComputeShader(GroupCountX, GroupCountY, GroupCountZ);
|
||||
}
|
||||
IMPLEMENT_GLOBAL_SHADER(FDeformComputeShader, "/Engine/Private/MiceCola/DeformationCS.usf", "MainCompute", SF_Compute);
|
||||
|
||||
// 线程安全参数管理
|
||||
void FThreadSafeDeformationParams::AddParams(const FDeformationCSDispatchParams& NewParams)
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
#pragma once
|
||||
#include "GlobalShader.h"
|
||||
// DeformComputeShader.h
|
||||
|
||||
// DeformationCS.h
|
||||
#pragma once
|
||||
#include "CoreMinimal.h"
|
||||
#include "RHI.h"
|
||||
#include "RHIResources.h"
|
||||
#include "GlobalShader.h"
|
||||
#include "ShaderParameterStruct.h"
|
||||
#include "RenderGraphUtils.h" // 必须包含
|
||||
|
||||
// Compute Shader参数结构体
|
||||
struct FDeformationCSDispatchParams
|
||||
@@ -52,32 +47,51 @@ extern FThreadSafeDeformationParams GDeformationParams;
|
||||
|
||||
// DeformationCS.h (续)
|
||||
// Compute Shader类
|
||||
class FDeformationCS : public FGlobalShader
|
||||
class FDeformComputeShader : public FGlobalShader
|
||||
{
|
||||
DECLARE_GLOBAL_SHADER(FDeformationCS);
|
||||
SHADER_USE_PARAMETER_STRUCT(FDeformationCS, FGlobalShader);
|
||||
DECLARE_GLOBAL_SHADER(FDeformComputeShader);
|
||||
SHADER_USE_PARAMETER_STRUCT(FDeformComputeShader, FGlobalShader);
|
||||
|
||||
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
||||
// 碰撞参数
|
||||
SHADER_PARAMETER(FVector3f, ImpactPoint)
|
||||
SHADER_PARAMETER(FVector3f, ImpactNormal)
|
||||
SHADER_PARAMETER(float, ImpactForce)
|
||||
SHADER_PARAMETER(FVector3f, ImpactNormal)
|
||||
SHADER_PARAMETER(float, DeformationRadius)
|
||||
SHADER_PARAMETER(float, Plasticity)
|
||||
|
||||
// 纹理参数
|
||||
SHADER_PARAMETER_TEXTURE(Texture2D, InputTexture)
|
||||
SHADER_PARAMETER_UAV(RWTexture2D<float4>, OutputTexture)
|
||||
SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, InputTexture)
|
||||
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutputTexture)
|
||||
|
||||
// 更新区域
|
||||
SHADER_PARAMETER(FIntVector, TextureSize)
|
||||
SHADER_PARAMETER(FIntVector, UpdateRegionMin)
|
||||
SHADER_PARAMETER(FIntVector, UpdateRegionSize)
|
||||
SHADER_PARAMETER(FIntVector4, UpdateRegionParam)
|
||||
END_SHADER_PARAMETER_STRUCT()
|
||||
|
||||
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
|
||||
{
|
||||
return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
|
||||
return GetMaxSupportedFeatureLevel(Parameters.Platform) >= ERHIFeatureLevel::SM5;
|
||||
}
|
||||
|
||||
// 2. ✨ 修复 Precache 错误的关键:实现 ShouldPrecachePermutation
|
||||
// 我们告诉引擎:在开发模式下,请始终预缓存这个着色器。
|
||||
static EShaderPermutationPrecacheRequest ShouldPrecachePermutation(const FGlobalShaderPermutationParameters& Parameters)
|
||||
{
|
||||
// 如果你的着色器没有使用任何模板或标志,只需返回 E_DEVELOPMENT 或 E_ALL。
|
||||
return EShaderPermutationPrecacheRequest::Precached;
|
||||
}
|
||||
|
||||
|
||||
static bool ShouldCache(EShaderPlatform Platform)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// (假设你的 .usf 文件中线程组大小为 8x8x1)
|
||||
static FIntVector GetGroupSize()
|
||||
{
|
||||
return FIntVector(8, 8, 1);
|
||||
}
|
||||
|
||||
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
|
||||
@@ -87,8 +101,4 @@ class FDeformationCS : public FGlobalShader
|
||||
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_Y"), 8);
|
||||
}
|
||||
|
||||
// 分派函数
|
||||
static void Dispatch(
|
||||
FRHICommandListImmediate& RHICmdList,
|
||||
const FDeformationCSDispatchParams& Params);
|
||||
};
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
|
||||
#include "IronBlock.h"
|
||||
|
||||
// 确保包含了 RDG 所需的头文件
|
||||
#include "RenderGraphBuilder.h"
|
||||
#include "RenderGraphUtils.h" // FComputeShaderUtils::AddPass
|
||||
#include "FDeformComputeShader.h" // 确保这个头文件存在且包含了 FDeformationCSDispatchParams
|
||||
#include "StaticMeshResources.h"
|
||||
#include "TextureResource.h"
|
||||
@@ -12,7 +14,6 @@
|
||||
#include "Materials/MaterialInstanceDynamic.h"
|
||||
#include "PhysicsEngine/BodySetup.h"
|
||||
#include "RHICommandList.h"
|
||||
#include "RenderGraphBuilder.h" // 包含 FRDGBuilder
|
||||
#include "Engine/Texture.h"
|
||||
#include "GenericPlatform/GenericPlatformProcess.h"
|
||||
|
||||
@@ -328,11 +329,11 @@ void AIronBlock::ExecuteDeformationCS()
|
||||
|
||||
// --- 关键修复: 在游戏线程只获取 Input RHI Texture 句柄 ---
|
||||
FTextureRHIRef InputRHI = GetRenderTargetRHI(ReadTarget);
|
||||
FTextureRHIRef WriteRHI = GetRenderTargetRHI(WriteTarget); // 必须获取写入目标的RHI
|
||||
|
||||
// 检查 Input RHI 和 WriteTarget UObject 是否有效
|
||||
if (!InputRHI.IsValid() || !WriteTarget)
|
||||
if (!InputRHI.IsValid() || !WriteRHI.IsValid())
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("Invalid texture RHI resources or WriteTarget UObject!"));
|
||||
UE_LOG(LogTemp, Error, TEXT("Invalid texture RHI resources!"));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -355,68 +356,87 @@ void AIronBlock::ExecuteDeformationCS()
|
||||
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;
|
||||
|
||||
// 准备参数
|
||||
FDeformationCSDispatchParams Params;
|
||||
Params.ImpactPoint = CurrentImpactPoint; // 确保类型匹配 (FVector -> FVector3f)
|
||||
Params.ImpactNormal = CurrentImpactNormal;
|
||||
Params.ImpactForce = CurrentImpactForce;
|
||||
Params.DeformationRadius = CurrentDeformationRadius;
|
||||
Params.Plasticity = CurrentPlasticity;
|
||||
Params.InputTexture = InputRHI;
|
||||
//Params.OutputTexture = OutputUAV; // **直接使用RT的UAV**
|
||||
Params.UpdateRegion = UpdateRegion;
|
||||
Params.TextureSize = FIntVector(TexSize, TexSize, 1);
|
||||
|
||||
// 在渲染线程中执行Compute Shader
|
||||
ENQUEUE_RENDER_COMMAND(ExecuteDeformationCS)(
|
||||
[Params, WriteTarget](FRHICommandListImmediate& RHICmdList)
|
||||
// --- 关键修改:使用 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);
|
||||
|
||||
// 1. 从 UObject 获取 FTextureResource
|
||||
FTextureResource* RTResource = WriteTarget->GetResource();
|
||||
if (!RTResource)
|
||||
// 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<FDeformComputeShader::FParameters>();
|
||||
|
||||
// 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);
|
||||
|
||||
// 5. ✨ 魔法发生的地方:RDG 为我们创建 SRV 和 UAV
|
||||
// 这就是解决你 nullptr 问题的核心
|
||||
Params->InputTexture = builder.CreateSRV(RDGReadTexture);
|
||||
Params->OutputTexture = builder.CreateUAV(RDGWriteTexture);
|
||||
|
||||
// 6. 获取着色器实例
|
||||
TShaderMapRef<FDeformComputeShader> ComputeShader(GetGlobalShaderMap(GMaxRHIFeatureLevel));
|
||||
if (!ComputeShader.IsValid())
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("Failed to get WriteTarget resource on render thread!"));
|
||||
UE_LOG(LogTemp, Error, TEXT("FDeformComputeShader is not valid!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 转换为 FTextureRenderTargetResource
|
||||
FTextureRenderTargetResource* WriteRTResource = static_cast<FTextureRenderTargetResource*>(RTResource);
|
||||
if (!WriteRTResource)
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("Failed to cast to FTextureRenderTargetResource on render thread!"));
|
||||
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()
|
||||
// );
|
||||
|
||||
// 3. ✨ 在渲染线程上调用 GetRenderTargetUAV()
|
||||
FUnorderedAccessViewRHIRef OutputUAV = WriteRTResource->GetRenderTargetUAV();
|
||||
// 8. 添加 Compute Pass
|
||||
FComputeShaderUtils::AddPass(
|
||||
builder,
|
||||
RDG_EVENT_NAME("ExecuteDeformationCS"),
|
||||
ComputeShader,
|
||||
Params,
|
||||
NumGroups
|
||||
);
|
||||
|
||||
// 4. 检查是否成功
|
||||
if (!OutputUAV.IsValid())
|
||||
{
|
||||
// 如果在这里仍然失败,说明 bCanCreateUAV=true 没有生效,
|
||||
// 或者 RHI 后端没有为这个 RT 创建 UAV。
|
||||
UE_LOG(LogTemp, Error, TEXT("GetRenderTargetUAV() returned null ON RENDER THREAD!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 5. 填充参数并调度
|
||||
FDeformationCSDispatchParams RenderParams = Params;
|
||||
RenderParams.OutputTexture = OutputUAV;
|
||||
|
||||
FDeformationCS::Dispatch(RHICmdList, RenderParams);
|
||||
|
||||
// 6. (重要) 添加一个UAV屏障
|
||||
// 告诉GPU,Compute Shader对UAV的写入操作已完成,
|
||||
// 在下一帧中,图形管线(材质)可以安全地将其作为 SRV (TextureSample) 读取。
|
||||
RHICmdList.Transition(FRHITransitionInfo(OutputUAV, ERHIAccess::UAVCompute, ERHIAccess::SRVGraphics));
|
||||
// 9. 执行 RDG (这会处理所有屏障和调度)
|
||||
builder.Execute();
|
||||
});
|
||||
|
||||
// 等待渲染命令完成,以便在CPU上读取 (如果需要立即更新碰撞体)
|
||||
// 注意:这是一个同步点,会影响性能。
|
||||
// --- 结束 RDG 修改 ---
|
||||
|
||||
// 确保渲染命令完成 (如果你需要立即更新碰撞体)
|
||||
// FlushRenderingCommands();
|
||||
// UpdateCollisionAsync(UpdateRegion, WriteTarget); // 异步更新碰撞体
|
||||
// UpdateCollisionAsync(UpdateRegion, WriteTarget);
|
||||
|
||||
// --- 关键修复: 更新材质参数,使其下一帧读取我们刚刚写入的纹理 ---
|
||||
if (DynMaterial)
|
||||
|
||||
Reference in New Issue
Block a user