调试shader
This commit is contained in:
@@ -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,43 +47,58 @@ 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)
|
||||
{
|
||||
FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
|
||||
OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_X"), 8);
|
||||
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