# How can I stop scaling instances based on their surface proximity?

I have been trying to make a procedural bubble generator where the instanced spheres wouldn't intersect.

Obviously, the issue is basing their scaling on something other than the mutual distance of the points upon which they are instanced so as to get some nice distribution of the bubbles while keeping them from intersecting. Non-linear, contextual scaling, if you will. So, for the first time in my life, I tried simulation/repeat zone to get an iterative process where I would keep scaling the sphere from a small size until they would approach each other closely enough and stopped scaling.

Now, the problem there is, how do you get the points of the realized instances and still scale the instances as instances? In other words, how do you get the proximity of points on each sphere and stop them from scaling the instances based on that?

I tried coming up with something like running a check whether an index of a point on a realized sphere belongs to the same mesh island (the same sphere) and then sample the nearest surface (geometry proximity) of another sphere but I got lost and couldn't figure it out.

The goal is to somehow fill the volume in between the spheres more fully. I am adding a reference image by Raw&Rendered, which is what I was going for, but in geonodes and without a rigid body sim.

How would you approach this? What nodes specifically will get me the check of the proximity of a surface of an instanced sphere (or realized spheres, plural) and affect the scaling on each instanced sphere?

• no need to use a simulation zone for spheres, a sphere radius is simply half the distance to the nearest sphere's center. So for each point, use "index of nearest" to find the nearest (other) point, use Vector Math: Distance to find the distance to it, and set it as scale when instancing r=0.5 icospheres on the points. Commented Nov 27, 2023 at 21:59
• Hey, thanks, I get that and I have done that, the problem is scaling the spheres when they are not uniform in scale initially. Commented Nov 27, 2023 at 22:18

Despite Markus comment is quite right, It makes spheres smaller and increase gaps between, makes spheres appear rarefied. So I made this setup, that's moves spheres if they overlap:

The main loop goes through all elements and compare distance between and 2 radius (scale) combined. If distance less than two radii, it moves in opposite direction at this range.

After moving, the sphere still can overlap with another one, so a second repeat zone is used to make additional quality steps

Quality steps animation:

# There are clarifications on your questions:

First, what is the point of the math done before the Volume Cube node.

This setup sets initial positions of spheres. It instances them in a given radius using volume cube. Moreover, the density increases toward the center of the sphere. Volume cube must be same size as radius of sphere inside, so coordinates should be (-R,-R,-R) - "min" and (R,R,R) - "max"

Secondly, how exactly does the power math node into scale instance affect the repeat zone operation?

Power math node affects initial scale of spheres. It makes the appearance of small spheres more likely.

If I follow the logic correctly, you are running an Index offset capturing each element's position and scale each loop.

You are right

Does the position and the instance scale node refer to the previous loop?

No, for these fields are used. The outer loop just refines the output by doing several iterations. Field has every sphere instance inside.

What function do the two subtract nodes have in your main loop? Why do we have to normalize whatever comes from the vector subtract node?

These three nodes calculates distance between the current sphere in loop and every other sphere. As you see, connection after sample index is solid, that indicates that it has only one value, instead of field. And this one value has a position of the sphere with current index in the loop. So we have the distance between current sphere and others.

Then I have distance and radii, I can compare them, and if they are closer than the sum of the 2 radii, then the sphere must be moved by the difference of these values, which is calculated by subtraction:

But in which direction the sphere should be shifted?

I calculate the direction vector by subtraction one vector from another. Direction vector have the length of distance between spheres, but it should have the length that we have calculated in previous step. So the direction vector is normalized (to set distance at 1) and multiplied by the distance from the previous step.

The not equal bolean with index input means that u don't look at the current object in its loop, right?

Yes, since the distance between same sphere will be 0, we should skip it

The overall logic being you displace the spheres and scale them in and out by distance?

No, the opposite. Scale spheres and move them if they intersect. This makes sphere appear close to each other.

• That's interesting, thank you! I am going to have a look at it tomorrow. Commented Nov 27, 2023 at 22:28
• Thank you for your file. I am still confused, not a math person and a beginner... Sorry, Would you mind clarifying a few things in your nodetree? First, what is the point of the math done before the Volume Cube node. Secondly, how exactly does the power math node into scale instance affect the repeat zone operation? I tried turning it off and it effect seemed to stop working. Commented Nov 27, 2023 at 23:33
• And the third and the most important question: If I follow the logic correctly, you are running an Index offset capturing each element's position and scale each loop. Does the position and the instance scale node refer to the previous loop? What function do the two subtract nodes have in your main loop? Why do we have to normalize whatever comes from the vector subtract node? The not equal bolean with index input means that u don't look at the current object in its loop, right? .... The overall logic being you displace the spheres and scale them in and out by distance? Thx. Commented Nov 27, 2023 at 23:36
• @AdamŠimek I've updated the answer Commented Nov 28, 2023 at 9:24
• Thank you very much, I think I get it now. Very smart. Have a good one! Commented Nov 28, 2023 at 19:56