A Shady Story
TL;DR - Dev log of me learning shaders by trying to recreate pics/effects I find online. :)
Over my game dev career. I've come across these black magic programs they call shaders. I'd see something like this
and ask "How do you do that?". The reply would be "it's a shader". In my attempt to become one of these magicians I'd start a shader tutorial series. It'd be blah blah blah runs on the GPU, something something lighting, pixar, blah blah blah lambertian, dot product and you'd end up with
-_______-
I picked up the basic theory. You've got vertices, move them and morph the mesh. You've got pixels, change their color. Oh, and it runs in parallel.
Then I had to write my first production shader. It was for Raptor Polo. We needed to be able to have player colors. There were a ton of frames of animation. The process of splitting the clothes from the orc, grayscaling them and puting them separately was infeasible. So I wrote a shader that did that. This was in Unity3D.
Next shaders were written for a WEB GL. Passed the shader audio frequency data to offset vertices as a song played. Eventually the shader and the music sculpted a sphere into a "rose". And then based on the offset the color of the vertex. That's why its darker closer to the center. Thanks CT mini jams.
Started to get excited about shaders. Next shader was for Semblance. Needed to recreate the lighting streaks like in this concept piece.
This was a fun challenge. Learnt about shader buffers and using more than one pass. Used a "masking effect" to get the light streaks.
Over this period I've been collecting images across the net of shaders I'd like to attempt to make. This thread is gonna be like the art dumps but of my progress learning shaders.
Over my game dev career. I've come across these black magic programs they call shaders. I'd see something like this
and ask "How do you do that?". The reply would be "it's a shader". In my attempt to become one of these magicians I'd start a shader tutorial series. It'd be blah blah blah runs on the GPU, something something lighting, pixar, blah blah blah lambertian, dot product and you'd end up with
-_______-
I picked up the basic theory. You've got vertices, move them and morph the mesh. You've got pixels, change their color. Oh, and it runs in parallel.
Then I had to write my first production shader. It was for Raptor Polo. We needed to be able to have player colors. There were a ton of frames of animation. The process of splitting the clothes from the orc, grayscaling them and puting them separately was infeasible. So I wrote a shader that did that. This was in Unity3D.
Next shaders were written for a WEB GL. Passed the shader audio frequency data to offset vertices as a song played. Eventually the shader and the music sculpted a sphere into a "rose". And then based on the offset the color of the vertex. That's why its darker closer to the center. Thanks CT mini jams.
Started to get excited about shaders. Next shader was for Semblance. Needed to recreate the lighting streaks like in this concept piece.
This was a fun challenge. Learnt about shader buffers and using more than one pass. Used a "masking effect" to get the light streaks.
Over this period I've been collecting images across the net of shaders I'd like to attempt to make. This thread is gonna be like the art dumps but of my progress learning shaders.
Comments
So far this is what I've got.
Right now my next step is to create a the springing to the vertices. I want to use the the same spring function I've been using in Semblance.
I've read you can write to textures using shaders. So, I'm going to save the velocity of each vertex in a texture. Save direction in rgb and magnitude in alpha.
A lot of guess work. Let me know if I'm heading down the wrong road.
A while back I was starting to look at how shaders worked and I happened to watch an episode of Archer with a scene in an office with a water feature on the right. And I thought to myself that it would be the perfect scene to try recreate with a custom cel shading, glass, and moving water shader. Of course, I never did that :(
stuff looks awesome!
What shader language are you doing this all in? :)
@IceCliff I'm using Unity3D for the current shader. It's GLSL, I think. In Unity there's RenderTextures, based on what I read about FBO they are similar. You can write to them. and use the texture again in another shader.
SImple shader that checks each vert against the position of the moving sphere and extrudes it out based on the verts normal.
and
This is two shaders. One that computes the springing and the other that takes the texture from the springing shader and extrudes the vert based on the color of the texture.
So, uhm ... yeah.
If you're stuck, you could perhaps try relaxing the constraint of having it all done in one ubershader, but to either layer multiple objects together, or use helper objects that drive your shaders?
So here's what I went with. I stuck with the 2 shader solution I had for simulating the springing. Now I had to figure out how to make the distorting sphere go through the spring shader.
The springing shader is purely a fragment shader. So, I had to think of the distorting sphere going through the texture in uv coordinates.
Here's a diagram of the theory. A sphere going through a plane in 2D is just a a circle on the plane that who's radius grows and shrinks again.
simple enough, equation of a circle with shader parameters for x, y. Interpolate towards the radius.
Obviously a linear interpolation creates a cone. I need a "sphere". So, just circle interpolate.
Now Unity's standard sphere maps the verts uvs nicely enough for me to fake where to make my circles grow and shrink from
So, I knew where to grow the circles on the texture. The shader that takes texture from the springing shader just does a simple vertex displacement based on the red channel of the texture.
I was using ProBuilder to create the Icosahedron sphere but it doesn't map the uvs like the Unity sphere. I guess I need to try manually create a model with the uv mapping I want???
There's nothing fancy with the sphere that goes through the springing sphere. It's just mapping it's x values to an animation curve that changes the values on the shader to spring. To make it general, I probably would use the their positions and radius values.
Things not quite right
- The extrusion max height should be based on the size of the radius
- the circle interpolation shouldn't be the full interpolation every time but also based on the radius
That's what I've got so far. :)
That is badass. :D
Have you tried what this looks like when the displacement tears the mesh apart? (I don't know for certain, especially because I haven't used ProBuilder, but I think you can reimport your sphere with automatic smoothing set to a tiny angle (0-1 degrees) to break all of the edges. I imagine ProBuilder would have some kind of edge-hardening tool built into it too.)
Great job man! What's next?
--
(also, just fyi, I was biting my tongue super hard not to suggest the implementations that I'd have attempted. I'm glad I did, because I think you've got a better (more dynamic) result than what I'd have suggested. :D)
Is it possible to increase the "resolution" of the sphere ripples simply by using a model with more verts?
And can this handle two spheres moving through the big one at once?
@jackshiels, thanks. I'm trying my best. :D
Also have you tried using compute shaders? I was reading about them recently and it seems like it would be extremely helpful for you for this exact kind of task.
I think I'm done, well I'm kinda over it now. I feel like I've exhausted enjoyment of the learning process here. I didn't get to the shiny rendering, or these
- The extrusion max height should be based on the size of the radius
- the circle interpolation shouldn't be the full interpolation every time but also based on the radius
- trying to make it general (there's few of cheats :P )
but I'm happy about what I learnt about GPGPU programming. Want to tackle the next shader now. I'm hoping to write a full article about the process soon. :)
Thanks @IceCliff!
The spring algorithm I got from here.
The simulation on a shader I learnt here. It's very Unity focussed but before I found it I read a lot about simulations on the GPU on different platforms. Just can't find the articles now.
Unity demo - adapted for unity
good luck
I ended up with this. :(
I'm writing some shaders in shadertoy and I get the theory of raymarching and signed distance fields. I can't for the life of me see what I've done wrong with this one in Unity, here's the shader. Any help?
Here's a WEBGL demo of the final shader. It's not as sexy as his though. I didn't end u working on the rendering part. As you've seen that's not my strong point at this moment even with the first shader in this thread. That's what I'd like to work on more.
I put up the code on github with all the various steps commented out if you'd like to follow the tutorial.
I got back at it. Wanted to pretty up the first shader I worked on. Remember, like 2 years ago. LOL. Also did a short twitter thread of the process mostly the same as above. I also put up a project on GitHub where I'll dump all future shader experiments.