IVSmoke 1.0
Loading...
Searching...
No Matches
MaterialExpressionIVSmoke_TextureSample.cpp
1// Copyright (c) 2026, Team SDB. All rights reserved.
2#include "MaterialExpressionIVSmoke_TextureSample.h"
3#include "MaterialCompiler.h"
4
5#define LOCTEXT_NAMESPACE "IVSmokeMaterialExpressions"
6
7UMaterialExpressionIVSmoke_TextureSample::UMaterialExpressionIVSmoke_TextureSample()
8{
9 TextureType = EIVSmokeTextureType::SmokeColor;
10 R = true;
11 G = true;
12 B = true;
13 A = true;
14
15#if WITH_EDITORONLY_DATA
16 MenuCategories.Add(LOCTEXT("IVSmokeCategory", "IVSmoke"));
17#endif
18
19 Outputs.Reset();
20 Outputs.Add(FExpressionOutput(TEXT("Color")));
21}
22#if WITH_EDITOR
23int32 UMaterialExpressionIVSmoke_TextureSample::Compile(class FMaterialCompiler* Compiler, int32 OutputIndex)
24{
25 if (!Compiler)
26 {
27 return INDEX_NONE;
28 }
29
30 uint32 SceneTextureId = 0;
31 switch (TextureType)
32 {
33 case EIVSmokeTextureType::SmokeColor:
34 SceneTextureId = PPI_PostProcessInput0;
35 break;
36 case EIVSmokeTextureType::SmokeLocalPos:
37 SceneTextureId = PPI_PostProcessInput1;
38 break;
39 case EIVSmokeTextureType::SceneColor:
40 SceneTextureId = PPI_PostProcessInput3; // PPI_PostProcessInput3
41 break;
42 case EIVSmokeTextureType::SmokeWorldPosLinearDepth:
43 SceneTextureId = PPI_PostProcessInput4;
44 break;
45 default:
46 return Compiler->Errorf(TEXT("Invalid texture type"));
47 }
48
49 int32 UVsInput = INDEX_NONE;
50
51 if (UVs.Expression)
52 {
53 UVsInput = UVs.Compile(Compiler);
54 }
55 else
56 {
57 UVsInput = Compiler->GetViewportUV();
58
59 if (TextureType == EIVSmokeTextureType::SceneColor)
60 {
61 int32 SceneTexSize = Compiler->GetSceneTextureViewSize(PPI_PostProcessInput3, false); // InvProperty = false
62 int32 ViewportSize = Compiler->ViewProperty(MEVP_ViewSize, false);
63 int32 NormalizedUV = Compiler->Div(UVsInput, SceneTexSize);
64 UVsInput = Compiler->Mul(NormalizedUV, ViewportSize);
65 }
66 }
67 if (UVsInput == INDEX_NONE)
68 {
69 return Compiler->Errorf(TEXT("Failed to compile UV input"));
70 }
71
72 int32 SceneTextureLookup = Compiler->SceneTextureLookup(
73 UVsInput,
74 SceneTextureId,
75 false,
76 false,
77 false
78 );
79
80 if (SceneTextureLookup == INDEX_NONE)
81 {
82 return Compiler->Errorf(TEXT("Failed to sample scene texture"));
83 }
84
85 if (!R && !G && !B && !A)
86 {
87 return Compiler->Errorf(TEXT("At least one channel must be selected"));
88 }
89
90 if (R && G && B && A)
91 {
92 return SceneTextureLookup;
93 }
94
95 return Compiler->ComponentMask(SceneTextureLookup, R, G, B, A);
96}
97
98void UMaterialExpressionIVSmoke_TextureSample::GetCaption(TArray<FString>& OutCaptions) const
99{
100 FString TypeName;
101 switch (TextureType)
102 {
103 case EIVSmokeTextureType::SmokeColor:
104 TypeName = TEXT("SmokeColor");
105 break;
106 case EIVSmokeTextureType::SmokeLocalPos:
107 TypeName = TEXT("SmokeLocalPos");
108 break;
109 case EIVSmokeTextureType::SceneColor:
110 TypeName = TEXT("SceneColor");
111 break;
112 case EIVSmokeTextureType::SmokeWorldPosLinearDepth:
113 TypeName = TEXT("SmokeWorldPosLinearDepth");
114 break;
115 default:
116 TypeName = TEXT("Unknown");
117 break;
118 }
119 OutCaptions.Add(FString::Printf(TEXT("IVSmoke Sample [%s]"), *TypeName));
120}
121
122uint32 UMaterialExpressionIVSmoke_TextureSample::GetOutputType(int32 OutputIndex)
123{
124 int32 NumChannels = 0;
125 if (R) NumChannels++;
126 if (G) NumChannels++;
127 if (B) NumChannels++;
128 if (A) NumChannels++;
129
130 switch (NumChannels)
131 {
132 case 1:
133 return MCT_Float1;
134 case 2:
135 return MCT_Float2;
136 case 3:
137 return MCT_Float3;
138 case 4:
139 default:
140 return MCT_Float4;
141 }
142}
143#endif
144
145#undef LOCTEXT_NAMESPACE