I’ve been hearing about Unity for some time and I figured I’d finally check it out. The big takeaway from today: it is a monstrous piece of software and I have a lot to learn. It’s really powerful though, so that’s neat.
I also decided to take my first dip into shaders given that unity makes it really easy to bind shaders to objects. So I read through a tutorial and looked at the math here to produce the following images (they’re animated as in the link above). These are all being done in a shader which is running on the gpu.
For those interested in the shader, the short version (image 1 above) is below. It could probably be optimized a bit.
float wave0 = sin(i.uv.x*300+_Time.y*.5);
float wave1 = sin((i.uv.x*.90096886+i.uv.y*.4338837)*300+_Time.y*.5);
float wave2 = sin((i.uv.x*.62348980185+i.uv.y*.78183148)*300+_Time.y*.5);
float wave3 = sin((i.uv.x*.22252093395+i.uv.y*.97492791218)*300+_Time.y*.5);
float wave4 = sin((i.uv.y*.97492791218-i.uv.x*.22252093395)*300+_Time.y*.5);
float wave5 = sin((i.uv.y*.78183148246-i.uv.x*.62348980185)*300+_Time.y*.5);
float wave6 = sin((i.uv.y*.43388373911-i.uv.x*.9009688679)*300+_Time.y*.5);
float z = 1.0/(1.0+exp(-1.0*(wave0+wave1+wave2+wave3+wave4+wave5+wave6)*2));
Photoshop teaches us the way fecundity, of mass production of seeds with expected flowers in the few range. But it’s not waste. All the seeds that don’t make it to flower-hood. Some of the seeds feed the birds. Some distract the monkey, get him off our back for a night. Some of the seed sprout, die, and fertilize something yet undreamed. I might have broken my metaphor. So be it.
This is a study for Iris [working title]
A video to start!
Today was an exciting day for Iris. Previously we’d made the ripples (as you can see here) circular rings which faded as they emanated outward. This was okay, and it served well enough as an indication of where the ripples were, but we weren’t moved. They were just sub-par, and I had tried to address it a few times by using masks to reduce the aliasing, but it just wasn’t quite good enough. They didn’t allow blending, they weren’t very expressive, and they didn’t look all that great. So today I went and completely rewrote how the ripples functioned and went in favor of a representation which would allow some more flexibility. Originally I was trying to put them on a grid and go for a cellular automata style, but quickly found the number of operations to be too cumbersome to be executing every frame1. I quickly took the approach to iterate over theta and position objects (squares initially) around the circle periodically, which results in the image to the right. This was all right, except as they move outward the representation of the circle gets sparser, which can make it a bit difficult to tell where it is. The solution here is to start rotating the squares, so that at each successive radius they’re being offset a little bit. This leads to the following: Not too shabby. I hit a couple of performance blockages when trying to go for finer resolutions and long fading animations, but those were fixed readily enough by basically killing the squares off on the next frame and persisting them in the ghost images taken of the entire ripple group snapshot. Given that it’s technically feasible to use this style of ripple, I began wondering what we could achieve with it. Here are a few results from some experiments
First you’ll see first a sinusoidal modulation in size, giving the sensation that the ripple is pulsing along with it’s growth or visualizing a wave traveling away from the source.
Next up we have circles instead of squares, and the rotation here isn’t quite as standard. It actually rotates them at each step proportional to the square of the radius (whereas the previous samples have linear relationships between angular offset and radius).
Finally there’s using random noise to determine the offset, except this noise is very well behaved. In fact, for each circle there’s a random sign that gets chosen (at each frame) of whether to rotate it CW or CCW by an amount linearly proportional to the radius. Thus it has something like a random interleaving of both CW and CCW spins of the red square sample above.
This is just the beginning of what can be done with this new ripple generation. Various blend modes are available now (and can be chosen at will), and the space of positioning is wide open for exploration. Hopefully this development will help give each of the colors something of their own personality, as well as adding to the aesthetic ceiling of the game (with infinite variations). I’m also excited to see it help immerse players in what is happening aesthetically rather than them keeping focused on getting to the next level.
1. Iterating over a grid of any fine enough resolution is fairly intensive–you can instead just check within the frame which is the square of side length 2r minus the inner square of side length 2r/sqrt(2) given that they circumsribe/inscribe the circle, but it can only do so much and there’s still a lot of useless computation