3
$\begingroup$

Using cycles nodes, how do I create a parametric n-sided star?enter image description here

I've seen Procedural Star Texture in Blender Cycles, but somehow I feel duplicating node groups and manually typing in the rotation is not the way to go. I'm fairly certain there's a more elegant way to do this but the math involved simply eludes me.


Early attempts: Ideally, this would be it, except the arrows are pointing in the wrong direction! :)

enter image description here


UPDATE: Following formulas from Wolfram, I've managed to come up with this: enter image description hereI have no idea if I did it correctly but I've made a pentagram, so at least something in there was correct. However, similar to the tutorial linked above this solution is not very elegant either, requiring me to duplicate the node group and typing in a rotation value per segment/spoke.

I'm hoping one of you blender math heads out there could help me. Thank you!

$\endgroup$
  • $\begingroup$ Just an idea: testing if the point is in a triangle + given a point angle (from the center), take a modulo of this angle (the angle module 2pi/n or something like that). So, the n triangles are seen as one whatever the amount of triangles is. $\endgroup$ – lemon Jul 18 at 17:27
  • $\begingroup$ What you can also do, is make it semi procedural. When this modulo trick is done (see prev. comment), just test if the vertex correspond to a white or black part of a texture. The texture may be one triangle here, and can be scaled to make its base vary. But doing so you'll be able to draw any shape (depending on what is on the texture). So the math are really simplified doing that. $\endgroup$ – lemon Jul 18 at 17:45
  • $\begingroup$ This would be part of a larger procedural texture, so I don't think making edits with the mesh would be a good way to go. This needs to be 100% procedural. Perhaps you could provide an answer with references/images to elaborate your initial comment. Thank you! $\endgroup$ – Rey Leonard Amorato Jul 18 at 18:04
4
$\begingroup$

I've started with the idea that we can have 5 parameters to do it.

  • The amount of stars to display: a scale effect along the surface.
  • The orientation of the star: turning it around its center.
  • The amount of branches.
  • The branch length.
  • The base width: how thin the branch is.

Globally, I think the main thing to consider to draw on a rendered surface (for Eevee or Cycles) is that the engine drives each raycast and so we can only "rearrange" the coordinates we receive so that it fits to our need. And "fit to our need" means driving this coordinate to a wanted color, texture or shader.

For instance, if we want to scale the figure, the idea is to multiply the given coordinates by a value (this is node by VectorMultiply node group in the blend file below, which simply multiplies X, Y and Z by a given value).

enter image description here

From that and more directly about the star subject, the idea is to test if a given point corresponds to a given triangle which is the half of a branch:

enter image description here

And if we know that our coordinates are positives, a point P(x,y) is inside the triangle if x + y < 1, or more precisely if the triangle we want is of dimensions A, B, then P is inside if (x/A) + (y/B) < 1.

From that, all the trick is to make any point the render engine gives to us come back in this quadrant appropriately.

enter image description here

First step, we have scaled the coordinates. That mean we no more have something between 0 and 1 (as the UV map coordinates are), but something between 0 and the scale. To have back something between 0 and 1, we can take the modulo 1 of the point coordinates. For example if the scale is twenty, will obtain a sequence of twenty intervals [0, 1[ when the render engine casts along the surface.

This is done by VectorModulo node group in the blend file (which simply takes the modulo of each coordinate of the vector).

Next to have a final quadrant (the rectangle image above) between 0 and 1, we recenter our current coordinates to a center at 0.5 and scale it by 2. This is done by the VectorRecenter node group. This last calculation gives something between -1 and 1, but will finally take only the positive quadrant below.

At this step, our point is somewhere around the center we defined above with a value between -1 and 1 and we want to know the angle it has from the X axis.

This is done by Vector2ToPolar node group which only take into accound X and Y and calculates the angle with arctan2( y, x ) because this arctangent give the good sign of the angle (and the other arctangent vector math node does not).

From this angle its easy to add a rotation so that we can turn the stars (just add a value to the previous angle).

enter image description here

Now we want an amount N of star branches. Each branch corresponds to an angle of a = 2pi / n.

And we want to know that our point is somewhere around 1 x a or 2 x a or (n - 1) x a. So we divide the current angle by a, round the obtained value and multiply it by a again. Relatively to that, our point angle become the point angle minus this previous rounded result. This is done inside the 'RoundAngleDelta' node group.

We now have two information (this last angle and the vector length) we go back to vector coordinates using the 'PolarToVector2' node group.

The point we now have fits to the half branch rectangle above, except that y could be negative. So we take the absolute value of it.

Finally we consider the last two parameters BranchLength and BaseLength so that we can apply the formula (x/BranchLength) + (y/BaseLength) < 1 (indicated (x/A) + (y/B) < 1 above).

Here are the variations for these last parameters:

enter image description here

Edit: mapping enhancement

The previous setup works well with UV maps. But it does not for "generated" or "object" coordinates inputs.

So, I've added some nodes to pre-process normal orientation so that the stars can be drawn on any orientations.

This solution is taken from this answer written by Rich Sedman

The setting in few words (as it described in the link above): given a normal input, we want to choose which pair of coordinates (X, Y or Z) will take the role of (X, Y) we need to draw the stars, so that they are drawn on every faces whatever their orientation is.

Here is the updated blend file:

$\endgroup$
  • $\begingroup$ Great answer! Simply marvelous. Thank you for the in-depth information on the process. $\endgroup$ – Rey Leonard Amorato Jul 19 at 10:59
  • 1
    $\begingroup$ Dang! Just while mine is in the works... I'll put it up anyway, when it's done :D $\endgroup$ – Robin Betts Jul 19 at 11:15
  • 1
    $\begingroup$ Looking forward to seeing it! $\endgroup$ – Rey Leonard Amorato Jul 19 at 11:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.