I'm a beginner, still learning Geometry nodes so forgive me if my explanation isn't the clearest! How to make these scattered points adhere moving and rotating on any model's surface? I've tried many methods, but none seem to work!

enter image description here

enter image description here

  • $\begingroup$ search Erindale on yt - he made a tutorial in GN for that. $\endgroup$
    – Chris
    Commented Sep 23, 2023 at 14:02

1 Answer 1


This can be done… I'll describe the algorithm, as I don't have the time to build the node tree:

  1. Generate your geometry, use UV Unwrap node, make sure UV islands are separated with a margin greater than the velocity of particles.
  2. Split Edges. You don't really have to, but it makes the algorithm simpler (no need to translate between face corner and point domain), so start with that.
  3. Distribute Points on Faces and pass them to a Simulation Zone.
  4. Store Named Attribute directions in the point domain, which are random vectors in range $<-0.01, -0.01, 0> … <+0.01, +0.01, 0>$, you can normalize them. Alternatively you could set all directions to the same vector to have a consistent herd/flock movement. Remember the values have to be small, because you will operate in UV space $0..1$ - with the values suggested it takes between 100 and 142 frames for a point to travel across the biggest possible UV island.
  5. Pass that geometry to a simulation zone.

In Simulation Zone:

  1. Use two Named Attribute nodes to add together UVMap and directions.
  2. Pass the result to Sample UV Surface, using Position field. If you get a valid output, that's it, use Set Position node to update the position, and Store Named Attribute to update the UV to the vector calculated in p. 5.
  3. If you don't get a valid output, things get complicated… (use a switch that based on Sample UV Surface: Is Valid output, either uses the calculated data, or another branch of nodes)

Things get complicated:

  1. Find Nearest Edge. Check how many neighbors (faces) it has. If only 1, it's an actual geometric boundary, and decide what to do: disappear? Stop? Bounce? For bouncing, just do p.5. but subtract directions instead of adding them. Now the Position from Sample UV Surface has an offset in the opposite direction.
  2. IF there's 2 neighbors, you also calculate the position as if you were bouncing, but don't actually set that as your position. Instead, calculate the offset to the new position - subtract from 'new position' the current position (Position node), and reverse it (Vector Math: Scale -1).
  3. Divide this offset to two parts - one towards the nearest edge, and the rest.
  4. Rotate "the rest" around the axis defined by the nearest edge, by the angle being this edge's angle.
  5. Add the two parts back together, add that to current position, Sample Nearest Surface at that position to find the UVMap attribute value there.
  6. You should know what do do now, you have your UV, so Sample UV to get position (yes you already have it, but it's only an estimate and this should avoid some 1-frame-jerks across boundaries), and update your position and UV.

Points 1 to 7:


You must log in to answer this question.

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