I will give a breakdown of how I made a parallax card shader using shader graph. For this shader, my personal challenge was to do as much as possible in the shader itself without relying on any textures. In the end, the only things I used 3D models for or textures are the little pokemon scene in the center of the card, and the text on the card. The design of the card was inspired by Rob Fichman's work. The 3D models of the Cosmog and Umbreon can be found on Sketchfab.
The main structure of the card consists of the outer frame, the divider at the bottom, the window and the title bar below the window. All of these are drawn using rectangle and polygon nodes. I have full control over these components which allows me to quickly change the structure and layout of the card. Here are some of the properties that control this card structure.
In total, the shader has 65 exposed properties. This is quite a lot, but I like that I can tweak variables as much as I want until I'm happy with the result.
The card features several drawings like the pokemon-type icons and the celestial bodies on the right bottom corner of the card. All of these are a combination of ellipse nodes and custom SDF nodes. Signed distance functions are extremely powerful for creating arbitrary shapes. For the corner pattern, the stars are made out of 2 Vesica SDFs blended together. The moon is made out of 2 spheres and the planet is made out of spheres and ellipses. I added a parallax effect to fake depth.
For practice, I decided to re-create several of the pokemon-types. This was very fun to work on.
The little spheres in the card that I use for the pokemon types and the attacks, are raymarched spheres. Together with some Blinn-Phong lighting they look 3D and I can fake having 3D objects in the shader without having any real 3D geometry.
At first, I attempted to do the text in-shader as well. This is possible for sure, using bezier curves and SDFs and I actually got quite close to rendering letters how I wanted to. In the end though, it was quite a lot of work to render text with the exact font that I wanted, so I decided to use a texture like a sane person.
For the sparkles I created some patterns using voronoi nodes. Then by converting the colors to directions and taking the dot product of this direction and the view direction, I could make different sparkles show up under different viewing angles.
Multiple voronoi patterns were overlayed to generate a more interesting pattern.
Several elements of the card use some kind of parallax effect. A parallax effect can be achieved by offsetting the UVs based on the view direction.
Using parallax is great way to achieve some sense of depth in an otherwise flat card.
A stencil shader was used to make it so that the 3D pokemon scene is only visible through the window of the card itself. To do this in URP I'd like to point to this post that explains it very well.
Some things are worth it, some things are not. If this were an actual project and not just me fooling around, I should for sure have used real spheres instead of raymarched ones in order to save time. The little icons however, were quick and fun to create so in the future I will do those kind of things in-shader. Another thing is that because I tried to do everything in 1 shader, my graph was very very large. With 65 properties and over 10 subgraphs, shadergraph slowed down quite a lot.
Alexander Ameye, Engineering Student and Unity Enthusiast
The article was originally published here.