调通usf调用,将usf输出添加到材质。但是现在usf正式算法的输出值无法产生形变

This commit is contained in:
2025-11-12 00:17:23 +08:00
parent f12fef4edd
commit b027ec6487
12 changed files with 275 additions and 16 deletions
+24
View File
@@ -0,0 +1,24 @@
{
"FileVersion": 3,
"Version": 1,
"VersionName": "1.0",
"FriendlyName": "MiceShaders",
"Description": "",
"Category": "Other",
"CreatedBy": "",
"CreatedByURL": "",
"DocsURL": "",
"MarketplaceURL": "",
"SupportURL": "",
"CanContainContent": true,
"IsBetaVersion": false,
"IsExperimentalVersion": false,
"Installed": false,
"Modules": [
{
"Name": "MiceShaders",
"Type": "Runtime",
"LoadingPhase": "PostConfigInit"
}
]
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

@@ -0,0 +1,91 @@
// 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;
}
}
@@ -0,0 +1,56 @@
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class MiceShaders : ModuleRules
{
public MiceShaders(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
PublicIncludePaths.AddRange(
new string[] {
// ... add public include paths required here ...
"MiceShaders/Public"
}
);
PrivateIncludePaths.AddRange(
new string[] {
// ... add other private include paths required here ...
"MiceShaders/Private"
}
);
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core",
// ... add other public dependencies that you statically link with here ...
"RenderCore",
"RHI",
}
);
PrivateDependencyModuleNames.AddRange(
new string[]
{
"CoreUObject",
"Engine",
"Projects"
// ... add private dependencies that you statically link with here ...
}
);
DynamicallyLoadedModuleNames.AddRange(
new string[]
{
// ... add any modules that your module loads dynamically here ...
}
);
}
}
@@ -0,0 +1,34 @@
#include "FDeformComputeShader.h"
#include "GlobalShader.h"
#include "ShaderParameterStruct.h"
#include "RHIStaticStates.h"
#include "Shader.h"
#include "GlobalShader.h"
#include "RHICommandList.h"
#include "RHIResources.h"
#include "ShaderParameterUtils.h"
// 全局参数存储
FThreadSafeDeformationParams GDeformationParams;
// 实现Compute Shader
IMPLEMENT_GLOBAL_SHADER(FDeformComputeShader, "/MiceShaders/Shaders/Private/DeformationCS.usf", "MainCompute", SF_Compute);
// 线程安全参数管理
void FThreadSafeDeformationParams::AddParams(const FDeformationCSDispatchParams& NewParams)
{
FScopeLock Lock(&ParamsCriticalSection);
PendingParams.Add(NewParams);
}
bool FThreadSafeDeformationParams::ConsumeParams(FDeformationCSDispatchParams& OutParams)
{
FScopeLock Lock(&ParamsCriticalSection);
if (PendingParams.Num() > 0)
{
OutParams = PendingParams[0];
PendingParams.RemoveAt(0);
return true;
}
return false;
}
@@ -0,0 +1,24 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "MiceShaders.h"
#include "Interfaces/IPluginManager.h"
#define LOCTEXT_NAMESPACE "FMiceShadersModule"
void FMiceShadersModule::StartupModule()
{
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
FString PluginShaderDir = FPaths::Combine(IPluginManager::Get().FindPlugin(TEXT("MiceShaders"))->GetBaseDir(), TEXT("Shaders"));
AddShaderSourceDirectoryMapping(TEXT("/MiceShaders/Shaders"), PluginShaderDir);
}
void FMiceShadersModule::ShutdownModule()
{
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
// we call this function before unloading the module.
}
#undef LOCTEXT_NAMESPACE
IMPLEMENT_MODULE(FMiceShadersModule, MiceShaders)
@@ -0,0 +1,103 @@
#pragma once
#include "CoreMinimal.h"
#include "GlobalShader.h"
#include "ShaderParameterStruct.h"
#include "RenderGraphUtils.h" // 必须包含
// Compute Shader参数结构体
struct MICESHADERS_API FDeformationCSDispatchParams
{
// 碰撞参数
FVector ImpactPoint;
FVector ImpactNormal;
float ImpactForce;
float DeformationRadius;
float Plasticity;
// 纹理资源
FTextureRHIRef InputTexture;
FUnorderedAccessViewRHIRef OutputTexture;
// 更新区域 (优化部分更新)
FIntRect UpdateRegion;
// 纹理尺寸
FIntVector TextureSize;
FDeformationCSDispatchParams() : ImpactPoint(0,0,0),
ImpactNormal(0,0,0),
ImpactForce(0.0f),
DeformationRadius(10.0f),
Plasticity(0.7f),
TextureSize(FIntVector::ZeroValue)
{
}
};
// 支持多实例的线程安全参数
struct FThreadSafeDeformationParams
{
FCriticalSection ParamsCriticalSection;
TArray<FDeformationCSDispatchParams> PendingParams;
void AddParams(const FDeformationCSDispatchParams& NewParams);
bool ConsumeParams(FDeformationCSDispatchParams& OutParams);
};
// 全局参数存储
extern FThreadSafeDeformationParams GDeformationParams;
// DeformationCS.h (续)
// Compute Shader类
class MICESHADERS_API FDeformComputeShader : public FGlobalShader
{
DECLARE_GLOBAL_SHADER(FDeformComputeShader);
SHADER_USE_PARAMETER_STRUCT(FDeformComputeShader, FGlobalShader);
BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
// 碰撞参数
SHADER_PARAMETER(FVector3f, ImpactPoint)
SHADER_PARAMETER(float, ImpactForce)
SHADER_PARAMETER(FVector3f, ImpactNormal)
SHADER_PARAMETER(float, DeformationRadius)
SHADER_PARAMETER(float, Plasticity)
// 更新区域
SHADER_PARAMETER(FIntVector, TextureSize)
SHADER_PARAMETER(FIntVector4, UpdateRegionParam)
// 纹理参数
SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture2D, InputTexture)
SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float4>, OutputTexture)
END_SHADER_PARAMETER_STRUCT()
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
{
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);
}
};
@@ -0,0 +1,14 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "Modules/ModuleManager.h"
class FMiceShadersModule : public IModuleInterface
{
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};