Sometime in late spring or early summer 2019,
one of my friends wanted a widget on their website:
“a rotating shape, like an icosahedron,
with a sort of iridescent effect to it.”
- paraphrased from memory
I was immediately inspired, and in ten minutes
I made a satisfactory demo in Blender. 1)
The hard part was actually making the widget.
It was my first-ever time writing javascript. 2)
Fortunately, basic javascript isn't particularly hard.
A different friend, who was actually writing the website,
directed me to the three.js library for graphics legwork.
This made it pretty easy to create an icosahedron,
make it wobble a bit, and cover it with a custom shader.
Writing the shader dredged up memories
of the one OpenGL class I took years ago. 3)
I had to look everything up, but it was all half-familiar,
and certainly easier than doing it for the first time.
Since my friend's expectations were vague,
I devised a very… crude iridescence shader.
“Iridescence” is when the color of an object
changes when viewed from different angles.
My implementation just takes the XYZ location
of each pixel's worth of surface, or “fragment”.
To this, it adds the difference between:
The geometric-nonsense result
is used for the fragment's RGB color.
gl_FragColor = vec4( location+vec3(1.5)*(faceNormal-location), 1.0 // alpha channel -- fully opaque );
This worked well because on sphere-like objects
like the icosahedron, the location of a fragment
closely corresponds to its angle to the viewer.
5)
Gently rotate the icosahedron, and the location
(and color) of its surfaces smoothly changes.
The effect satisfied me and also my friends.
Looking to identify the shader as
a cheap
6)
imitation of the real thing,
I named it “Tin Iridescence”.
By this point I had gotten deeply involved
in the project, so I ended up pair-programming
the whole website with my friends.
7)
They learned a lot about 3D graphics
(we wrote Voronoi cells from scratch)
and I learned a lot about JS and CSS.
8)
We wrote two completely different ways
to make the icosahedron spin around,
and stuck with the easier-to-keep-right one.
The final result was “Invisible Networks”.
The source code is on GitHub.