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
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:
Create a MaterialParameterCollection Asset in the Unreal Editor
Add a specific number of elements to the Array (like 10, 20, 128, 256âŚ)
Get this Asset in code by using ConstructorHelpers:
static ConstructorHelpers::FObjectFinder MaterialParamCollection(TEXT(âMaterialParameterCollectionâ/Game/Materials/EchoCollection.EchoCollectionââ));
//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;
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.
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.
I got this method working ( the vector array inside the MPC) but I found it to be prohibitively expensive. MPCs support up to 1024 array elements but on a 3090 I found that my GPU time was spiking into the 20-30ms range when I tried iterating more than a couple hundred. This cost scales per pixel as well, so the more of your screen that is taken up by shaders implementing this function, the worse off you are.
Yes, generally they are b/c the cost is multiplicative vs the number of pixels that have to run that code. You can pay for it, sure, and you surely will, but was it worth it?
As for the root-question: how to use multiple, external-values in a material (typically in an array)?
Material Parameter Collection (MPC) : this exists as a 1024 scalar + 1024 4vec value bundle, as a distinct-object. a given material can reference 2 of these. the MPC-values can be set in C/Blueprints. The cost to use X of these scales with X, like any other variables you might be usingâŚ
Material Instance Dynamic (MID): you expose scalar/4vec values as parameters in the material and then set them directly in the particular material-instance(s) for that/those thing(s) are applied-to. So far as I know this is a slower-path (peanut-gallery, confirm?)
FYI, you can also use Texture Arrays in a material and you can save yourself samplers/slots since you pick X out of a list vs using a sampler for every texture.
If you are going to loop through a bunch of vectors in a shader, it probably makes sense to encode those values into a texture if possible. This will allow the GPU to sample the values relatively efficiently during each loop since all of the data will be on the GPU and memory with minimal back and forth between the CPU.
This is partially how a technique like Parallax Occlusion Mapping can loop hundreds of times without taking 30ms (although itâs still best to keep loops to a minimum).