6
$\begingroup$

I am using array modifier on an object with, say, Brick texture that uses UV map. I try to get a different layout of bricks for object instances but no matter what I use (e.g. Object Info's Location or even Random) the texture shows up on all objects in the same way as on the first one.

Here is an example material I'm trying to use, note attempted use of Object Info's randomness to have a different bricks layout:

enter image description here

I can achieve the desired effect by dropping array modifier and duplicating the object (and applying location if I use Object's Info Location to randomize brick texture) but that's not very convenient when there is a lot of objects I need to duplicate.

I think the above could be done using geometry nodes albeit I don't have 100% working solution right now.

I wonder if what I'm trying to achieve is possible while still using array modifier.

Here is an example blend file: column of objects on the left hand side was created using duplication, a column of objects in the center was created using array modifier - note that each object in the center has exact same bricks layout:

$\endgroup$
2
  • 1
    $\begingroup$ You might also want to look at the possible uses of the Array modifier's UV > 'Offset UV' settings: blender.stackexchange.com/a/168747/35559 $\endgroup$
    – Robin Betts
    Sep 2, 2023 at 7:41
  • $\begingroup$ Thank you, Robin! $\endgroup$
    – J. A.
    Sep 3, 2023 at 5:43

3 Answers 3

6
$\begingroup$

You can achieve this by using Random per Island instead of Random. However, if your mesh already has multiple islands, each of these will get an individual random number. An island is basically a loose part, i.e. a cube welded shut is one island, while if you split all its edges, each face will be an island. Random gives one single random number for the entire object. Random per Island is located under Input -> Geometry.

Result of using Random per Island

$\endgroup$
5
  • $\begingroup$ Thank you! I tried to use it as follows, almost identical to your example (I tried scaling random value before adding), but it doesn't seem to work: i.stack.imgur.com/4sBl3.png - note column of cubes in the center and still the same brick pattern for each object in the column. $\endgroup$
    – J. A.
    Sep 2, 2023 at 3:59
  • 1
    $\begingroup$ @J.A. Apparently in this case, as in many others, there's a difference between Cycles and Eevee. I just downloaded your file, and tested both Cycles and Eevee, and in Cycles it does work. It would appear that Eevee either doesn't use Random per Island, or evaluates it before the modifer. I hardly ever use Eevee, and I'm at a loss. $\endgroup$ Sep 2, 2023 at 4:17
  • 1
    $\begingroup$ Yep, double checked this and indeed it works fine in Cycles, that should be fine for my case. Thank you! $\endgroup$
    – J. A.
    Sep 2, 2023 at 5:13
  • 1
    $\begingroup$ @J.A. Please see blender.stackexchange.com/questions/258449/… $\endgroup$
    – Gorgious
    Sep 2, 2023 at 7:35
  • 1
    $\begingroup$ That too seems like a very easy solution. Thank you for sharing @Gorgious $\endgroup$
    – J. A.
    Sep 3, 2023 at 5:33
4
$\begingroup$

A solution that also works in Eevee is to store the total face count before the array modifier using Geometry Nodes:

Geo nodes before array modifier

And then, with another Geometry Nodes after the array modifier, calculate the instance index of each face and store it as a named attribute:

Geo nodes after array modifier

In the materials, use an Attribute node to get the named attribute:

shader nodes $$$$ You can use a Random value node to get a random value for each id, or maybe do some more complex operation, before sending the value to the shader.

random vector geo nodes after array modifier shader nodes using random vector

$\endgroup$
4
$\begingroup$

Here's a method, not using GN, that works even when arraying objects with multiple mesh islands, in Eevee or in Cycles:

enter image description here

I've added an additional UV map where I've scaled all the UV to a single point. I use a UV offset on the array modifier. This won't affect a tiling texture image, since it offsets by the exact tile amount, but when used as the input to a noise texture, it provides a unique seed for every instance of the array.

Here, I'm using that to assign a unique hue to each circle, but you're free to use that value however you'd like.

There is a situation where this is not appropriate, which is when you want to use textures on clip or extend border modes. That's usually fixable with a bit of vector math on your coordinates (but it can affect mipmapping if borders are small.) I guess it wouldn't be appropriate if you don't have a UV map to spare either-- Blender only permits so many of them.

Something similar is doable in GN, but it's not any simpler. When I can, I avoid GN to preserve vertex groups.

$\endgroup$
2
  • $\begingroup$ Do you really need a separate UV Map? You could just floor the coordinate that is offset in the Array Modifier. And Geometry Nodes already do preserve vertex groups in 3.6 (maybe earlier, not sure when exactly this was fixed) i.imgur.com/CPdX7ja.gif (well with constructive geometry it doesn't i.imgur.com/lQ5iN8Z.png though you can use my trick blender.stackexchange.com/a/275405/60486) $\endgroup$ Sep 5, 2023 at 7:58
  • 1
    $\begingroup$ @MarkusvonBroady Floor would work in most situations, not all (UV can be bigger than 0,1.) Can still use math, with a big enough offset, but precision is at risk, and it's more complicated, more work, than add UV. I expect that somebody doing an array in GN is going to do it by constructing geo. Hadn't seen that workaround, thanks for link! $\endgroup$
    – Nathan
    Sep 5, 2023 at 14:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .