IVSmoke 1.0
Loading...
Searching...
No Matches
IVSmokeVSMProcessor.cpp
1// Copyright (c) 2026, Team SDB. All rights reserved.
2
3#include "IVSmokeVSMProcessor.h"
4#include "IVSmokeCSMRenderer.h"
5#include "IVSmokeShaders.h"
6#include "IVSmokePostProcessPass.h"
7#include "RenderGraphBuilder.h"
8#include "RenderGraphUtils.h"
9#include "GlobalShader.h"
10
11DEFINE_LOG_CATEGORY_STATIC(LogIVSmokeVSM, Log, All);
12
13// ============================================================================
14// Constructor / Destructor
15// ============================================================================
16
17FIVSmokeVSMProcessor::FIVSmokeVSMProcessor()
18{
19}
20
21FIVSmokeVSMProcessor::~FIVSmokeVSMProcessor()
22{
23}
24
25// ============================================================================
26// Process
27// ============================================================================
28
30 FRDGBuilder& GraphBuilder,
31 FRDGTextureRef DepthTexture,
32 FRDGTextureRef VSMTexture,
33 int32 BlurRadius)
34{
35 if (!DepthTexture || !VSMTexture)
36 {
37 return;
38 }
39
40 // Step 1: Convert depth to variance
41 AddDepthToVariancePass(GraphBuilder, DepthTexture, VSMTexture);
42
43 // Step 2: Apply blur if radius > 0
44 if (BlurRadius > 0)
45 {
46 const FIntPoint TextureSize(VSMTexture->Desc.Extent.X, VSMTexture->Desc.Extent.Y);
47
48 // Create temporary texture for ping-pong blur
49 FRDGTextureDesc TempDesc = FRDGTextureDesc::Create2D(
50 TextureSize,
51 PF_G32R32F, // RG32F for variance
52 FClearValueBinding::None,
53 TexCreate_ShaderResource | TexCreate_UAV
54 );
55 FRDGTextureRef TempTexture = GraphBuilder.CreateTexture(TempDesc, TEXT("IVSmokeVSMBlurTemp"));
56
57 // Horizontal blur: VSMTexture -> TempTexture
58 AddHorizontalBlurPass(GraphBuilder, VSMTexture, TempTexture, BlurRadius);
59
60 // Vertical blur: TempTexture -> VSMTexture
61 AddVerticalBlurPass(GraphBuilder, TempTexture, VSMTexture, BlurRadius);
62 }
63}
64
66 FRDGBuilder& GraphBuilder,
67 TArray<FIVSmokeCascadeData>& Cascades,
68 int32 BlurRadius)
69{
70 for (int32 CascadeIndex = 0; CascadeIndex < Cascades.Num(); CascadeIndex++)
71 {
72 FIVSmokeCascadeData& Cascade = Cascades[CascadeIndex];
73
74 if (!Cascade.DepthRT || !Cascade.VSMRT)
75 {
76 continue;
77 }
78
79 // Register external textures (include cascade index for RenderDoc debugging)
80 FRDGTextureRef DepthRDG = GraphBuilder.RegisterExternalTexture(
81 CreateRenderTarget(
82 Cascade.DepthRT->GetRenderTargetResource()->GetRenderTargetTexture(),
83 *FString::Printf(TEXT("IVSmokeCSMDepth_%d"), CascadeIndex)
84 )
85 );
86
87 FRDGTextureRef VSMRDG = GraphBuilder.RegisterExternalTexture(
88 CreateRenderTarget(
89 Cascade.VSMRT->GetRenderTargetResource()->GetRenderTargetTexture(),
90 *FString::Printf(TEXT("IVSmokeCSMVSM_%d"), CascadeIndex)
91 )
92 );
93
94 Process(GraphBuilder, DepthRDG, VSMRDG, BlurRadius);
95 }
96}
97
98// ============================================================================
99// Depth to Variance Pass
100// ============================================================================
101
102void FIVSmokeVSMProcessor::AddDepthToVariancePass(
103 FRDGBuilder& GraphBuilder,
104 FRDGTextureRef DepthTexture,
105 FRDGTextureRef VSMTexture)
106{
107 const FIntPoint TextureSize(DepthTexture->Desc.Extent.X, DepthTexture->Desc.Extent.Y);
108
109 FGlobalShaderMap* ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel);
110 TShaderMapRef<FIVSmokeDepthToVarianceCS> ComputeShader(ShaderMap);
111
112 auto* Parameters = GraphBuilder.AllocParameters<FIVSmokeDepthToVarianceCS::FParameters>();
113 Parameters->DepthTexture = DepthTexture;
114 Parameters->VarianceTexture = GraphBuilder.CreateUAV(VSMTexture);
115 Parameters->TextureSize = TextureSize;
116
118 GraphBuilder,
119 ShaderMap,
120 ComputeShader,
121 Parameters,
122 FIntVector(TextureSize.X, TextureSize.Y, 1)
123 );
124}
125
126// ============================================================================
127// Blur Passes
128// ============================================================================
129
130void FIVSmokeVSMProcessor::AddHorizontalBlurPass(
131 FRDGBuilder& GraphBuilder,
132 FRDGTextureRef SourceTexture,
133 FRDGTextureRef DestTexture,
134 int32 BlurRadius)
135{
136 const FIntPoint TextureSize(SourceTexture->Desc.Extent.X, SourceTexture->Desc.Extent.Y);
137
138 FGlobalShaderMap* ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel);
139 TShaderMapRef<FIVSmokeVSMBlurCS> ComputeShader(ShaderMap);
140
141 auto* Parameters = GraphBuilder.AllocParameters<FIVSmokeVSMBlurCS::FParameters>();
142 Parameters->SourceTexture = SourceTexture;
143 Parameters->DestTexture = GraphBuilder.CreateUAV(DestTexture);
144 Parameters->LinearClampSampler = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
145 Parameters->TextureSize = TextureSize;
146 Parameters->BlurRadius = BlurRadius;
147 Parameters->BlurDirection = 0; // Horizontal
148
150 GraphBuilder,
151 ShaderMap,
152 ComputeShader,
153 Parameters,
154 FIntVector(TextureSize.X, TextureSize.Y, 1)
155 );
156}
157
158void FIVSmokeVSMProcessor::AddVerticalBlurPass(
159 FRDGBuilder& GraphBuilder,
160 FRDGTextureRef SourceTexture,
161 FRDGTextureRef DestTexture,
162 int32 BlurRadius)
163{
164 const FIntPoint TextureSize(SourceTexture->Desc.Extent.X, SourceTexture->Desc.Extent.Y);
165
166 FGlobalShaderMap* ShaderMap = GetGlobalShaderMap(GMaxRHIFeatureLevel);
167 TShaderMapRef<FIVSmokeVSMBlurCS> ComputeShader(ShaderMap);
168
169 auto* Parameters = GraphBuilder.AllocParameters<FIVSmokeVSMBlurCS::FParameters>();
170 Parameters->SourceTexture = SourceTexture;
171 Parameters->DestTexture = GraphBuilder.CreateUAV(DestTexture);
172 Parameters->LinearClampSampler = TStaticSamplerState<SF_Bilinear, AM_Clamp, AM_Clamp, AM_Clamp>::GetRHI();
173 Parameters->TextureSize = TextureSize;
174 Parameters->BlurRadius = BlurRadius;
175 Parameters->BlurDirection = 1; // Vertical
176
178 GraphBuilder,
179 ShaderMap,
180 ComputeShader,
181 Parameters,
182 FIntVector(TextureSize.X, TextureSize.Y, 1)
183 );
184}
static void AddComputeShaderPass(FRDGBuilder &GraphBuilder, FGlobalShaderMap *ShaderMap, TShaderMapRef< TShaderClass > ComputeShader, typename TShaderClass::FParameters *Parameters, const FIntVector &TotalThreadSize)
void ProcessCascades(FRDGBuilder &GraphBuilder, TArray< FIVSmokeCascadeData > &Cascades, int32 BlurRadius)
void Process(FRDGBuilder &GraphBuilder, FRDGTextureRef DepthTexture, FRDGTextureRef VSMTexture, int32 BlurRadius)
TObjectPtr< UTextureRenderTarget2D > VSMRT
TObjectPtr< UTextureRenderTarget2D > DepthRT