Toon/Cel Shader

toon shader on 3d objects

Table of Contents

Breakdown

  1. Basic idea is to discretize (remove transitions).
  2. We do this by calculating light intensity to be a fixed constant if the surface is pointing towards light, else it is zero. This is unlike a smooth transition that occurs in lambert or other shading models.
  3. The diffuse light is added first.
  4. Then specular light (just by varying some values)
  5. Finally, we add rim light, which depends on dot product of view angle and the surface normal.

Godot Code

shader_type spatial;

uniform vec3 color: source_color;

// Cel shader
void light() {
	float diffuse_intensity = dot(NORMAL, LIGHT) > 0.5 ? 1.0 : 0.0;
	DIFFUSE_LIGHT = diffuse_intensity == 0.0 ? color / 2.0 : color;
	
	float specular_intensity = dot(NORMAL, LIGHT) > 0.990 ? 1.0 : 0.0;
	SPECULAR_LIGHT = color * 2.0 * specular_intensity;
	
	float rim_dot_product = 1.0 - dot(VIEW, NORMAL);
	float rim_intensity = pow(smoothstep(0.0, 2.0, rim_dot_product) * 2.0, 4);
	DIFFUSE_LIGHT += rim_intensity;
}

This post is incomplete.