Using Arrays in Materials

Hey guys,

I try to export a Material I wrote in Unity to Unreal.
Unfortunately I cannot find a way to loop through Arrays in Materials.

What I know so far:

  • I can create custom expressions to use a for-loop
    • Problem: There are no arrays which I can loop
  • There are Material Parameter Collection Assets, which store a Scalar and a Vector Array
    - Problem: I cannot get the Collection Arrays in the custom expressions. Its weird, because the generated
    HLSL code uses MaterialCollection0.Vectors[0]. But the Compiler doesnt recognize
    MaterialCollection0, when I try to apply the changes
  • I can use Textures to store data and loop through it
    - Problem: I tried to manipulate the data of a Texture2D and set a texture parameter value to it, but it didnt work.
    Maybe I overlooked something with this attempt.

It would be awesome if someone could help me with my problem :slight_smile:

Thanks in advance for you answers

Greetings

I’m working on a similar issue, and it appears that we have to use a Blueprint instead of being able to do it just in the Material.

It would be really nice to be able to cycle through, say Emissive Color masks in the Material, though.

I solved it with Material Parameter Collections.
Actually they can only be read if at least one Parameter is set as an input for your custom expression.
If you need further informations I can provide them

I have been trying to use array in material editor. Do you think I can populate my array via code ? or even more using user defined struct as an array?

Unfortunately I didnt find a way to send custom structs to the shader.
I used MaterialParameterCollection to send specific data via code to my Material.

To do this:

  1. Create a MaterialParameterCollection Asset in the Unreal Editor

  2. Add a specific number of elements to the Array (like 10, 20, 128, 256…)

  3. Get this Asset in code by using ConstructorHelpers:
    static ConstructorHelpers::FObjectFinder MaterialParamCollection(TEXT(“MaterialParameterCollection’/Game/Materials/EchoCollection.EchoCollection’”));

  4. Next is to fill the MaterialParameterCollection:

    FCollectionVectorParameter VectorParam;
    VectorParam.DefaultValue = FLinearColor(1, 0, 0);

    //Generate any Name to find this Parameter in you Collection
    FString Name = FString(“Index_”) + FString::FromInt(index) + FString(“_”);
    VectorParam.ParameterName = *Name;

    // This line and the line below should not be different. I dont know anymore why I chose to do this twice :P. Maybe there is a difference
    ParameterCollection->VectorParameters[index++] = VectorParam;

    UKismetMaterialLibrary::SetVectorParameterValue(GetWorld(), ParameterCollection, VectorParam.ParameterName, VectorParam.DefaultValue);

    //The same procedure goes for FCollectionScalarParameter

To actually iterate through this array you have to write custom expression code in your materials

!!!Warning!!! You have to use one Vector or Scalar Parameter from the Collection as an Input. Otherwise the shader doesnt know your collection

for(int i = 0; i < NumberOfParams; ++i)
{
    float4 VectorParam = MaterialCollection0.Vectors[i];
    //Do something...
}

This should be it :slight_smile:

3 Likes

Hi McStrife,

Sorry, for unearthing this. Would you please be able to provide a HLSL code extract for accessing individual floats in an input float array? I am trying to do something with HLSL and the custom nodes, but its all new, and I cannot access individual array values properlly.

Cheers,
Ben.

hey sorry to revive this old thread, but it was the only “almost” answer i found.
Just one thing: using float4 VectorParam = MaterialCollection0.Vectors[i]; trows an error in UE4
Invalid Subscript Vectors
If i leave it out my custom node complains that the input (a Material Parameters Collection) is not an array, so it can’t be indexed…
What is the proper way to iterate through a MPC parameters?

I tried the Material Parameter Collections solution, but was not able to get it fully working.

MaterialCollection0.Vectors[i] was available and partly worked, but I did not find any way to access a scalar value. Does anyone have an Idea how to access a scalar in the code for the custom node?
MaterialCollection0.Scalars[i] did not work.

The second problem I encountered was that while it actually worked with Vectors, the input did not update when the MPC value was changed. It just used the value that was set as default in the MPC.

A solution for these 2 problems would be amazing!

All Scalar parameter are stored as Vectors in front of Vector parameter ,you can use debug node to show the vector values.