Overview
Spritify (Name pending) is a custom Unity shader I wrote since my friend and I were discussing real-time implementations of doom-like billboard sprites. I had the realization that Unity provides just enough features for me to implement the entire sprite drawing process without any form of scripts.
Process
Since this shader has been designed for VRChat avatars, certain restrictions are imposed, such as not being able to use custom C# scripts, and requirements need to be met, like supporting stereo rendering and mirrors (oblique matrices).
Normally to achieve an effect like this, you bake out the albedo to a sprite sheet containing the model rendered from all sorts of angles, but this limits you to a finite amount of unique frames. What you might want to do is have a camera that lies on the surface of a sphere with a given radius that fits the entire model within it, however, since we can’t do custom C# scripts for VRChat avatars, it is not really possible to set the location or orientation of this camera.
But then I wondered “What if I just substitute the regular view matrix with a custom one in the shader?”, and suddenly things started to click. Since I could easily get a forward direction and want a vertical billboard, I could easily construct a custom matrix that would represent the camera as if it were lying on this abstract sphere containing the model. Then by putting it at an early queue,using a GrabPass, I could essentially render out the model into a unique buffer, although the size of the buffer would be that of the current render target.
So now I had a model that would orient itself properly and be stored into a separate buffer, but it’s very much visible in the middle of the screen. So the next step is to make sure that we clear the buffer properly before and after we’ve drawn the model. In order to reduce user-error, the way I solved this was by making a custom geometry shader that places a triangle over the entire screen, making everything black and writing the depth to the far plane both before and after the abstract camera pass. I had to make sure that this was also done at some point before the skybox and other geometry is drawn, as to not accidentally clear something that’s supposed to be in the final frame. So I have to put all of this at a really early queue.
Now that the processing passes are not visible, I made another geometry program that creates a quad at a later transparent queue, and it samples the GrabPass buffer using some truncated uv coordinates. After quite a bit of tinkering, bug fixing, and implementing features like AudioLink (an audio reactive shader system) integration for audio reactive effects and a palette LUT texture and generator, I began feeling satisfied with the results.