Hello friends,
I’m trying to create a new custom material expression that acts as switch node but lerps between colors/values and the node can take as many inputs as I need by adding + Add button that adds inputs in an array.

The class in C++ inherits from UMaterialExpression same as switch node and I saw I should override compile function. I did that but I saw there is no change in the material output and I just get 0 for no reason I tried to copy paste the switch node compile function into Palette compile function but same no change I don’t understand why and how.
// MaterialExpression.h
USTRUCT()
struct FPaletteCustomInput {
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere, Category = CustomInput)
FName InputName;
UPROPERTY()
FExpressionInput Input;
};
/**
*
*/
UCLASS(collapsecategories, hidecategories = Object, MinimalAPI)
class UMaterialExpressionPalette : public UMaterialExpression {
GENERATED_UCLASS_BODY()
UPROPERTY(EditAnywhere, Category = UMaterialExpressionPalette)
FString Description;
UPROPERTY(meta = (RequiredInput = "false", ToolTip = "Defaults to 'ConstAlpha' if not specified"))
FExpressionInput Alpha;
UPROPERTY(EditAnywhere, Category = UMaterialExpressionPalette, meta = (OverridingInputProperty = "Alpha"))
float ConstAlpha;
UPROPERTY(EditAnywhere, Category = UMaterialExpressionPalette)
TArray<struct FPaletteCustomInput> Inputs;
#if WITH_EDITOR
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
void RebuildOutputs();
#endif // WITH_EDITOR
virtual void Serialize(FStructuredArchive::FRecord Record) override;
////~ End UObject Interface.
//~ Begin UMaterialExpression Interface
#if WITH_EDITOR
virtual int32 Compile(class FMaterialCompiler* Compiler, int32 OutputIndex) override;
virtual void GetCaption(TArray<FString>& OutCaptions) const override;
virtual FText GetCreationName() const override { return FText::FromString(TEXT("Palette")); }
virtual TArrayView<FExpressionInput*> GetInputsView() override;
virtual FExpressionInput* GetInput(int32 InputIndex) override;
virtual FName GetInputName(int32 InputIndex) const override;
virtual uint32 GetInputType(int32 InputIndex) override { return MCT_Float3; }
#endif // WITH_EDITOR
//~ End UMaterialExpression Interface
};
// UMaterialExpression.cpp
int32 UMaterialExpressionPalette::Compile(FMaterialCompiler* Compiler, int32 OutputIndex) {
TArray<int32> CompiledInputs;
uint32 Value = this->Alpha.Compile(Compiler), Default = Compiler->Constant(0.0);
for (int32 i = 0; i < Inputs.Num(); i++)
{
if (!Inputs[i].Input.GetTracedInput().Expression)
{
return Compiler->Errorf(TEXT("Texture Multiplexer missing input %d (%s)"), i + 1, *Inputs[i].InputName.ToString());
}
int32 InputCode = Inputs[i].Input.Compile(Compiler);
if (InputCode < 0)
{
return InputCode;
}
CompiledInputs.Add(InputCode);
}
return Compiler->Switch(Value, Default, CompiledInputs);
for now I tried to use switch node logic but still no change, and even though I can’t implement the lerping logic here because in the code below it shows that I need to get alpha value as floating point and the only way I can is overriding the value of alpha variable through UPROPERTY which is not ideal because I can’t use a texture to use it as alpha and I want the expression to work with textures as well as the switch node does so I can have an output like this.
// Native C++
struct Color {
float R, G, B;
Color operator+(Color Other) {
return Color(R + Other.R, G + Other.G, B + Other.B);
}
Color operator-(Color Other) {
return Color(R - Other.R, G - Other.G, B - Other.B);
}
Color operator*(float Alpha) {
return Color(R * Alpha, G * Alpha, B * Alpha);
}
};
Color Lerp(Color A, Color B, float Alpha) {
return Color(A + ((B - A) * Alpha));
}
Color ColorPalette(const std::vector<Color>& Colors, float Alpha) {
if (Colors.size() == 1 || Alpha <= 0) {
return Colors.front();
}
if (Alpha >= 1) {
return Colors.back();
}
float ScaledAlpha = Alpha * (Colors.size() - 1);
int Index = ScaledAlpha;
float A = ScaledAlpha - Index;
return Lerp(Colors[Index], Colors[Index + 1], A);
}
I want to know if I’m missing something i tried even to modify the source code in the following files:
MaterialCompiler.h
HLSLMaterialTranslator.h/.cpp
but still nothing seems to work.
Thanks