how can i seed random material values by object?

sometimes with material shaders, i need to produce a random value that is constant per-object, but different across different objects. for instance- maybe i want to have a material that randomly changes color for each object, so that many objects with the same material are all slightly different BUT over time, each of the objects stays the same color that it started.

the way that i usually do this is by using the object world location as a seed, since each different object will be in a different location. the problem is that then those objects can’t move, or their color will change.

is there a better parameter i can use here to randomly seed by object? ideally there would be some kind of integer called like ‘object id’ that is just a fixed number passed into the material to tell it which object it is in the scene. does this exist, what else could i use to seed random values by object?

If you’re using Instanced or Hierarchical Instanced Static Mesh components to populate your objects you can use the PerInstanceRandom material node to have the system generate a random value between 0.0-1.0 that can then be leveraged.

Alternately you can have a blueprint generate a random value that’s passed to each objects material instance as a parameter. (Can be seed based or not)

Either way, to make life easier you can create two material functions like the image below that will allow you to use that random number more effectively. (My functions are for scalar values, but they could be adapted for float3 values)

The top function uses the random value, a target value, and a deviation [<1.0 smaller, >1.0 is larger] value to generate an output that randomly deviates from the target value by up to the specified deviation percentage.

The bottom function uses the random value (misnamed as Input Percentage) to select from within a range. (Basically a lerp now that I think about it…)

1 Like

this is basically what i’m looking for, but is there an equivalent for things that aren’t instances? like just regular objects in the scene?

i considered passing in random values manually but wouldn’t that mean i’d have to create a new material instance for each object? that seems inefficient.

I haven’t looked into using this on non-instanced objects yet but had the same thought.

To my limited understanding you’d create and apply the material instance at runtime in Blueprints so there’s be some inefficiencies, but not terrible. Whether they’d be enough to affect FPS would require a test scene and some profiling to evaluate the tradeoff.