I'm trying to use an attribute generated from an instance position to affect the geometry of the instances. For example with the below setup, let's say I want to shift just the 4 top vertices of each cube, along the x-axis, by the amount given by the noise texture. Is it possible to use the noise texture value after realizing the geometry, or modifying the geometry in some other way?
3 Answers
This problem has come up in a variety of guises: 'How do we get a per-instance attribute into realized geometry?' If you want a per-instance color, deformation, or anything else, the route isn't obvious.
The hitch in Geometry Nodes at the moment is that there is nowhere on an unrealized instance to store an attribute. This looks as if it's going to change; there may be an 'Instance' domain coming to the Capture Attribute node in Blender 3.1. At the time of writing, it doesn't yet work.
Edit: At 29 Dec 2021, in Blender 3.1 alpha, the 'Instance' domain is available and working. It makes the following hack unnecessary. See @qullenform's answer, instead.
If the instances are small enough, and don't overlap, you can often get away with direct transfer of an attribute to geometry by its vertex-proximity to the points on which the instances were generated, as shown in @Harisreedhar 's answer
If not, though, for now, you can employ some variation of this hack:
- Make a parallel branch of your tree, in which instances are scaled to 0 before being realized.
- Transfer the attribute to the scale-0 realized instances by proximity ('Nearest').
- Transfer the attribute back to the full-sized geometry by Index.
This makes the difference between the case on the left, below, (where the attribute is interpolated across vertices,) and the case on the right, (where the attribute is picked up per-instance).
- 1$\begingroup$ That's a nice trick +1 $\endgroup$Harisreedhar– Harisreedhar2021-12-13 13:48:34 +00:00Commented Dec 13, 2021 at 13:48
- $\begingroup$ The T.A. node on the right doesn't have anything connected to
Indexsocket, but it still is fed an index just like texture nodes in shaders are fed coordinates even if a vector is unconnected? I only just started learning geonodes so some rearranging my neurons hurt, like why two T.A. nodes are needed? Why the noise texture? I thought I connect an attribute I want to get from a given geometry, apparently that's not how it works 🤔 $\endgroup$Markus von Broady– Markus von Broady2021-12-14 21:40:26 +00:00Commented Dec 14, 2021 at 21:40 - 1$\begingroup$ @MarkusvonBroady That one made my neurons hurt, too. I have to confess, I found it only as the result of exhaustively stripping out as many nodes as possible. It's the first TA I find confusing, not the second. The second one is OK. It transfers from the target (the realized instances at scale 0) to the first geometry encountered on its little forward branch ( full-sized geo in the Set Position ,) using 'Index' as the key to match by ..(as opposed to 'Nearest', etc). It is not transferring 'Index'. It is transferring the 'Fac' from the texture it picked up earlier, by 'Index'. $\endgroup$Robin Betts– Robin Betts2021-12-14 22:41:56 +00:00Commented Dec 14, 2021 at 22:41
- $\begingroup$ @MarkusvonBroady Ahh I see what you mean.. The 'Index' input to the TA defaults to the index you see in the left-column you see in the spreadsheet. You could replace it with a roll-your own 'ID' or any other integer. $\endgroup$Robin Betts– Robin Betts2021-12-14 22:46:44 +00:00Commented Dec 14, 2021 at 22:46
In Blender 3.1+ there is the possibility to capture an attribute in the Instance domain, which makes various hacks superfluous.
Additionally, it is recommended to use a specific vertex group previously created as Group Input as Selection.
This selection is simply used as an input in the node Set Position.
Of course, the vertex group can also be used directly during instantiation in the Instance on Points node, depending on what result you want.
Why a vertex group instead of a mathematical solution?
If you want to instantiate different objects from a collection, you only need to create a vertex group in these objects with the identifier you chose before and define which points should be modified. This makes the selection easier to handle and less prone to errors.
To make a vertex group available in geometry nodes, simply create an Input of type Boolean, and specify the identifier of the vertex group.
- $\begingroup$ I see... On realizing instances, the attributes on the instances get copied to all elements of resulting geometry. $\endgroup$Markus von Broady– Markus von Broady2022-05-10 12:57:26 +00:00Commented May 10, 2022 at 12:57
- $\begingroup$ @MarkusvonBroady Yes, and as long as the instance is not realized, it is treated as a point that is assigned exactly one value from the texture node. $\endgroup$2022-05-10 13:01:53 +00:00Commented May 10, 2022 at 13:01
- $\begingroup$ Can this technique be used to capture the texture color of an emitter mesh so that each instance receives the color from the area it was emitted from? (Something like this, except using GN instead of a particle system.) $\endgroup$Mentalist– Mentalist2022-05-18 08:42:08 +00:00Commented May 18, 2022 at 8:42
- $\begingroup$ @Mentalist I am sure that an interesting answer can be found if you post this here as a separate question. $\endgroup$2022-05-18 09:21:13 +00:00Commented May 18, 2022 at 9:21
- 1$\begingroup$ @Vikas Yes, in this setup Capture Attribute is indeed necessary, because only then each of the four upper points of each object gets the same position. If you would not use the node, every single point would get a different position, because after realizing the instances the node Set Position works in the point domain. $\endgroup$2024-09-21 20:26:52 +00:00Commented Sep 21, 2024 at 20:26







