调试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_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_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_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>
|
<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;
|
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||||
|
|
||||||
|
// 如果你的模块类型是 Runtime 或 Gameplay 相关的,则添加这行:
|
||||||
|
// bFasterWithoutUnity = false; // 确保非 Unity 构建也能正确加载
|
||||||
PublicDependencyModuleNames.AddRange(new string[] {
|
PublicDependencyModuleNames.AddRange(new string[] {
|
||||||
"Core",
|
"Core",
|
||||||
"CoreUObject",
|
"CoreUObject",
|
||||||
@@ -16,11 +18,13 @@ public class BladeSmith : ModuleRules
|
|||||||
"EnhancedInput",
|
"EnhancedInput",
|
||||||
"RenderCore",
|
"RenderCore",
|
||||||
"RHI",
|
"RHI",
|
||||||
|
"RenderCore",
|
||||||
"Renderer",
|
"Renderer",
|
||||||
"PhysicsCore",
|
"PhysicsCore",
|
||||||
"AudioExtensions",
|
"AudioExtensions",
|
||||||
"AudioMixer",
|
"AudioMixer",
|
||||||
"AudioPlatformConfiguration"
|
"AudioPlatformConfiguration"
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,41 +12,7 @@
|
|||||||
FThreadSafeDeformationParams GDeformationParams;
|
FThreadSafeDeformationParams GDeformationParams;
|
||||||
|
|
||||||
// 实现Compute Shader
|
// 实现Compute Shader
|
||||||
IMPLEMENT_GLOBAL_SHADER(FDeformationCS, "/Shaders/Private/DeformationCS.usf", "MainCS", SF_Compute);
|
IMPLEMENT_GLOBAL_SHADER(FDeformComputeShader, "/Engine/Private/MiceCola/DeformationCS.usf", "MainCompute", 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 线程安全参数管理
|
// 线程安全参数管理
|
||||||
void FThreadSafeDeformationParams::AddParams(const FDeformationCSDispatchParams& NewParams)
|
void FThreadSafeDeformationParams::AddParams(const FDeformationCSDispatchParams& NewParams)
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "GlobalShader.h"
|
|
||||||
// DeformComputeShader.h
|
|
||||||
|
|
||||||
// DeformationCS.h
|
|
||||||
#pragma once
|
|
||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "RHI.h"
|
#include "GlobalShader.h"
|
||||||
#include "RHIResources.h"
|
|
||||||
#include "ShaderParameterStruct.h"
|
#include "ShaderParameterStruct.h"
|
||||||
|
#include "RenderGraphUtils.h" // 必须包含
|
||||||
|
|
||||||
// Compute Shader参数结构体
|
// Compute Shader参数结构体
|
||||||
struct FDeformationCSDispatchParams
|
struct FDeformationCSDispatchParams
|
||||||
@@ -52,43 +47,58 @@ extern FThreadSafeDeformationParams GDeformationParams;
|
|||||||
|
|
||||||
// DeformationCS.h (续)
|
// DeformationCS.h (续)
|
||||||
// Compute Shader类
|
// Compute Shader类
|
||||||
class FDeformationCS : public FGlobalShader
|
class FDeformComputeShader : public FGlobalShader
|
||||||
{
|
{
|
||||||
DECLARE_GLOBAL_SHADER(FDeformationCS);
|
DECLARE_GLOBAL_SHADER(FDeformComputeShader);
|
||||||
SHADER_USE_PARAMETER_STRUCT(FDeformationCS, FGlobalShader);
|
SHADER_USE_PARAMETER_STRUCT(FDeformComputeShader, FGlobalShader);
|
||||||
|
|
||||||
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
|
||||||
// 碰撞参数
|
// 碰撞参数
|
||||||
SHADER_PARAMETER(FVector3f, ImpactPoint)
|
SHADER_PARAMETER(FVector3f, ImpactPoint)
|
||||||
SHADER_PARAMETER(FVector3f, ImpactNormal)
|
|
||||||
SHADER_PARAMETER(float, ImpactForce)
|
SHADER_PARAMETER(float, ImpactForce)
|
||||||
|
SHADER_PARAMETER(FVector3f, ImpactNormal)
|
||||||
SHADER_PARAMETER(float, DeformationRadius)
|
SHADER_PARAMETER(float, DeformationRadius)
|
||||||
SHADER_PARAMETER(float, Plasticity)
|
SHADER_PARAMETER(float, Plasticity)
|
||||||
|
|
||||||
// 纹理参数
|
// 纹理参数
|
||||||
SHADER_PARAMETER_TEXTURE(Texture2D, InputTexture)
|
SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, InputTexture)
|
||||||
SHADER_PARAMETER_UAV(RWTexture2D<float4>, OutputTexture)
|
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutputTexture)
|
||||||
|
|
||||||
// 更新区域
|
// 更新区域
|
||||||
SHADER_PARAMETER(FIntVector, TextureSize)
|
SHADER_PARAMETER(FIntVector, TextureSize)
|
||||||
SHADER_PARAMETER(FIntVector, UpdateRegionMin)
|
SHADER_PARAMETER(FIntVector4, UpdateRegionParam)
|
||||||
SHADER_PARAMETER(FIntVector, UpdateRegionSize)
|
|
||||||
END_SHADER_PARAMETER_STRUCT()
|
END_SHADER_PARAMETER_STRUCT()
|
||||||
|
|
||||||
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
|
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)
|
static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
|
||||||
{
|
{
|
||||||
FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
|
FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
|
||||||
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_X"), 8);
|
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_X"), 8);
|
||||||
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_Y"), 8);
|
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_Y"), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 分派函数
|
|
||||||
static void Dispatch(
|
|
||||||
FRHICommandListImmediate& RHICmdList,
|
|
||||||
const FDeformationCSDispatchParams& Params);
|
|
||||||
};
|
};
|
||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "IronBlock.h"
|
#include "IronBlock.h"
|
||||||
|
// 确保包含了 RDG 所需的头文件
|
||||||
|
#include "RenderGraphBuilder.h"
|
||||||
|
#include "RenderGraphUtils.h" // FComputeShaderUtils::AddPass
|
||||||
#include "FDeformComputeShader.h" // 确保这个头文件存在且包含了 FDeformationCSDispatchParams
|
#include "FDeformComputeShader.h" // 确保这个头文件存在且包含了 FDeformationCSDispatchParams
|
||||||
#include "StaticMeshResources.h"
|
#include "StaticMeshResources.h"
|
||||||
#include "TextureResource.h"
|
#include "TextureResource.h"
|
||||||
@@ -12,7 +14,6 @@
|
|||||||
#include "Materials/MaterialInstanceDynamic.h"
|
#include "Materials/MaterialInstanceDynamic.h"
|
||||||
#include "PhysicsEngine/BodySetup.h"
|
#include "PhysicsEngine/BodySetup.h"
|
||||||
#include "RHICommandList.h"
|
#include "RHICommandList.h"
|
||||||
#include "RenderGraphBuilder.h" // 包含 FRDGBuilder
|
|
||||||
#include "Engine/Texture.h"
|
#include "Engine/Texture.h"
|
||||||
#include "GenericPlatform/GenericPlatformProcess.h"
|
#include "GenericPlatform/GenericPlatformProcess.h"
|
||||||
|
|
||||||
@@ -328,11 +329,11 @@ void AIronBlock::ExecuteDeformationCS()
|
|||||||
|
|
||||||
// --- 关键修复: 在游戏线程只获取 Input RHI Texture 句柄 ---
|
// --- 关键修复: 在游戏线程只获取 Input RHI Texture 句柄 ---
|
||||||
FTextureRHIRef InputRHI = GetRenderTargetRHI(ReadTarget);
|
FTextureRHIRef InputRHI = GetRenderTargetRHI(ReadTarget);
|
||||||
|
FTextureRHIRef WriteRHI = GetRenderTargetRHI(WriteTarget); // 必须获取写入目标的RHI
|
||||||
|
|
||||||
// 检查 Input RHI 和 WriteTarget UObject 是否有效
|
if (!InputRHI.IsValid() || !WriteRHI.IsValid())
|
||||||
if (!InputRHI.IsValid() || !WriteTarget)
|
|
||||||
{
|
{
|
||||||
UE_LOG(LogTemp, Error, TEXT("Invalid texture RHI resources or WriteTarget UObject!"));
|
UE_LOG(LogTemp, Error, TEXT("Invalid texture RHI resources!"));
|
||||||
return;
|
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.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;
|
||||||
|
|
||||||
// 准备参数
|
// --- 关键修改:使用 RDG ---
|
||||||
FDeformationCSDispatchParams Params;
|
ENQUEUE_RENDER_COMMAND(ExecuteDeformationCS_RDG)(
|
||||||
Params.ImpactPoint = CurrentImpactPoint; // 确保类型匹配 (FVector -> FVector3f)
|
[
|
||||||
Params.ImpactNormal = CurrentImpactNormal;
|
// 捕获所有需要的参数
|
||||||
Params.ImpactForce = CurrentImpactForce;
|
InputRHI,
|
||||||
Params.DeformationRadius = CurrentDeformationRadius;
|
WriteRHI,
|
||||||
Params.Plasticity = CurrentPlasticity;
|
CurrentImpactPoint = this->CurrentImpactPoint, // 拷贝一份
|
||||||
Params.InputTexture = InputRHI;
|
CurrentImpactNormal = this->CurrentImpactNormal,
|
||||||
//Params.OutputTexture = OutputUAV; // **直接使用RT的UAV**
|
CurrentImpactForce = this->CurrentImpactForce,
|
||||||
Params.UpdateRegion = UpdateRegion;
|
CurrentDeformationRadius = this->CurrentDeformationRadius,
|
||||||
Params.TextureSize = FIntVector(TexSize, TexSize, 1);
|
CurrentPlasticity = this->CurrentPlasticity,
|
||||||
|
UpdateRegion, //
|
||||||
// 在渲染线程中执行Compute Shader
|
TexSize //
|
||||||
ENQUEUE_RENDER_COMMAND(ExecuteDeformationCS)(
|
](FRHICommandListImmediate& RHICmdList)
|
||||||
[Params, WriteTarget](FRHICommandListImmediate& RHICmdList)
|
|
||||||
{
|
{
|
||||||
// --- 现在我们在渲染线程上 ---
|
// 1. 创建 RDG Builder
|
||||||
|
FRDGBuilder builder(RHICmdList);
|
||||||
|
|
||||||
// 1. 从 UObject 获取 FTextureResource
|
// 2. 将我们的外部 RT 注册到 RDG 中
|
||||||
FTextureResource* RTResource = WriteTarget->GetResource();
|
// 注意:我们使用 WriteRHI->GetDesc() 来获取纹理描述
|
||||||
if (!RTResource)
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. 转换为 FTextureRenderTargetResource
|
// 7. 计算线程组数量
|
||||||
FTextureRenderTargetResource* WriteRTResource = static_cast<FTextureRenderTargetResource*>(RTResource);
|
// (注意:你的USF需要处理 UpdateRegion,这里我们调度整个区域)
|
||||||
if (!WriteRTResource)
|
FIntVector NumGroups = FIntVector::DivideAndRoundUp(
|
||||||
{
|
FIntVector(UpdateRegion.Width(), UpdateRegion.Height(), 1),
|
||||||
UE_LOG(LogTemp, Error, TEXT("Failed to cast to FTextureRenderTargetResource on render thread!"));
|
FDeformComputeShader::GetGroupSize()
|
||||||
return;
|
);
|
||||||
}
|
// 如果你的shader总是处理整个纹理,请使用:
|
||||||
|
// FIntVector NumGroups = FIntVector::DivideAndRoundUp(
|
||||||
|
// Params->TextureSize, FDeformComputeShader::GetGroupSize()
|
||||||
|
// );
|
||||||
|
|
||||||
// 3. ✨ 在渲染线程上调用 GetRenderTargetUAV()
|
// 8. 添加 Compute Pass
|
||||||
FUnorderedAccessViewRHIRef OutputUAV = WriteRTResource->GetRenderTargetUAV();
|
FComputeShaderUtils::AddPass(
|
||||||
|
builder,
|
||||||
|
RDG_EVENT_NAME("ExecuteDeformationCS"),
|
||||||
|
ComputeShader,
|
||||||
|
Params,
|
||||||
|
NumGroups
|
||||||
|
);
|
||||||
|
|
||||||
// 4. 检查是否成功
|
// 9. 执行 RDG (这会处理所有屏障和调度)
|
||||||
if (!OutputUAV.IsValid())
|
builder.Execute();
|
||||||
{
|
|
||||||
// 如果在这里仍然失败,说明 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));
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 等待渲染命令完成,以便在CPU上读取 (如果需要立即更新碰撞体)
|
// --- 结束 RDG 修改 ---
|
||||||
// 注意:这是一个同步点,会影响性能。
|
|
||||||
|
// 确保渲染命令完成 (如果你需要立即更新碰撞体)
|
||||||
// FlushRenderingCommands();
|
// FlushRenderingCommands();
|
||||||
// UpdateCollisionAsync(UpdateRegion, WriteTarget); // 异步更新碰撞体
|
// UpdateCollisionAsync(UpdateRegion, WriteTarget);
|
||||||
|
|
||||||
// --- 关键修复: 更新材质参数,使其下一帧读取我们刚刚写入的纹理 ---
|
// --- 关键修复: 更新材质参数,使其下一帧读取我们刚刚写入的纹理 ---
|
||||||
if (DynMaterial)
|
if (DynMaterial)
|
||||||
|
|||||||
Reference in New Issue
Block a user