IVSmoke 1.0
Loading...
Searching...
No Matches
IVSmokeShaders.h
1// Copyright (c) 2026, Team SDB. All rights reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "GlobalShader.h"
7#include "RHI.h"
8#include "RHIStaticStates.h"
9#include "RenderGraphUtils.h"
10#include "SceneTexturesConfig.h"
11#include "SceneView.h"
12#include "ShaderParameterStruct.h"
13
14//~==============================================================================
15// GPU Data Structures for Multi-Volume Rendering
16
17/**
18 * GPU-side volume metadata for single-pass multi-volume ray marching.
19 * Each volume has its own transform, bounds, and rendering parameters.
20 * This struct is uploaded to a StructuredBuffer for GPU access.
21 *
22 * Memory layout: 256 bytes (aligned to 16-byte boundary)
23 */
25{
26 /** Grid resolution (voxel count per axis). */
27 FIntVector3 GridResolution; // 12 bytes
28 /** Total voxel count for this volume. */
29 uint32 VoxelCount; // 4 bytes
30
31 /** Smoke color for this volume. */
32 FVector3f SmokeColor; // 12 bytes
33 /** Absorption coefficient. */
34 float Absorption; // 4 bytes
35
36 /** Center offset for grid-to-local coordinate conversion. */
37 FVector3f CenterOffset; // 12 bytes
38 /** Per-volume density multiplier (default 1.0). */
39 float DensityScale; // 4 bytes
40
41 /** World-space AABB minimum (for fast ray-box intersection). */
42 FVector3f VolumeWorldAABBMin; // 12 bytes
43 float VoxelSize; // 4 bytes
44
45 /** World-space AABB maximum (for fast ray-box intersection). */
46 FVector3f VolumeWorldAABBMax; // 12 bytes
47 uint32 VoxelBufferOffset; // 4 bytes
48
49 FVector3f VoxelWorldAABBMin; // 12 bytes
50 float FadeInDuration; // 4 bytes
51 FVector3f VoxelWorldAABBMax; // 12 bytes
52 float FadeOutDuration; // 4 bytes
53
54 float Reserved[4]; // 16 bytes (future use / alignment)
55};
56
57// Ensure structure is 256 bytes for efficient GPU access
58static_assert(sizeof(FIVSmokeVolumeGPUData) % 16 == 0, "FIVSmokeVolumeGPUData size error");
59
60// Note: FIVSmokeMultiVolumeRayMarchCS is now defined in IVSmokeOccupancy.h
61// (Occupancy-based ray marching has replaced the original implementation)
62
63class IVSMOKE_API FIVSmokeNoiseGeneratorGlobalCS : public FGlobalShader
64{
65public:
66 static constexpr uint32 ThreadGroupSizeX = 8;
67 static constexpr uint32 ThreadGroupSizeY = 8;
68 static constexpr uint32 ThreadGroupSizeZ = 8;
69 static constexpr const TCHAR* EventName = TEXT("IVSmokeNoiseGeneratorGlobalCS");
70
71 DECLARE_GLOBAL_SHADER(FIVSmokeNoiseGeneratorGlobalCS);
72 SHADER_USE_PARAMETER_STRUCT(FIVSmokeNoiseGeneratorGlobalCS, FGlobalShader);
73 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
74 /** Output noise volume texture. */
75 SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture3D<float>, RWNoiseTex)
76 /** Texture resolution (voxel count per axis). */
77 SHADER_PARAMETER(FUintVector3, TexSize)
78 /** Number of fractal octaves for noise generation. */
79 SHADER_PARAMETER(int32, Octaves)
80 /** Wrap value for seamless tiling. */
81 SHADER_PARAMETER(float, Wrap)
82 /** Number of cells per axis for cellular noise. */
83 SHADER_PARAMETER(int32, AxisCellCount)
84 /** Noise amplitude (intensity). */
85 SHADER_PARAMETER(float, Amplitude)
86 /** Size of each noise cell. */
87 SHADER_PARAMETER(int32, CellSize)
88 /** Random seed for noise generation. */
89 SHADER_PARAMETER(int32, Seed)
90 END_SHADER_PARAMETER_STRUCT()
91
92public:
93 static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
94 {
95 return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
96 }
97};
98class IVSMOKE_API FIVSmokeStructuredToTextureCS : public FGlobalShader
99{
100public:
101 static constexpr uint32 ThreadGroupSizeX = 8;
102 static constexpr uint32 ThreadGroupSizeY = 8;
103 static constexpr uint32 ThreadGroupSizeZ = 8;
104 static constexpr const TCHAR* EventName = TEXT("IVSmokeStructuredToTextureCS");
105
106 DECLARE_GLOBAL_SHADER(FIVSmokeStructuredToTextureCS);
107 SHADER_USE_PARAMETER_STRUCT(FIVSmokeStructuredToTextureCS, FGlobalShader);
108 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
109 /** Output 3D texture atlas containing voxel density values. */
110 SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture3D<float>, Desti)
111 /** Per-voxel birth times for fade-in animation. */
112 SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<float>, BirthTimes)
113 /** Per-voxel death times for fade-out animation. */
114 SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<float>, DeathTimes)
115 /** Per-volume GPU metadata (transform, bounds, etc.). */
116 SHADER_PARAMETER_RDG_BUFFER_SRV(StructuredBuffer<FIVSmokeVolumeGPUData>, VolumeDataBuffer)
117
118 /** Total atlas texture size. */
119 SHADER_PARAMETER(FIntVector, TexSize)
120 /** Voxel resolution per volume. */
121 SHADER_PARAMETER(FIntVector, VoxelResolution)
122 /** Spacing between volumes in atlas. */
123 SHADER_PARAMETER(int32, PackedInterval)
124 /** Number of volumes per axis in atlas (3D grid layout). */
125 SHADER_PARAMETER(FIntVector, VoxelAtlasCount)
126 /** Current game time for fade animation calculation. */
127 SHADER_PARAMETER(float, GameTime)
128 /** Number of active volumes (for bounds checking). */
129 SHADER_PARAMETER(int32, VolumeCount)
130 END_SHADER_PARAMETER_STRUCT()
131
132public:
133 static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
134 {
135 return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
136 }
137};
138class IVSMOKE_API FIVSmokeVoxelFXAACS : public FGlobalShader
139{
140public:
141 static constexpr uint32 ThreadGroupSizeX = 8;
142 static constexpr uint32 ThreadGroupSizeY = 8;
143 static constexpr uint32 ThreadGroupSizeZ = 8;
144 static constexpr const TCHAR* EventName = TEXT("IVSmokeVoxelFXAACS");
145
146 DECLARE_GLOBAL_SHADER(FIVSmokeVoxelFXAACS);
147 SHADER_USE_PARAMETER_STRUCT(FIVSmokeVoxelFXAACS, FGlobalShader);
148 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
149 /** Output anti-aliased 3D texture. */
150 SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture3D<float>, Desti)
151 /** Source 3D texture to apply FXAA. */
152 SHADER_PARAMETER_RDG_TEXTURE_SRV(Texture3D<float>, Source)
153 /** Linear sampler with border addressing. */
154 SHADER_PARAMETER_SAMPLER(SamplerState, LinearBorder_Sampler)
155 /** Texture resolution. */
156 SHADER_PARAMETER(FIntVector, TexSize)
157
158 /** Maximum edge span for FXAA. */
159 SHADER_PARAMETER(float, FXAASpanMax)
160 /** Edge detection range threshold. */
161 SHADER_PARAMETER(float, FXAARange)
162 /** Sharpness factor for anti-aliasing. */
163 SHADER_PARAMETER(float, FXAASharpness)
164 END_SHADER_PARAMETER_STRUCT()
165};
166
167class IVSMOKE_API FIVSmokeCompositePS : public FGlobalShader
168{
169public:
170 static constexpr const TCHAR* EventName = TEXT("IVSmokeCompositePS");
171 static FRHIBlendState* GetBlendState()
172 {
173 return TStaticBlendState<>::GetRHI();
174 }
175
176 DECLARE_GLOBAL_SHADER(FIVSmokeCompositePS);
177 SHADER_USE_PARAMETER_STRUCT(FIVSmokeCompositePS, FGlobalShader);
178 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
179 /** Scene color texture (background). */
180 SHADER_PARAMETER_RDG_TEXTURE(Texture2D, SceneTex)
181 /** Smoke albedo (color) from ray marching. */
182 SHADER_PARAMETER_RDG_TEXTURE(Texture2D, SmokeTex)
183 /** Linear sampler with repeat addressing. */
184 SHADER_PARAMETER_SAMPLER(SamplerState, LinearClamp_Sampler)
185 /** Viewport size for UV calculation. */
186 SHADER_PARAMETER(FVector2f, ViewportSize)
187 /** View rect offset for multi-view support. */
188 SHADER_PARAMETER(FVector2f, ViewRectMin)
189 RENDER_TARGET_BINDING_SLOTS()
190 END_SHADER_PARAMETER_STRUCT()
191
192public:
193 static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
194 {
195 return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
196 }
197};
198class IVSMOKE_API FIVSmokeCopyPS : public FGlobalShader
199{
200public:
201 static constexpr const TCHAR* EventName = TEXT("IVSmokeCopyPS");
202 static FRHIBlendState* GetBlendState()
203 {
204 return TStaticBlendState<>::GetRHI();
205 }
206
207 DECLARE_GLOBAL_SHADER(FIVSmokeCopyPS);
208 SHADER_USE_PARAMETER_STRUCT(FIVSmokeCopyPS, FGlobalShader);
209
210 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
211 /** Source texture to copy. */
212 SHADER_PARAMETER_RDG_TEXTURE(Texture2D, MainTex)
213 /** Linear sampler for bilinear filtering. */
214 SHADER_PARAMETER_SAMPLER(SamplerState, LinearRepeat_Sampler)
215 /** Destination texture size for UV mapping. */
216 SHADER_PARAMETER(FVector2f, ViewportSize)
217 RENDER_TARGET_BINDING_SLOTS()
218 END_SHADER_PARAMETER_STRUCT()
219
220public:
221 static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
222 {
223 return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
224 }
225};
226
227class IVSMOKE_API FIVSmokeUpsampleFilterPS : public FGlobalShader
228{
229public:
230 static constexpr const TCHAR* EventName = TEXT("IVSmokeUpsampleFilterPS");
231 static FRHIBlendState* GetBlendState()
232 {
233 return TStaticBlendState<>::GetRHI();
234 }
235
236 DECLARE_GLOBAL_SHADER(FIVSmokeUpsampleFilterPS);
237 SHADER_USE_PARAMETER_STRUCT(FIVSmokeUpsampleFilterPS, FGlobalShader);
238
239 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
240 /** Scene color texture. */
241 SHADER_PARAMETER_RDG_TEXTURE(Texture2D, SceneTex)
242 /** Smoke albedo (color) from ray marching. */
243 SHADER_PARAMETER_RDG_TEXTURE(Texture2D, SmokeAlbedoTex)
244 /** Smoke opacity mask from ray marching. */
245 SHADER_PARAMETER_RDG_TEXTURE(Texture2D, SmokeLocalPosAlphaTex)
246 /** Linear sampler with repeat addressing. */
247 SHADER_PARAMETER_SAMPLER(SamplerState, LinearClamp_Sampler)
248 /** UpSample Filter Type. (0 = None, 1 = Sharpen, 2 = Blur, 3 = Median) */
249 SHADER_PARAMETER(int, UpSampleFilterType)
250 /** Sharpeness filter strength. */
251 SHADER_PARAMETER(float, SharpenStrength)
252 /** 3x3 gaussian blur strength. */
253 SHADER_PARAMETER(float, BlurStrength)
254 /** Viewport size for UV calculation. */
255 SHADER_PARAMETER(FVector2f, ViewportSize)
256 /** View rect offset for multi-view support. */
257 SHADER_PARAMETER(FVector2f, ViewRectMin)
258 RENDER_TARGET_BINDING_SLOTS()
259 END_SHADER_PARAMETER_STRUCT()
260
261public:
262 static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
263 {
264 return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
265 }
266};
267
268//~==============================================================================
269// VSM (Variance Shadow Map) Shaders
270
271/**
272 * Depth to Variance compute shader.
273 * Converts depth texture (R32F) to variance texture (RG32F).
274 * Output: (depth, depth²)
275 */
276class IVSMOKE_API FIVSmokeDepthToVarianceCS : public FGlobalShader
277{
278public:
279 static constexpr uint32 ThreadGroupSizeX = 8;
280 static constexpr uint32 ThreadGroupSizeY = 8;
281 static constexpr uint32 ThreadGroupSizeZ = 1;
282 static constexpr const TCHAR* EventName = TEXT("IVSmokeDepthToVarianceCS");
283
284 DECLARE_GLOBAL_SHADER(FIVSmokeDepthToVarianceCS);
285 SHADER_USE_PARAMETER_STRUCT(FIVSmokeDepthToVarianceCS, FGlobalShader);
286
287 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
288 /** Input depth texture from shadow capture. */
289 SHADER_PARAMETER_RDG_TEXTURE(Texture2D, DepthTexture)
290 /** Output variance texture (depth, depth squared). */
291 SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float2>, VarianceTexture)
292 /** Texture resolution. */
293 SHADER_PARAMETER(FIntPoint, TextureSize)
294 END_SHADER_PARAMETER_STRUCT()
295
296 static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
297 {
298 return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
299 }
300
301 static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
302 {
303 FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
304 OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_X"), ThreadGroupSizeX);
305 OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_Y"), ThreadGroupSizeY);
306 }
307};
308
309/**
310 * VSM Gaussian blur compute shader.
311 * Performs separable Gaussian blur on variance texture.
312 * Uses horizontal or vertical direction based on BlurDirection parameter.
313 */
314class IVSMOKE_API FIVSmokeVSMBlurCS : public FGlobalShader
315{
316public:
317 static constexpr uint32 ThreadGroupSizeX = 8;
318 static constexpr uint32 ThreadGroupSizeY = 8;
319 static constexpr uint32 ThreadGroupSizeZ = 1;
320 static constexpr const TCHAR* EventName = TEXT("IVSmokeVSMBlurCS");
321
322 DECLARE_GLOBAL_SHADER(FIVSmokeVSMBlurCS);
323 SHADER_USE_PARAMETER_STRUCT(FIVSmokeVSMBlurCS, FGlobalShader);
324
325 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
326 /** Source variance texture to blur. */
327 SHADER_PARAMETER_RDG_TEXTURE(Texture2D, SourceTexture)
328 /** Output blurred variance texture. */
329 SHADER_PARAMETER_RDG_TEXTURE_UAV(RWTexture2D<float2>, DestTexture)
330 /** Linear sampler with clamp addressing. */
331 SHADER_PARAMETER_SAMPLER(SamplerState, LinearClampSampler)
332 /** Texture resolution. */
333 SHADER_PARAMETER(FIntPoint, TextureSize)
334 /** Blur kernel radius in pixels. */
335 SHADER_PARAMETER(int32, BlurRadius)
336 /** Blur direction (0 = Horizontal, 1 = Vertical). */
337 SHADER_PARAMETER(int32, BlurDirection)
338 END_SHADER_PARAMETER_STRUCT()
339
340 static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
341 {
342 return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
343 }
344
345 static void ModifyCompilationEnvironment(const FGlobalShaderPermutationParameters& Parameters, FShaderCompilerEnvironment& OutEnvironment)
346 {
347 FGlobalShader::ModifyCompilationEnvironment(Parameters, OutEnvironment);
348 OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_X"), ThreadGroupSizeX);
349 OutEnvironment.SetDefine(TEXT("THREADGROUP_SIZE_Y"), ThreadGroupSizeY);
350 }
351};
352
353//~==============================================================================
354// Depth Write Shaders
355
356/**
357 * Pre-Pass Depth Write pixel shader.
358 * Writes smoke depth for correct translucent sorting.
359 * Only writes depth for nearly opaque pixels (Alpha >= 0.99).
360 */
361class IVSMOKE_API FIVSmokeDepthWritePS : public FGlobalShader
362{
363public:
364 static constexpr const TCHAR* EventName = TEXT("IVSmokeDepthWritePS");
365
366 DECLARE_GLOBAL_SHADER(FIVSmokeDepthWritePS);
367 SHADER_USE_PARAMETER_STRUCT(FIVSmokeDepthWritePS, FGlobalShader);
368
369 BEGIN_SHADER_PARAMETER_STRUCT(FParameters, )
370 /** Smoke world position + depth from ray march. */
371 SHADER_PARAMETER_RDG_TEXTURE(Texture2D, SmokeWorldPosDepthTex)
372 /** Smoke local position + alpha from ray march. */
373 SHADER_PARAMETER_RDG_TEXTURE(Texture2D, SmokeLocalPosAlphaTex)
374 /** Linear sampler with clamp addressing. */
375 SHADER_PARAMETER_SAMPLER(SamplerState, LinearClampSampler)
376 /** Camera forward direction. */
377 SHADER_PARAMETER(FVector3f, CameraForward)
378 /** Camera world position. */
379 SHADER_PARAMETER(FVector3f, CameraOrigin)
380 /** Viewport size for UV calculation. */
381 SHADER_PARAMETER(FVector2f, ViewportSize)
382 /** ViewRect minimum offset. */
383 SHADER_PARAMETER(FVector2f, ViewRectMin)
384 /** Depth bias in centimeters. */
385 SHADER_PARAMETER(float, DepthBias)
386 /** Alpha threshold for depth write. */
387 SHADER_PARAMETER(float, AlphaThreshold)
388 /** Projection matrix element [2][2] for depth conversion. */
389 SHADER_PARAMETER(float, ViewToClip_22)
390 /** Projection matrix element [3][2] for depth conversion. */
391 SHADER_PARAMETER(float, ViewToClip_32)
392 RENDER_TARGET_BINDING_SLOTS()
393 END_SHADER_PARAMETER_STRUCT()
394
395public:
396 static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters& Parameters)
397 {
398 return IsFeatureLevelSupported(Parameters.Platform, ERHIFeatureLevel::SM5);
399 }
400};
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters &Parameters)
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters &Parameters)
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters &Parameters)
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters &Parameters)
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters &Parameters)
static bool ShouldCompilePermutation(const FGlobalShaderPermutationParameters &Parameters)