Procedural Archimedean Spirals in Blender – Part 1: creating the node group

Introduction

This is one of my favorite procedural textures, although I rarely use it. Here is a step by step tutorial describing the technique. The tutorial was prepared using 2.79b but the texture will work in any version of Blender that supports the math node.

The Archimedean Spiral

There are several kinds of spirals, each defined by its own equation. The equation for the Archimedean Spiral, in polar form is

r = a + b * theta

which makes perfect sense to a mathematician but is probably Greek to an artist. Ignore it for now.

Wikipedia describes this as

the locus of points corresponding to the locations over time of a point moving away from a fixed point with a constant speed along a line which rotates with constant angular velocity

a description that I suppose would seem natural to a physics student but is just more Greek to anyone else.

Another way of saying the Wikipedia description is to consider a record player. The locus of points is simply the groove that runs from the inside to the outside of the record. Constant angular velocity means the turntable rotates at a constant speed. For an old LP this is 33 1/3 rotations per minute. If you look straight down on the turntable you will see that the needle moves in a straight line from the edge towards the center. No matter where it is along that line, it is moving at the same speed. This is the constant speed along a line.

Preliminaries

There are two useful helper node groups. The first is a bit of coordinate geometry, the second a bit of logic. The next two subsections describe them, but you can safely skip the description and move to the following section.

Measuring Distance

Blender uses a Cartesian coordinate system to describe where points are on a surface. It takes three numbers to describe where a point is in space, but we’ll be working with a plane, so we only need two.

The distance between the origin and a point is described by the equation

D = square root(x*x + y*y)

we can express this as a procedural material using this node group

From left to right

  • Extracting X and Y:
    • The Object output of a Texture Coordinate node. This will provide the 3d coordinate of each point on the object, in arbitrary blender units. The origin of this coordinate system is the Blender origin of the object.
    • The Vector output of a Mapping node.  For this texture, the mapping node is not used and can be ignored.
    • The X and Y outputs of a Separate XYZ node
  • Calculating the distance
    • Two multiply Math nodes. These compute X*X and Y*Y
    • One add Math node. This adds the two previous results together, giving X*X + Y*Y
    • One power Math node. This extracts the square root, providing the distance.
  • Displaying the result
    • A Diffuse node. This converts the distance value into a gray level.
    • A Material node. Output the result.

Since Blender represents gray values with a number that varies from zero to one, this material will provide an output that is darker near the origin of the plane and becomes lighter the farther away from the plane the point is.

Determining if a number lies between two other numbers

Suppose we want to create a ring using the distance.  A ring would include every point that is farther away from the center than a certain distance, but no farther away than another. The math for this is

d < outer radius AND d > inner radius

We can express this as

The distance formula is now calculated using a node group and we’ve added three more columns of nodes. From left to right, the new nodes are

  • Two Value nodes. These are not strictly necessary because the values can be input directly to the next two nodes.
  • a greater than Math node and a less than Math node.  These give one if their condition is true for their inputs or zero if it is not.
  • A minimum Math node. Blender doesn’t have logic nodes and this is one of several ways to provide the AND logic. If either of its inputs are 0, then the node will give 0.  If both are 1, then the node will give 1. This is the truth table for AND.

Since 0 will display as black and 1 as white, rendering this gives a ring.

Creating a spiral

There are two ways to go about this.  One is to do more complicated math to convert the equation from polar to Cartesian form.  Another is to use a few tricks to accomplish the same thing.  We’ll take the tricky path. How this path works is left as an exercise for the mathematically inclined.

First Trick: Add a radial gradient.

We know what r is: The distance from the center. But what is theta that we use it to know which distance matters? The first thing is to add a radial gradient texture.

The radial gradient, by itself renders as

Adding it to the distance modifies this.

 It is difficult to see what this happens.  Temporarily add the nodes to determine what part of the image is in the range zero to one

The edge of the white area turns out to be a spiral, but only one complete rotation.

Second Trick: add a modulo

The second trick comes from Modular Arithmetic.  Consider time keeping.  The next hour after 12 on a 12 hour clock is not 13 but 1. Without describing the math let’s add a modulo math node

which renders as

giving us a two armed spiral.

Setting the number of arms

Add a multiply before the modulo operator. Now the texture will produce twice as many arms as that number

A value of 2 results in 4 arms

It’s inconvenient to remember to divide the number of arms we want by 2. Here’s a node group that allows us to set the number by changing the value in the value node

With the value set to 1 we get a single arm

Controlling the spacing

So far we’ve accomplished the equivalent of R = theta.  Let’s add in the constant b.  B controls how far apart the turns of the spiral are. A simple trick for doing this is to divide the X and Y coordinates by a constant.

for the value .5 this renders as

Adding limits

Suppose we wanted this pattern to fit in a ring, the way the grooves on a record do.  This is where the range calculation comes into play

There is a subtly here.  We compute the distance twice, once with the division and once without. If we used the output of the division in both cases, the limits would depend on the divisor for the ring.  This keeps them independent.  It now renders as

Setting the “width” of the groove

We have a complete node group that will generate a spiral within a ring. We control the spacing of the spiral and we can control the number of arms.  This is a complete procedural spiral.  There’s one more feature that I’ve found useful.

Look closely at the grooves.  There is a repeated pattern moving outward. The spiral itself is black, but moving outward, it ramps up to white. We can control the way that ramp happens.  We use a color ramp to do this.  In this example, a color ramp that changes the saw tooth pattern into a more symmetric one with a more gentle gradient.

This renders as 

We can add another node group that controls the falloff

rendering as

This doesn’t look any different, but if you adjust the width parameter you can change the curve. The higher the width value, the sharper the falloff, giving greater contrast.

width = .1, you can barely detect the spiral

width = 4, the fall off is much sharper.

Conclusion

We’ve created a procedural material that will generate a spiral. We refined the material, allowing us to

  • control the number of arms generated
  • control the distance covered in one rotation — the spacing
  • limit the range of the spiral to a ring of a given size
  • control the ‘falloff’ from black to white as you move a long a radius — the width

This is a useful enough material that we might turn it into a node group. Part 2 discusses one way to do that.

Procedural Circles, Rings and Linked Rings in Blender Cycles

Procedural Linked Rings

Procedural Linked Rings

A step by step guide to linking rings in Blender

There are two important parts to making linked rings in Blender: Making a ring and making it repeat. The ring requires a bit of math, but it’s not hard math. Repeating requires a different bit of math, but it’s not hard either. I’ll explain the math as I go along, but you can skip it and still learn how to use ring textures.

Drawing a circle

Remember from Cartesian geometry that a circle is all of the points that are the same distance from a given point. The distance is called the radius, and the given point the center.

The Generated output from the Texture Coordinates node encodes the X, Y, Z coordinates of a point in space. Since we’re only using a flat plane, we only care about X and Y. We can feed the Generated output into the Vector input of a Separate XYZ node and obtain those coordinates, mapped so they fit in the range of 0 to 1. If we view our plane from above, the X coordinates run along the bottom of the plane from zero on the left to 1 on the right. Because blender also uses the range of 0 to 1 for the gray scale, we can visualize this using a simple node group

X to gray mapping

A simple node group that will display the X coordinate as a gray scale running from black on the left to white on the right.

Rendering this gives up the coordinates, ranging from black as 0, to 1 as white.

gray scale

A gray scale representation of the X coordinates ranging from black as 0 to white as 1

If we take the X and Y values from the Separate XYZ and combine them properly, we will know the distance of any point on the plane from the origin, the lower left hand corner. Recall from Cartesian geometry that the distance to a point is the square root of the sum of the square of X and the square of Y, SQRT(X^2+Y^2). We calculate this with a combination of 4 math nodes. Blender doesn’t have a node to calculate the square root, but recall that the square root is the same thing as raising the sum to the 1/2 power.  (generalizing: The Nth root is the same as the 1/Nth power)

calculating distance

A node group that calculates the distance from the origin at the lower left hand corner to each point on the plane

Producing

Distance from the origin as gray scale

A gray scale showing the distance from the origin to each point on the plane

That’s an interesting blob, but we want our center at the midpoint of the plane. The formula for the distance between two points is only slightly more complicated that the one for the distance from the origin: sqrt((X1 – X0)^2 + (Y1 – Y0)^2) where (X0, Y0) is the coordinate of the center and (X1, Y1) Is the coordinate of the point.  An easy adjustment:

Calculating the distance from the center

A gray scale showing the distance each point is from the center of the plane, rather than the origin.

producing

A gray scale showing the distance each point is from the center of the plane, rather than the origin.

gray scale showing distance of a point from the center of the plane

It’s a step in the right direction. Let’s turn it into a circle, using another math node, a greater than. Now the gray scale goes from black at the center to 0 at the edge, so it’s no longer a direct match for the coordinates.  Let’s place the edge of the circle half way between the center and the edge. Since the center is at .5, half way between it and the edge will be half that or .25. The greater than node will return a 1 if the point is farther away and a 0 if it’s not. We can apply that to a Mix RGB node and produce a nice red circle on a blue field.

A red circle on a blue field

Using a greater than node to divide the plane to inside the circle and outside the circle.

Renders

A red circle on a blue field.

A red circle on a blue field.

Now to make it a ring.  Let’s use a less than math node along with the greater than. We’ll make anything that’s in the range between the two red and leave everything else blue. Blender doesn’t have logic nodes, but we want to know when the distance is less than the higher value and also greater than the lower value. To do this we use a minimum math node.  If the distance is outside the range, one or the other of the compare nodes will return 0 and the minimum will select 0.  If it’s inside the range, than both will return 1 and the minimum will select 1.

We need to make another change. For the circle, we had 0 mean outside and 1 mean inside. But for the ring we have the opposite. There are several ways to fix this.  I simply switched the two colors in the mix RGB node.

A ring ring on a blue field

A ring ring on a blue field

and we have our red ring on our blue field

A ring ring on a blue field

A ring ring on a blue field

Now we can create a ring of any width. The value in the greater than provides the inner radius of the ring, while the value in the less than provides the outer radius.

Repeating patterns

It would be nice if Blender had a tile option that would resize its input and repeat it, like the checker tile, but using the whole pattern. It doesn’t, so we fake it.  Time for our last bit of math: Modulus. We’re going to repeat the pattern by repeating the coordinates, going from 0 to 1 many times. Recall that if you divide one integer by another, the remainder is called the modulus of the number being divided. For instance 22 divided by 7 returns 3, 3 times 7 returns 21 and 22 minus 21 gives 1, so the modulus of 22 with respect to 7 is 1. The modulus “wraps around” every time the number is divisible by 7, so it will be a repeating pattern from 0 to 6. The function that calculates the modulus is modulo and blender has a module function.

Since Blender coordinates go from  0 to 1, the Blender  modulo function is a bit funky. Without going into the details, what we need to know is that the modulo operator takes an argument such that the pattern from 0 to 1 is repeated a certain number of times that depend on the value of the modulo’s second argument. If modulo were .5, the pattern would be reproduced twice. If it were .25, it would be reproduced 4 times. The number of patterns across is 1 divided by the second argument. Here’s an example with modulus set to .25. Notice that the value node contains the number of repetitions we want. The divide node converts it to the value expected by modulo.

Repeating coordinates 4 times

Repeating coordinates 4 times

as expected, gives

Repeating coordinates 4 times

Repeating coordinates 4 times

This is good, but it’s not quiet what we want. (Why it’s not is left as an exercise for the curious.) It repeats the pattern 0..1 4 times, but what we really want the pattern 0..1..0 Let’s add a color ramp with white at both ends and black in the middle

Trying to make the repetition symmetric

Trying to make the repetition symmetric

Unfortunately, we get symmetry but it doesn’t go 0..1..0. (The math for this is left as an exercise for the curious.) Without going into details, I will replace the modulus operator with a group of math nodes that give us useful values to work with.

A symmetric modulus

A symmetric modulus

giving what we want

A symmetric modulus

A symmetric modulus

Putting it all together

There are only two more things to do: have the repeating pattern be the rings, and then do it again, offset, to make the links. Putting it together is easy:

Repeating RIngs

Node group that puts the ring drawing pattern together with the pattern replication node to produce repeating rings.

renders as

Repeated Rings

Render that puts the ring drawing pattern together with the pattern replication node to produce repeating rings.

The next step requires duplicating all those nodes and adding two more.  This is a good time to turn some of the repetition into node groups. Calculating the ring become two node groups, distance and in range

calculate the distance from the origin

calculate the distance from the origin

is in Range

return 1 if x lies between the lower and upper bound, 0 otherwise.

and symmetric modulus becomes another

Generate a symmetric modulus

Generate a symmetric modulus

Put it all together and duplicate it we get our final material

Linked Rings

Blender Cycles Material that will generate linked rings on a plane.

We’ve added a mapping node to the second copy, using its parameters to move the X and Y coordinates slightly, resulting in the image we started with.

Extra credit: One last node group.

Suppose we wanted to reuse the repeated ring pattern in other contexts. We can easily create a node group that does that, if we have our own version of the mapping node. I won’t go into the custom mapping node, but having it handy, we create a new node group that produced the repeating rings pattern

Repeating Rings Node Group

Repeating Rings Node Group

In our example, we want the rings to be the same size, so we use a few value parameters to insure this and our final material is the very simple

Repeating rings material

Having created node groups, our material is simplified down to 7 nodes, although we add 3 value nodes to make it clear that we meant the rings to be the same size

Appendix: The custom mapping node group

This is not a precise duplicate of the mapping node, but it often serves when we would like to control the mapping node. It duplicates the group behavior of applying the translation first, the rotation second, and the scaling last. It could be made simpler by using vector math for the translation and scaling. This version was written for clarity.

mapping parameterized

Vector mapping is translation, rotation, and scaling, in that order

vector translate

Vector translate is simply adding constants to each of X, Y and Z

Vector Rotate XYZ

When applying rotation, the order matters. The mapping node rotates around X, then around Y, finally around Z.

vector scale

Vector scale is similar to vector translate. It multiplies X, Y and Z by a constant value.

Vector Rotate 2D

Rotating around an axis works the same way for each axis, so we use a single node group. It makes Vector Rotate XYZ a little hard to follow, but it works.

degrees to radians

Blender does trig using radians, so we apply the conversion factor.

A procedural layered wall in Blender Cycles – Part 1: creating the layers

Introduction

A section of a wall

This texture was a contest entry in the Facebook page “Blender Procedural Textures”

The Facebook “Blender Procedural Textures” page runs a weekly contest to use procedural textures to match a specific texture, usually from a photograph. This image is similar to my entry for one of the contests. Most of the texture will be familiar to you if you create your own bump pattern and cracks, that are made with common techniques for doing so. The method for creating the layers may not be: it is not the typical approach.

This is a step by step explanation of the approach taken. If you understand what each of the individual nodes do, you will have no trouble following it. The examples were created using Blender 2.79b. Most of the approach should apply to any release with cycles. The displacement will not, but a bump map may be substituted.

Analyzing the texture

This texture can be described as having these parts

  1. The displacement of the underlying wall
  2. Obviously, the paint layers
  3. soft wear, in the forms of speckles and dots
  4. scratches

Normally this could be accomplished using the techniques described in BlenderInsight, Joakim Tornhill’s excellent manual Procedural Wear from A to Z in Blender. The manual can be found in the files section of the Facebook procedural textures page.

A close inspection of the original photograph, (which I do not have permission to post) shows that there is different kinds of wear in each of the segments, possibly because a different pigment was used for each and wore differently.

How to create regions and use them to select between textures

The simplest approach is to create a color ramp and use it to select the colors. Use a gradient texture for the color ramp fac and get something like

Gradient bands with linear color ramp

There are two obvious problems: the bands are vertical instead of horizontal, and they blend. The first is easy to solve: rotate the plane. The second is also easy: switch the color ramp from linear to constant

Rotating the plane is left as an exercise for the reader. The edges are too straight, so add some noise.

Use the multiply to control the strength of the noise texture. Use the color ramp to set the color, number, order and width of bands. This will do for most purposes, but it is very difficult to use it to put a different texture in the blue region than in the green. Is there another way?

Yes.  One way is with math.  It’s easy math, so take a calming breath and follow along. Start by thinking about how to mix two colors, so that one or the other is chosen, but not both. We can do this simply using a greater than node. We can easily split the plane in half this way

This image is produced by this simple node group.

The gradient texture produces a number between 0 and 1. Greater than compares that value to its other value, in this case .5. If the upper value, from the gradient, is greater than the lower value, greater than returns 1, otherwise 0. When the mix input factor is 0, only the top color is used, otherwise the bottom color. You change the width of the region by changing the value being compared to.

Add another region by adding another greater than and mix.

This image is produced by this node group

We can continue to add as many bands as we want.

There is one more feature of the banding to model: the bands slope downward from left to right. One way to do this is through the use of texture coordinates. Replace the gradient texture with a texture coordinates node’s generated coordinates and get

This is not precisely what we want.

This node group will give us exactly the same results as the gradient texture, but for a different reason. Any point on the plane can be described by two numbers, the distance along the bottom, X and the distance along the side, Y. X varies from 0, on the left, to 1, on the right. Y from 0 on the bottom to 1 on the top.

Add the slant by combining X and Y.  We could simply add them, but we only want X to have a small effect, so multiply it by a small number.

This looks good, three bands, slanted in the right direction. Add a little noise and you have what you want.  (Notice that I also rotated the bands).

The texture coordinate provides the position of a point.  The y value is used to select the band edges. As x gets larger going from left to right, it is added to y, giving the slant.

Let’s add a texture that applies only to the blue band, just a simple Voronoi to demonstrate.

This is straightforward. Replace the color in the color mix with the mixed texture. Now let’s add a texture that crosses all the bands.  This is ugly, but it shows the effect.

Add the noise on the borders back in and the result looks like this

and is produced by this

The overlay texture is mixed with the output of the band mixture and provides the color to the diffuse node.