Advertisement
xavierck3d

Godot simple cel shader

Feb 8th, 2024 (edited)
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Godot GLSL 3.88 KB | Source Code | 0 0
  1. // Simple cel shader with support for painted shadow maps in Godot 4
  2. // Original shader by Xavier Coelho-Kostolny https://www.xavierck.com/
  3. // Feel free to copy, modify, and share as you like.
  4. // Credit is appreciated but not necessary.
  5.  
  6. // Spatial shaders are used for 3D scenes
  7. shader_type spatial;
  8.  
  9. // Drawing the model on the screen as opaque and turning off backface culling
  10. render_mode blend_mix,depth_draw_opaque,cull_disabled;
  11.  
  12. // Base color on top of which the base_texture is multiplied
  13. // Displayed if no base_texture is assigned
  14. // Defaults to white
  15. uniform vec4 base_color: source_color;
  16.  
  17. // Base color texture with no lighting info painted in
  18. uniform sampler2D base_texture: source_color;
  19.  
  20. // Base shadow texture
  21. // Defaults to flat white
  22. uniform sampler2D shadow_texture: hint_default_white;
  23.  
  24.  
  25. // Adjustable parameters visible in the shader editor
  26. // group_uniforms defines a named section of the shader editor
  27. group_uniforms ToonShadingProperties;
  28.  
  29. // Width of the lighting terminator
  30. uniform float terminator_width : hint_range(0, 1) = 0.01;
  31.  
  32. // Push the light terminator around the model between the range -1.0 to +1.0
  33. uniform float terminator_push : hint_range(-1.0, 1.0) = -0.3;
  34.  
  35. // Push the painted shadow terminator in the same way as above
  36. uniform float painted_shadow_push : hint_range(-1.0, 1.0) = 0.25;
  37.  
  38. // Alpha cutout threshold. Anything above this value will be opaque.
  39. uniform float alpha_cutoff : hint_range(0, 1) = 0.5;
  40.  
  41. // End of the adjustable parameter section
  42. group_uniforms;
  43.  
  44.  
  45. // Pixel shader to give us the base colors and alpha
  46. void fragment() {
  47.    
  48.     // Store the base_texture in a variable so we can use it in other areas
  49.     vec4 albedo_tex = texture(base_texture, UV);
  50.    
  51.     // Multiply the base_color and base_texture
  52.     ALBEDO = base_color.rgb * texture(base_texture, UV).rgb;
  53.    
  54.     // Multiply the base_color and base_texture alpha channels so you can get alpha cutout
  55.     ALPHA = base_color.a * albedo_tex.a;
  56.    
  57.     // Set the threshold of the alpha cutout
  58.     ALPHA_SCISSOR_THRESHOLD = alpha_cutoff;
  59.    
  60. }
  61.  
  62.  
  63. // The lighting calculations go in here
  64. void light() {
  65.    
  66.     // Base position of the light terminator
  67.     // Starts at 0.5 for a larger lit area
  68.     float terminator_max = 0.5;
  69.    
  70.    
  71.     // Width of the light terminator
  72.     // Smoothstep between min and max with the transition width being terminator_width
  73.     float terminator_min = terminator_max - terminator_width;
  74.    
  75.    
  76.     // Grab the painted Shadow Texture and store it in a vec4 variable
  77.     vec4 shadows = texture(shadow_texture, UV);
  78.    
  79.    
  80.     // Calculate lighting based on normal and light direction, then clamp it between 0-1
  81.     // Doesn't include shadows, just the directional lighting
  82.     float base_lighting = clamp(dot(NORMAL, LIGHT), 0.0, 1.0);
  83.    
  84.    
  85.     // Lerp the shadow texture
  86.     float lighting_mix = mix(shadows.r, 1.0, base_lighting);
  87.    
  88.    
  89.     // Sharpen the shadow texture terminator so there aren't smooth gradients on painted shadows
  90.     // Add in painted_shadow_push so you can adjust the painted light terminator separately from the regular lighting
  91.     float lighting_mix_sharpen = smoothstep(
  92.         terminator_min + painted_shadow_push,
  93.         terminator_max + painted_shadow_push,
  94.         lighting_mix
  95.     );
  96.    
  97.     // Multiply the shadows cast from the light onto the base lighting so the model self-shadows
  98.     float attenuated_base = base_lighting * ATTENUATION;
  99.    
  100.     // Smoothstep to make a sharp light terminator
  101.     // Use terminator_push to force the terminator further along the surface
  102.     float sharp_terminator = smoothstep(
  103.         terminator_min + terminator_push,
  104.         terminator_max + terminator_push,
  105.         attenuated_base);
  106.    
  107.     // Get the lowest values from the base lighting and the painted shadows
  108.     float combined_lighting = min(lighting_mix_sharpen, sharp_terminator);
  109.    
  110.     // Replace the standard diffuse lighting calculation and multiply it with the color of the light
  111.     DIFFUSE_LIGHT += combined_lighting * LIGHT_COLOR;
  112.  
  113. }
  114.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement