IVSmoke 1.0
Loading...
Searching...
No Matches
IVSmokePostProcessPass.h
1// Copyright (c) 2026, Team SDB. All rights reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "RenderGraphBuilder.h"
7#include "RenderGraphUtils.h"
8#include "ScreenPass.h"
9#include "GlobalShader.h"
10#include "ShaderParameterStruct.h"
11#include "PixelShaderUtils.h"
12
13/**
14 * Core utility for dispatching PS/CS post process passes.
15 * Designed for reusability - bring your own shader and parameters.
16 */
17
18class IVSMOKE_API FIVSmokePostProcessPass
19{
20public:
21 /**
22 * Add a fullscreen pixel shader pass.
23 *
24 * @param GraphBuilder RDG builder
25 * @param ShaderMap Global shader map
26 * @param PixelShader Pixel shader to use
27 * @param Parameters Shader parameters (must have RenderTargets bound)
28 * @param Output Render target
29 * @param Config Pass configuration
30 *
31 * @warning Confirmed Engine Bug (UE 5.6 - UE 5.7)
32 * The RDG Timeline View currently displays the raw format string (e.g., "IVSmoke::PixelShader: %s")
33 * instead of the resolved variable name in Unreal Insights.
34 *
35 * Workaround:
36 * 1. Select the event bar in Unreal Insights (Timing View).
37 * 2. Check the Details Panel (Metadata) to view the correct shader name (e.g., MyShaderPS).
38 *
39 * https://issues.unrealengine.com/issue/UE-298245
40 */
41 template<typename TShaderClass>
42 static void AddPixelShaderPass(
43 FRDGBuilder& GraphBuilder,
44 FGlobalShaderMap* ShaderMap,
45 TShaderMapRef<TShaderClass> PixelShader,
46 typename TShaderClass::FParameters* Parameters,
47 const FScreenPassRenderTarget& Output);
48
49 /**
50 * Add a compute shader pass.
51 *
52 * @param GraphBuilder RDG builder
53 * @param ShaderMap Global shader map
54 * @param ComputeShader Compute shader to use
55 * @param Parameters Shader parameters (must have UAV bound)
56 * @param ViewportSize Size of the viewport for thread dispatch
57 * @param Config Pass configuration
58 *
59 * @warning Confirmed Engine Bug (UE 5.6 - UE 5.7)
60 * Similar to the Pixel Shader pass, the scope name appears as "IVSmoke::ComputeShader: %s"
61 * in the Timing View due to the engine bug mentioned above.
62 *
63 * Please refer to the Details Panel in Unreal Insights for the correct shader name
64 */
65 template<typename TShaderClass>
66 static void AddComputeShaderPass(
67 FRDGBuilder& GraphBuilder,
68 FGlobalShaderMap* ShaderMap,
69 TShaderMapRef<TShaderClass> ComputeShader,
70 typename TShaderClass::FParameters* Parameters,
71 const FIntVector& TotalThreadSize);
72
73 /**
74 * Create an output texture suitable for UAV (compute shader).
75 *
76 * @param GraphBuilder RDG builder
77 * @param SourceTexture Texture to base dimensions on
78 * @param DebugName Debug name for the new texture
79 * @param OverrideFormat Override pixel format (PF_Unknown = use source format)
80 * @param OverrideExtent Override texture extent (zero = use source extent)
81 * @return New texture with UAV flag
82 */
83 static FRDGTextureRef CreateOutputTexture(
84 FRDGBuilder& GraphBuilder,
85 FRDGTextureRef SourceTexture,
86 const TCHAR* DebugName = TEXT("IVSmokeOutput"),
87 EPixelFormat OverrideFormat = PF_Unknown,
88 FIntPoint OverrideExtent = FIntPoint::ZeroValue,
89 ETextureCreateFlags Flags = ETextureCreateFlags::UAV);
90};
91//------------------------------------------------------------------------------
92// Template implementations
93//------------------------------------------------------------------------------
94
95template<typename TShaderClass>
97 FRDGBuilder& GraphBuilder,
98 FGlobalShaderMap* ShaderMap,
99 TShaderMapRef<TShaderClass> PixelShader,
100 typename TShaderClass::FParameters* Parameters,
101 const FScreenPassRenderTarget& Output)
102{
103 RDG_EVENT_SCOPE(GraphBuilder, "IVSmoke::PixelShader: %s", TShaderClass::EventName);
104
105 FPixelShaderUtils::AddFullscreenPass(
107 ShaderMap,
108 RDG_EVENT_NAME("%s", TShaderClass::EventName),
111 Output.ViewRect,
112 TShaderClass::GetBlendState()
113 );
114}
115
116template<typename TShaderClass>
118 FRDGBuilder& GraphBuilder,
119 FGlobalShaderMap* ShaderMap,
120 TShaderMapRef<TShaderClass> ComputeShader,
121 typename TShaderClass::FParameters* Parameters,
122 const FIntVector& TotalThreadSize)
123{
124 const uint32 GroupCountX = FMath::DivideAndRoundUp((uint32)TotalThreadSize.X, TShaderClass::ThreadGroupSizeX);
125 const uint32 GroupCountY = FMath::DivideAndRoundUp((uint32)TotalThreadSize.Y, TShaderClass::ThreadGroupSizeY);
126 const uint32 GroupCountZ = FMath::DivideAndRoundUp((uint32)TotalThreadSize.Z, TShaderClass::ThreadGroupSizeZ);
127
128 RDG_EVENT_SCOPE(GraphBuilder, "IVSmoke::ComputeShader: %s", TShaderClass::EventName);
129
130 FComputeShaderUtils::AddPass(
132 RDG_EVENT_NAME("%s", TShaderClass::EventName),
136 );
137}
static void AddComputeShaderPass(FRDGBuilder &GraphBuilder, FGlobalShaderMap *ShaderMap, TShaderMapRef< TShaderClass > ComputeShader, typename TShaderClass::FParameters *Parameters, const FIntVector &TotalThreadSize)
static void AddPixelShaderPass(FRDGBuilder &GraphBuilder, FGlobalShaderMap *ShaderMap, TShaderMapRef< TShaderClass > PixelShader, typename TShaderClass::FParameters *Parameters, const FScreenPassRenderTarget &Output)