In this lesson, you will learn how to bypass Unity’s standard physically-based rendering (PBR) to create custom lighting models that define the unique visual identity of your stylized game objects.
Moving Beyond Standard Lighting
Unity’s default lighting calculates brightness based on real-world physics, such as how light bounces off surfaces or how roughness affects specular highlights. While accurate, it doesn't always fit the aesthetic needs of non-photorealistic games, like cel-shaded environments or hand-painted visuals.
To override these behaviors, we use Shader Graph to intercept the raw light data—the direction and intensity of your scene lights—and mathematically remap how that light interacts with your object's surface.
The Custom Lighting Node
Instead of relying on the standard master node's PBR calculations, you can create a Custom Function Node that acts as a bridge between the light source and your material. By taking the Main Light Direction and the surface Normal, you can perform a dot product calculation to determine how much light hits a specific pixel.
For a classic "Cel-Shaded" look, you would pipe that dot product into a Step or Smoothstep node to snap the gradients into discrete bands of color rather than a smooth, realistic transition.
// Conceptual logic for a simple Toon lighting override
float NdotL = dot(Normal, LightDirection);
float celShaded = smoothstep(0.4, 0.45, NdotL);
return celShaded * LightColor;
Implementing the Logic
- Create a new Shader Graph and set the target to your project's pipeline (e.g., URP).
- Within the graph, add a Custom Function Node.
- Pass in the
Normal Vectorand theMain Light Directionfrom the scene. - Apply a threshold—such as a
Stepnode—to the output of the dot product to create sharp "lit" and "shadowed" regions. - Multiply this result by your base texture color to finalize the stylized effect.
By manipulating these mathematical inputs, you gain complete creative control over the lighting environment, allowing you to force shadows into specific shapes or tint them with custom gradients, regardless of the light’s physical properties.
Key Takeaway: By using Shader Graph to intercept and remap light data via custom functions, you can move away from physical accuracy to create stylized, intentional lighting behaviors tailored to your game's unique artistic vision.