Best way to assign unique materials to multiple instances of one object?

I’m modeling this OP-1 synthesizer. See those empty circular buttons on my model (first image)? Those should each have a unique decal, as seen in the photo ref (second image). In my model, those buttons are linked instances of one object. What’s the best way to assign unique textures to each of those buttons, while keeping the object data linked? My ideas:

  1. Set materials to be per object, instead of per data, using either the drop-down at the top of the Properties > Material panel, or in Blender’s preferences.

  2. Use floating transparent textures, positioned right above each button, and turn off shadow casting for these floating decal objects. (I don’t like this method, since it might might cause Z-fighting or other problems later.)

But maybe someone here has a better idea for this particular case. Thanks!

A silly trick is to use Position output of the Geometry node as the Vector input of the image texture. You then need to perfectly place the buttons.

That’s a cool trick. I played w/ it it and it seems like I still have to set each object instance’s material usage to Object, away from Data. I guess the benefit of your method is I don’t have to create unique materials for each object instance, I just use one big image in one material?

Is it possible to move or animate the overall object in this case, or does it have to stay put for this trick to work? I tried your method on a couple test cube instances, grouped them, and put a group instance of that group into my scene, then moved the group instance, but that didn’t work–the texture shifted around.Linking to an external copy of the group didn’t work correctly either.

Give each knob its own Object Pass Index, and use that info in the nodes to manipulate which part of the texture is being looked up. Here I’m using the bottom row of a dominoes image, probably simpler if you setup the lookup texture to only have a single row.

Awesome, that is some mad scientist stuff! I tried to reverse engineer your node setup by figuring out how the math worked, but I couldn’t get it completely, so I just recreated it and did some trial and error using a single-row lookup texture. I realized by accident I could get away w/ using only one Value node (texture canvas width divided by height, basically the same thing you were doing dividing 7 by 8 using two separate Value nodes).

I’m using this lookup table w/ a test pattern until I recreate all the decals. It works! YEAH! Thanks to both of you for the help, both very cool and unique solutions.

Say I wanted to make all the button objects single-user, and then merge them all into one big object. Since the texturing trick above relies on multiple object IDs, merging all objects into one object breaks the texturing. Is there an easy way to apply / expand the node setup, or do I have to make a custom UV layout from scratch in this case?

I was going to try messing with material index (moving away from object index), but I’m trying to do this in 2.8, and it doesn’t look like material index is in there yet.

Edit: eh, I can create a bunch of different copies of the button material, assign them to the buttons one by one, and use a Value node to replace the old object ID node for each unique material.