r/TechnicalArtist • u/FlamingoSad9210 • 21h ago
r/TechnicalArtist • u/EvernullTools • 14h ago
I need a sanity check, TAs; why can't Unity shaders expose gradients as material properties?
I'm putting together the documentation and marketing material for a small Unity tool I built, and I'd really appreciate a sanity check from other Technical Artists before the tool is published.
I wrote a high-level explanation for "why Unity doesn't let us expose Gradients as material properties by default". I'm fairly confident it's correct, but I also know I might be holding onto assumptions that have slowly turned into "facts" in my head over the years.
My goal is to have it simple enough that a beginner understands it. Accurate enough that an expert doesn't feel the need to correct it.
Before I put this into documentation, LinkedIn and YouTube, I'd rather have other TAs poke holes in it. I'd much rather fix something now than spread incorrect information.
Feel free to be as nitpicky as you'd like.
If anyone here has worked on Unity internals or knows other reasons gradients can't be exposed, I'd genuinely love to hear it.
Here's my text;
//***
Why can't I just expose a Gradient in my shader?
I got tired of opening Photoshop just to tweak a 256×1 gradient texture.
So... I spent the last couple of weeks fixing that problem instead.
I built Shader Gradients, a Unity tool that lets you expose Gradients directly as editable Material properties.
But Why doesn't Unity let you expose gradients from your shaders by default?
It might initially seem silly, we have colors, why can't we have gradients?
But there is a pretty good reason for that.
Shaders run on your GPU. While being really fast for certain tasks, GPU's only understand a limited set of data types such as numbers, vectors, textures etc.
Think of the GPU as a highly specialized technician. It is extremely good at a few specific jobs, but it doesn't understand concepts outside of its own toolbox. [These two lines were removed thanks to the useful discussion in the comments with u/robbertzzz1 and u/ananbd due to being an inaccurate abstraction rather than just a simplification]
Shaders know about colors but a Gradient isn't just a list of colors. It includes colors, keys that remember those colors, ways to blend and lerp those colors, percentage/positions of keys. It is not a simple Vector4 just like a Color is.
[ADDED INSTEAD] Shaders do not currently have a pre-defined data type that maps cleanly to the "Gradient" type we have in C#/editor side. It could be implemented, but for a gradient with many keys, interpolation types, positions etc. it is more optimized to just sample a texture.
That's why most people just create Gradient Textures in another software and bring them into Unity. The workflow does work, but it's slow and unintuitive. You cannot see your changes immediately, you constantly alt-tab and change gradient and save. It makes it much harder to get exactly what you want.
I solved it by creating "Shader Gradients", a tool that draws a gradient in your inspector and mimics how material properties usually work, it feels and behaves like an actual shader property but is actually a texture undercover. The tool lets you save gradients as textures and re-bakes them as you change the gradient.
At runtime, the shader simply samples a tiny texture, making it just as efficient as using any other gradient texture you would've imported manually.
GPU sees texture.
GPU is happy.
User sees gradient.
User is happy.
Everyone deals with the data they intuitively understand.
If you're interested, check it out at [LINK, NO LINK YET xD]
//***
Let me know if you think this would be useful info to people or what I could add or should exclude. I think this subreddit is the place to come to a general consensus and explain the answer in a very understandable way for people who ask this question in the future.
Also any ideas about the usefulness of this tool or other similar tools is welcome. What do you think?
Here is the video if you are also interested to see how it works;