Today I’ve been working on a project for CS450, and thought it might be fun to document my process, including the mistakes I made along the way!
The assignment requires us to make a 3d object, and apply vertex and fragment shaders to change its shape and draw a pattern on it. We’re also required to apply per-fragment lighting, but that’s a project for tomorrow.
I wanted to do something vaguely cloudy, and went hunting for reference images. This portfolio has some amazing stuff, and I particularly like the picture of the arctic snow material.
First step: draw a sphere using the shader pipeline as oppose to the OpenGL color pipeline! Simple in theory.
I ran into some early obstacles getting my visual environment configured. My first attempts didn’t call the shader pipeline correctly, so I rendered a LOT of thrillingly blank backgrounds. I admit I shouted at the computer after about the fifth time seeing this:
After finally rearranging to suit, I wrote the simplest possible vertex and fragment shaders: the vertex shader didn’t change anything, and the fragment shader made everything white. Exciting stuff!
Bolstered by my boring spheres, I added a black stripe to my fragment shader, just so I could see what was going on. On to the vertex shader! One simple way to distort a sphere is to apply a wobble along one or more axes. I started with a wobble along the x axis, based on the program’s time counter.
I felt like I was getting somewhere at this point! The wobbly sphere was oddly soothing. I added more wobble along the y and z axes just to make it more interesting. But it was getting hard to see what was happening without more color variation, so it’s time to revisit the fragment shader. I know I want to do something that shows the waves in the sphere. Based on my reference image, I want to vary the color from white to a deep cloudy blue. I opted to base each fragment’s color off of the z coordinate and the amount of vertex distortion from the original spherical shape.
I thought it might be cool to add some random noise to the vertex shader to mix it up a little more. I regretted this decision pretty much instantly.
After hastily throwing the noise code away, I thought it might be less wild to distort the color over time. So I’m adding a second color wave pattern, and finally mixing the two together. The final call to mix is time-dependent, so the fragment shader will change independent of the vertex shader.
The renderings are getting a little hypnotic! The next step of the project requirements are to draw a shape using the fragment shader. I’m not sure if my stripes count, and at any rate I want to add some lightning-like visuals to my cloud planet. But baby steps first–let’s draw a sphere. (In this case it’s distorted by the vertex shader, but I’m not too fussed about that.)
Using more sine/cosine functions to turn the sphere into distorted rings that move as a function of time. These aren’t quite as lightning-like as I had in mind, so I may revisit them later.
The shapes are looking nice, but the colors are a little stark. I want the centers of the shapes to be gold, and blend into the cloud patterns on the edges. I played around with smoothstep to blend the edges of the lightning into the clouds, and was pretty pleased with the result.
I’m pretty happy with the result at this point. It’s reasonably close to what I envisioned at the start, and I think it’s a good level of visual variety for a single fragment shader. I’d like to adjust the lightning a bit, as I’m not entirely thrilled with the behavior at the boundaries, but I have a few days to fine tune it. Tomorrow I’ll be working on per-fragment lighting, which should make help emphasize the distortions in the shape. For tonight, I’m making everyone who wanders near my computer look at my cloud planet!