Toon Shader
Godot 4
Toon shader which uses the light function.
Shader code
/*
Toon Shader by Firerabbit
MIT License
*/
shader_type spatial;
render_mode ambient_light_disabled;
uniform vec4 color : source_color = vec4(1.0);
uniform sampler2D tex : source_color, hint_default_white;
uniform float shadow : hint_range(0.0, 1.0) = 0.5;
uniform float shadow_width : hint_range(0.001, 0.5) = 0.0;
uniform vec4 shadow_color: source_color = vec4(0.705);
uniform float _specular_smoothness : hint_range(0.0,0.5) = 0.01;
uniform float _specular_strength : hint_range(0.0,0.25) = 0.075;
uniform float _glossiness : hint_range(0.0,0.5) = 0.1;
uniform float _rim_size : hint_range(0,1) = 0.5;
uniform float _rim_smoothness : hint_range(0.0,0.5) = 0.01;
void fragment() {
ALBEDO = pow(texture(tex, UV).rgb, vec3(2.2)) * color.rgb;
}
void light() {
float NdotL = dot(NORMAL, LIGHT) * ATTENUATION.x;
NdotL = smoothstep(shadow - shadow_width, shadow + shadow_width, NdotL);
// specular
vec3 H = normalize(VIEW + LIGHT);
float NdotH = max(0, dot(NORMAL, H));
float specular_intensity = pow(NdotH, 1.0 / _glossiness);
vec3 specular = vec3(smoothstep(0.5 - _specular_smoothness, 0.5 + _specular_smoothness, specular_intensity));
// rim
float rimDot = 1.0 - dot(VIEW, NORMAL);
float rim_intensity = rimDot * NdotL;
vec3 rim = vec3(smoothstep(1.0 -_rim_size - _rim_smoothness, 1.0 -_rim_size + _rim_smoothness, rim_intensity));
DIFFUSE_LIGHT = mix(ALBEDO * shadow_color.rgb, (ALBEDO + (rim + specular) * _specular_strength) * LIGHT_COLOR.rgb * 0.33, NdotL + 0.33 * (smoothstep(1.0 -_rim_size - _rim_smoothness, 1.0 -_rim_size + _rim_smoothness, rimDot)));
}
Nice! I haven’t tested it out yet, but this seems to be exactly what I need.
Just so you know, this is mislabeled as a canvas item shader.
Thank you, I have adjusted the label.
I dont why . But cannot change color everything is Blueish !!!
hint_color become -> source_color
and hint_white -> hint_default_white ! and now it work for 4.0
thanks im having fun with this shader !
This Shader looks amazing it’s exactly what I need!
Problem is, it’s not working properly for me in Godot 4.
In line 31. I get the following error, since ATTENUATION is no longer a float:
And if I remove the ‘.x’ from the attenuation it works – but I get this weird cutoff in shadow:
https://imgur.com/saIsB5P
Can you post a link to a gihub repository with a project for reproducing the bug?
Tell me, why is the beam of the light source square when illuminating the material with this shader? I compared it with another toon shader, and the result is the same.
I’m not sure if I understand the question correctly.
It could be the following:
The normals of the 3D model are used to calculate the light. If the normals of the model are flat, all normals of a surface point in the same direction and the surface is displayed in only one color. An example is a cube. In the case of a sphere, the normals are smooth, the normals of the corner points point in different directions and the specular highlight is not angular but round. Normals can be edited with Blender, for example.
https://www.youtube.com/watch?v=S1aJdBGolXA
An example image of a sphere with soft and flat normal can be found here: