Building a Procedural Kaleidoscope Shader in Unity Shader Graph







At its core, the shader works by converting the texture coordinates from Cartesian space into polar space, applying a series of mathematical operations to fold and mirror those coordinates, and then sampling the original texture using the transformed UVs. 

The result is a fully procedural kaleidoscope whose number of segments, rotation, and animation can all be adjusted in real time.









Converting UV Space into Polar Coordinates


The first step is transforming the incoming UV coordinates into polar coordinates.

Instead of describing a point by its horizontal and vertical position (X,Y), polar coordinates represent it by:
  • Radius – the distance from the center.
  • Angle – the direction around the center.

This transformation is essential because radial symmetry is much easier to manipulate when distance and direction are independent values.

The Polar Coordinates node in Shader Graph performs this conversion while also allowing the angular coordinate to be scaled by a Segments parameter. Increasing this value effectively repeats the angular coordinate around the circle, laying the groundwork for multiple mirrored wedges.

Folding the Radius


Once the radius is isolated, it passes through a sequence of operations:
Modulo
→ Subtract
→ Absolute
→ Multiply

Rather than allowing the radius to continuously increase, these nodes fold it back on itself at regular intervals. This creates a series of mirrored rings that contribute to the kaleidoscope's radial symmetry.

Because every ring is reflected, the texture appears continuous instead of obviously repeating.


Folding the Angle


The angular coordinate undergoes a similar transformation.

Before any folding occurs, a time-based value is added to the angle:
Angle + (Rotation Speed × Time)

This rotates the kaleidoscope procedurally by changing the direction before it is mirrored.

The angle is then processed through another Modulo and Absolute combination.

The modulo operation wraps each angular section back into a fixed interval, while the absolute value mirrors every other section. Rather than each wedge displaying the texture in the same orientation, adjacent wedges become reflections of one another—the defining characteristic of a kaleidoscope.

Without the Absolute operation, the shader would simply tile the texture around the center. The mirror operation is what creates the seamless reflective symmetry.


Recombining the Coordinates


After both the radius and angle have been folded independently, they are recombined into a new coordinate pair.

Although these values no longer represent the original UVs, they describe a transformed sampling location that contains all of the radial repetition and mirrored symmetry created in the previous steps.

This transformed coordinate becomes the new location from which the texture is sampled.


Independent Rotation Controls


The shader includes two separate rotation systems that create different visual effects.

Internal Rotation


The first rotation is applied directly to the angular coordinate before folding.

Because it modifies the angle itself, the mirrored wedges appear to rotate within the kaleidoscope. This gives the impression that the reflections are spinning around the center.

Final UV Rotation


After the radius and angle have been folded and recombined, the entire coordinate system passes through a Rotate node driven by a second animation parameter.

Unlike the first rotation, this rotates the completed UV mapping rather than the individual angular calculations. The effect is similar to rotating the finished kaleidoscope image instead of rotating the mirrors themselves.

Separating these two controls provides greater artistic flexibility, allowing both the internal reflections and the overall pattern to animate independently.


Sampling the Texture


The final transformed coordinates are fed into a Texture Sample node.

The texture itself remains completely unchanged. Instead, the shader repeatedly samples different locations within the original image according to the transformed UV coordinates.

This is a common principle in procedural shaders: visual complexity is created not by modifying textures, but by altering where those textures are sampled.


Bringing It All Together


Although the final effect appears intricate, it is built from a surprisingly small collection of mathematical operations:
  • Polar Coordinates separate distance and direction.
  • Modulo creates repeating intervals.
  • Absolute reflects those intervals into mirrored symmetry.
  • Time introduces procedural animation.
  • Rotate provides an additional transformation after the procedural calculations.

Each node performs a single, well-defined task. When combined, these simple operations produce the dynamic radial reflections that define the kaleidoscope effect.

This project demonstrates one of the strengths of procedural graphics: complex visual results often emerge from composing small mathematical transformations rather than relying on complex assets or handcrafted animations.