IVSmoke 1.0
Loading...
Searching...
No Matches
IVSmokeSettings.h
1// Copyright (c) 2026, Team SDB. All rights reserved.
2
3#pragma once
4
5#include "CoreMinimal.h"
6#include "Engine/DeveloperSettings.h"
7#include "SceneViewExtension.h"
8#include "IVSmokeSettings.generated.h"
9
10/**
11 * Global quality preset that sets all section quality levels at once.
12 */
13UENUM(BlueprintType)
14enum class EIVSmokeGlobalQuality : uint8
15{
16 /** All sections set to Low (External Shadow Off). */
17 Low UMETA(DisplayName = "Low (Performance)"),
18
19 /** All sections set to Medium. */
20 Medium UMETA(DisplayName = "Medium (Balanced)"),
21
22 /** All sections set to High. */
23 High UMETA(DisplayName = "High (Quality)"),
24
25 /** Per-section custom configuration. */
26 Custom UMETA(DisplayName = "Custom")
27};
28
29/**
30 * Ray marching quality levels.
31 * Controls MaxSteps and MinStepSize for volumetric rendering.
32 */
33UENUM(BlueprintType)
34enum class EIVSmokeRayMarchQuality : uint8
35{
36 /** Low quality: MaxSteps=128, MinStepSize=50 */
37 Low UMETA(DisplayName = "Low"),
38
39 /** Medium quality: MaxSteps=256, MinStepSize=25 */
40 Medium UMETA(DisplayName = "Medium"),
41
42 /** High quality: MaxSteps=512, MinStepSize=16 */
43 High UMETA(DisplayName = "High"),
44
45 /** User-defined parameters. */
46 Custom UMETA(DisplayName = "Custom")
47};
48
49/**
50 * Self-shadow quality levels.
51 * Controls light marching for internal smoke self-shadowing.
52 */
53UENUM(BlueprintType)
54enum class EIVSmokeSelfShadowQuality : uint8
55{
56 /** Disabled: No self-shadowing. */
57 Off UMETA(DisplayName = "Off"),
58
59 /** Low quality: LightMarchingSteps=3 */
60 Low UMETA(DisplayName = "Low"),
61
62 /** Medium quality: LightMarchingSteps=6 */
63 Medium UMETA(DisplayName = "Medium"),
64
65 /** High quality: LightMarchingSteps=8 */
66 High UMETA(DisplayName = "High"),
67
68 /** User-defined parameters. */
69 Custom UMETA(DisplayName = "Custom")
70};
71
72/**
73 * External shadow quality levels.
74 * Controls cascaded shadow map settings for external object shadows.
75 */
76UENUM(BlueprintType)
77enum class EIVSmokeExternalShadowQuality : uint8
78{
79 /** Disabled: No external shadows. */
80 Off UMETA(DisplayName = "Off"),
81
82 /** Low quality: NumCascades=3, Resolution=512, MaxDistance=20000 */
83 Low UMETA(DisplayName = "Low"),
84
85 /** Medium quality: NumCascades=4, Resolution=512, MaxDistance=30000 */
86 Medium UMETA(DisplayName = "Medium"),
87
88 /** High quality: NumCascades=4, Resolution=1024, MaxDistance=50000 */
89 High UMETA(DisplayName = "High"),
90
91 /** User-defined parameters. */
92 Custom UMETA(DisplayName = "Custom")
93};
94
96/**
97 * Global settings for IVSmoke plugin.
98 * Accessible via Project Settings > Plugins > IVSmoke.
99 *
100 * These settings affect ALL smoke volumes globally.
101 * For per-volume appearance (color, density), use UIVSmokeSmokePreset.
102 */
103UCLASS(Config = Game, DefaultConfig, meta = (DisplayName = "IVSmoke"))
104class IVSMOKE_API UIVSmokeSettings : public UDeveloperSettings
105{
106 GENERATED_BODY()
107
108public:
110
111 /** Get the singleton settings instance. */
112 static const UIVSmokeSettings* Get();
113
114 //~==============================================================================
115 // UDeveloperSettings Interface
116
117 virtual FName GetCategoryName() const override { return TEXT("Plugins"); }
118 virtual FName GetSectionName() const override { return TEXT("IVSmoke"); }
119
120 UIVSmokeVisualMaterialPreset* GetVisualMaterialPreset() const;
121 virtual void PostInitProperties() override;
122
123 /** Change visual material preset data asset. */
124 UFUNCTION(BlueprintCallable, Category = "IVSmoke | VisualMaterial")
125 void SetVisualMaterialPreset(FSoftObjectPath VisualMaterialPresetPath);
126
127#if WITH_EDITOR
128 virtual FText GetSectionText() const override { return NSLOCTEXT("IVSmoke", "SettingsSection", "IVSmoke"); }
129 virtual FText GetSectionDescription() const override { return NSLOCTEXT("IVSmoke", "SettingsDescription", "Configure IVSmoke volumetric smoke settings"); }
130 virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
131#endif
132
133 //~==============================================================================
134 // General
135
136 /** Enable smoke rendering globally. */
137 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | General")
138 bool bEnableSmokeRendering = true;
139
140 /** Show advanced options in all categories. */
141 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | General")
142 bool bShowAdvancedOptions = false;
143
144 /** Global quality preset. Sets all section quality levels at once. */
145 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Quality")
146 EIVSmokeGlobalQuality GlobalQuality = EIVSmokeGlobalQuality::Medium;
147
148 /** Ray marching quality level. */
149 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Quality",
150 meta = (EditCondition = "GlobalQuality==EIVSmokeGlobalQuality::Custom", EditConditionHides))
151 EIVSmokeRayMarchQuality RayMarchQuality = EIVSmokeRayMarchQuality::Medium;
152
153 /** Custom: Maximum ray marching steps (32-1024). */
154 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Quality",
155 meta = (ClampMin = "32", ClampMax = "1024",
156 EditCondition = "GlobalQuality==EIVSmokeGlobalQuality::Custom && RayMarchQuality==EIVSmokeRayMarchQuality::Custom",
157 EditConditionHides))
158 int32 CustomMaxSteps = 256;
159
160 /** Custom: Minimum step size in world units (5-100). */
161 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Quality",
162 meta = (ClampMin = "5.0", ClampMax = "100.0",
163 EditCondition = "GlobalQuality==EIVSmokeGlobalQuality::Custom && RayMarchQuality==EIVSmokeRayMarchQuality::Custom",
164 EditConditionHides))
165 float CustomMinStepSize = 25.0f;
166
167 /** Self-shadow quality level. */
168 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Quality",
169 meta = (EditCondition = "GlobalQuality==EIVSmokeGlobalQuality::Custom", EditConditionHides))
170 EIVSmokeSelfShadowQuality SelfShadowQuality = EIVSmokeSelfShadowQuality::Medium;
171
172 /** Custom: Number of light marching steps (1-16). */
173 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Quality",
174 meta = (ClampMin = "1", ClampMax = "16",
175 EditCondition = "GlobalQuality==EIVSmokeGlobalQuality::Custom && SelfShadowQuality==EIVSmokeSelfShadowQuality::Custom",
176 EditConditionHides))
177 int32 CustomLightMarchingSteps = 6;
178
179 /** External shadow quality level. */
180 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Quality",
181 meta = (EditCondition = "GlobalQuality==EIVSmokeGlobalQuality::Custom", EditConditionHides))
182 EIVSmokeExternalShadowQuality ExternalShadowQuality = EIVSmokeExternalShadowQuality::Medium;
183
184 /** Custom: Number of shadow cascades (1-6). */
185 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Quality",
186 meta = (ClampMin = "1", ClampMax = "6",
187 EditCondition = "GlobalQuality==EIVSmokeGlobalQuality::Custom && ExternalShadowQuality==EIVSmokeExternalShadowQuality::Custom",
188 EditConditionHides))
189 int32 CustomNumCascades = 4;
190
191 /** Custom: Shadow map resolution per cascade (256-2048). */
192 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Quality",
193 meta = (ClampMin = "256", ClampMax = "2048",
194 EditCondition = "GlobalQuality==EIVSmokeGlobalQuality::Custom && ExternalShadowQuality==EIVSmokeExternalShadowQuality::Custom",
195 EditConditionHides))
196 int32 CustomCascadeResolution = 512;
197
198 /** Custom: Maximum shadow distance in centimeters (1000-100000). */
199 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Quality",
200 meta = (ClampMin = "1000", ClampMax = "100000",
201 EditCondition = "GlobalQuality==EIVSmokeGlobalQuality::Custom && ExternalShadowQuality==EIVSmokeExternalShadowQuality::Custom",
202 EditConditionHides))
203 float CustomShadowMaxDistance = 50000.0f;
204
205 //~==============================================================================
206 // Quality Getters
207
208 /** Get effective MaxSteps based on quality settings. */
209 int32 GetEffectiveMaxSteps() const;
210
211 /** Get effective MinStepSize based on quality settings. */
212 float GetEffectiveMinStepSize() const;
213
214 /** Check if self-shadowing is enabled based on quality settings. */
215 bool IsSelfShadowingEnabled() const;
216
217 /** Get effective light marching steps based on quality settings. */
218 int32 GetEffectiveLightMarchingSteps() const;
219
220 /** Check if external shadowing is enabled based on quality settings. */
221 bool IsExternalShadowingEnabled() const;
222
223 /** Get effective number of shadow cascades based on quality settings. */
224 int32 GetEffectiveNumCascades() const;
225
226 /** Get effective cascade resolution based on quality settings. */
227 int32 GetEffectiveCascadeResolution() const;
228
229 /** Get effective shadow max distance based on quality settings. */
230 float GetEffectiveShadowMaxDistance() const;
231
232 //~==============================================================================
233 // Appearance
234
235 /** Controls edge softness. Lower = softer edges. */
236 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Appearance", meta = (ClampMin = "0.0", ClampMax = "1.0"))
237 float SmokeDensityFalloff = 0.2f;
238
239 /** Scale for noise sampling. Affects smoke detail size. */
240 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Appearance", meta = (ClampMin = "1.0", ClampMax = "1000.0"))
241 float SmokeSize = 256.0f;
242
243 /** Wind direction and speed for smoke animation. */
244 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Appearance")
245 FVector WindDirection = FVector(0.00f, 0.00f, 0.1f);
246
247 /** Volume edge range offset for density falloff. */
248 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Appearance", meta = (ClampMin = "0.0", ClampMax = "1.0", EditCondition = "bShowAdvancedOptions", EditConditionHides))
249 float VolumeRangeOffset = 0.1;
250
251 /** Noise-based edge fade offset. */
252 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Appearance", meta = (ClampMin = "-1.0", ClampMax = "1.0", EditCondition = "bShowAdvancedOptions", EditConditionHides))
253 float VolumeEdgeNoiseFadeOffset = 0.1f;
254
255 /** Edge fade sharpness factor. */
256 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Appearance", meta = (ClampMin = "0.1", ClampMax = "10.0", EditCondition = "bShowAdvancedOptions", EditConditionHides))
257 float VolumeEdgeFadeSharpness = 3.0f;
258
259 //~==============================================================================
260 // Lighting
261
262 /** Enable Rayleigh scattering for atmospheric light effects. */
263 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Lighting")
264 bool bEnableScattering = true;
265
266 /** Scattering intensity multiplier. Higher = more light scattered through smoke. */
267 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Lighting", meta = (ClampMin = "0.0", ClampMax = "10.0", EditCondition = "bEnableScattering", EditConditionHides))
268 float ScatterScale = 0.5f;
269
270 /** Anisotropy parameter for Henyey-Greenstein phase function.
271 * 0 = isotropic, positive = forward scattering, negative = backward scattering */
272 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Lighting", meta = (ClampMin = "-0.99", ClampMax = "0.99", EditCondition = "bEnableScattering", EditConditionHides))
273 float ScatteringAnisotropy = 0.5f;
274
275 /** Override light direction instead of using scene directional light. */
276 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Lighting", meta = (EditCondition = "bShowAdvancedOptions", EditConditionHides))
277 bool bOverrideLightDirection = false;
278
279 /** Custom light direction (normalized). Used when bOverrideLightDirection is true. */
280 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Lighting", meta = (EditCondition = "bShowAdvancedOptions && bOverrideLightDirection", EditConditionHides))
281 FVector LightDirectionOverride = FVector(0.0f, 0.0f, 1.0f);
282
283 /** Override light color instead of using scene directional light. */
284 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Lighting", meta = (EditCondition = "bShowAdvancedOptions", EditConditionHides))
285 bool bOverrideLightColor = false;
286
287 /** Custom light color. Used when bOverrideLightColor is true. */
288 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Lighting", meta = (EditCondition = "bShowAdvancedOptions && bOverrideLightColor", EditConditionHides))
289 FLinearColor LightColorOverride = FLinearColor::White;
290
291 //~==============================================================================
292 // Self-Shadowing (Light Marching)
293
294 /** Minimum brightness in fully shadowed areas (0=dark, 1=no shadow). */
295 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Shadows | Self", meta = (ClampMin = "0.0", ClampMax = "1.0"))
296 float ShadowAmbient = 0.2f;
297
298 /** Maximum distance to march toward light (0=no limit). */
299 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Shadows | Self", meta = (ClampMin = "0.0", ClampMax = "500.0", EditCondition = "bShowAdvancedOptions", EditConditionHides))
300 float LightMarchingDistance = 0.0f;
301
302 /** Exponential distribution factor for light marching steps (1=uniform, 2-3=recommended). */
303 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Shadows | Self", meta = (ClampMin = "1.0", ClampMax = "5.0", EditCondition = "bShowAdvancedOptions", EditConditionHides))
304 float LightMarchingExpFactor = 2.0f;
305
306 //~==============================================================================
307 // External Shadows (Scene Capture)
308
309 /** Minimum brightness in externally shadowed areas (0=dark, 1=no shadow). */
310 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Shadows | External", meta = (ClampMin = "0.0", ClampMax = "1.0"))
311 float ExternalShadowAmbient = 0.3f;
312
313 /** Enable Variance Shadow Maps for soft shadows. */
314 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Shadows | External")
315 bool bEnableVSM = true;
316
317 /** VSM blur kernel radius (0=no blur). Higher = softer shadows. */
318 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Shadows | External", meta = (ClampMin = "0", ClampMax = "8", EditCondition = "bEnableVSM", EditConditionHides))
319 int32 VSMBlurRadius = 2;
320
321 /** Shadow depth bias to prevent shadow acne. */
322 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Shadows | External", meta = (ClampMin = "0.0", ClampMax = "100.0", EditCondition = "bShowAdvancedOptions", EditConditionHides))
323 float ShadowDepthBias = 1.0f;
324
325 /** Include skeletal meshes (characters) in shadow capture. */
326 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Shadows | External", meta = (EditCondition = "bShowAdvancedOptions", EditConditionHides))
327 bool bCaptureSkeletalMeshes = false;
328
329 /** Log/Linear cascade split blend (0=linear, 1=logarithmic). */
330 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Shadows | External", meta = (ClampMin = "0.0", ClampMax = "1.0", EditCondition = "bShowAdvancedOptions", EditConditionHides))
331 float CascadeLogLinearBlend = 0.85f;
332
333 /** Blend region at cascade boundaries (0-0.3). */
334 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Shadows | External", meta = (ClampMin = "0.0", ClampMax = "0.3", EditCondition = "bShowAdvancedOptions", EditConditionHides))
335 float CascadeBlendRange = 0.1f;
336
337 /** Minimum variance for VSM to prevent artifacts. */
338 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Shadows | External", meta = (ClampMin = "0.01", ClampMax = "100.0", EditCondition = "bShowAdvancedOptions && bEnableVSM", EditConditionHides))
339 float VSMMinVariance = 1.0f;
340
341 /** VSM light bleeding reduction (0=none). */
342 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Shadows | External", meta = (ClampMin = "0.0", ClampMax = "0.5", EditCondition = "bShowAdvancedOptions && bEnableVSM", EditConditionHides))
343 float VSMLightBleedingReduction = 0.2f;
344
345 // TODO: Priority Update system disabled - causes shadow flickering due to texel snapping
346 // synchronization issues. Properties kept for serialization compatibility.
347 // See IVSmokeCSMRenderer::UpdateCascadePriorities for details.
348
349 UPROPERTY()
350 bool bEnablePriorityUpdate = false;
351
352 UPROPERTY()
353 int32 NearCascadeUpdateInterval = 1;
354
355 UPROPERTY()
356 int32 FarCascadeUpdateInterval = 4;
357
358 //~==============================================================================
359 // Post Processing (Voxel FXAA)
360
361 /** FXAA maximum edge search distance. */
362 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | PostProcessing", meta = (ClampMin = "0.0", ClampMax = "4.0", EditCondition = "bShowAdvancedOptions", EditConditionHides))
363 float FXAASpanMax = 4.0f;
364
365 /** FXAA edge detection threshold range. */
366 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | PostProcessing", meta = (ClampMin = "0.0", ClampMax = "8.0", EditCondition = "bShowAdvancedOptions", EditConditionHides))
367 float FXAARange = 1.2f;
368
369 /** FXAA sharpness factor. */
370 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | PostProcessing", meta = (ClampMin = "0.1", ClampMax = "8.0", EditCondition = "bShowAdvancedOptions", EditConditionHides))
371 float FXAASharpness = 1.7f;
372
373 //~==============================================================================
374 // Rendering
375
376 /** Smoke visual material data asset. */
377 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Rendering")
378 FSoftObjectPath SmokeVisualMaterialPreset;
379
380 /** Write smoke depth to scene depth buffer for correct translucent sorting.
381 * When enabled, particles behind opaque smoke regions are correctly occluded. */
382 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Rendering",
383 meta = (EditCondition = "bShowAdvancedOptions", EditConditionHides))
384 bool bEnableDepthWrite = true;
385
386 /** Depth bias in centimeters. Positive values push depth further from camera. */
387 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Rendering",
388 meta = (ClampMin = "0.0", ClampMax = "100.0", EditCondition = "bShowAdvancedOptions && bEnableDepthWrite", EditConditionHides))
389 float DepthWriteBias = 50.0f;
390
391 /** Alpha threshold for depth write. Only pixels with alpha >= this value write to depth buffer.
392 * Lower values include more semi-transparent areas, higher values only include nearly opaque areas. */
393 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Rendering",
394 meta = (ClampMin = "0.01", ClampMax = "0.99", EditCondition = "bShowAdvancedOptions && bEnableDepthWrite", EditConditionHides))
395 float DepthWriteAlphaThreshold = 0.99f;
396
397 //~==============================================================================
398 // Debug
399
400 /** Show debug visualization for smoke volumes. */
401 UPROPERTY(Config, EditAnywhere, BlueprintReadOnly, Category = "IVSmoke | Debug")
402 bool bShowDebugVolumes = false;
403
404
405private:
406
407 /** Cached smoke visual material preset. */
408 UIVSmokeVisualMaterialPreset* CachedVisualMaterialPreset;
409};