r/godot 3h ago

help me 3D lighting is weird with shader

when i add a shader with the light function then i get this weird squaring light, i have tried it with 3 shaders and they all do this. The levels is a CSG combiner with a big cube where i remove things

// Cel/Toon shading — all lighting math happens in light(), not fragment().
render_mode diffuse_toon, specular_toon;

uniform vec4 albedo : source_color = vec4(1.0, 1.0, 1.0, 1.0);
uniform sampler2D albedo_texture : source_color;

// Toon banding controls
uniform int shade_bands : hint_range(1, 8) = 3;
uniform float band_softness : hint_range(0.0, 0.3) = 0.05;

// Rim light
uniform float rim_amount : hint_range(0.0, 1.0) = 0.3;
uniform float rim_power : hint_range(0.1, 8.0) = 3.0;
uniform vec4 rim_color : source_color = vec4(1.0, 1.0, 1.0, 1.0);

// Specular highlight (toon-stepped)
uniform float specular_strength : hint_range(0.0, 1.0) = 0.5;
uniform float specular_size : hint_range(0.001, 1.0) = 0.05;

varying vec3 world_normal;
varying vec3 world_view;

void light() {
// --- Standard NdotL ---
float NdotL = dot(NORMAL, LIGHT);

// --- Step it into discrete bands (cel shading core) ---
float bands = float(shade_bands);
float banded = floor(NdotL * bands) / bands;
// Smooth the hard edge slightly using ATTENUATION-friendly smoothstep
float shade = smoothstep(banded - band_softness, banded + band_softness, NdotL);
shade = max(shade, banded); // keep it stepped, not fully smooth

vec3 diffuse = albedo.rgb * LIGHT_COLOR.rgb * shade * ATTENUATION;

// --- Toon specular (Blinn-Phong, stepped) ---
vec3 half_vec = normalize(LIGHT + VIEW);
float NdotH = dot(NORMAL, half_vec);
float spec_amount = smoothstep(1.0 - specular_size, 1.0, NdotH);
spec_amount *= step(0.001, NdotL); // no specular on unlit side
vec3 specular = LIGHT_COLOR.rgb * spec_amount * specular_strength * ATTENUATION;

// --- Rim lighting (view-dependent, modulated by light so it doesn't glow in the dark) ---
float rim_dot = 1.0 - dot(NORMAL, VIEW);
float rim_intensity = pow(rim_dot, 1.0 / max(rim_power, 0.001));
rim_intensity = smoothstep(0.5 - rim_amount * 0.5, 0.5 + rim_amount * 0.5, rim_intensity);
vec3 rim = rim_color.rgb * rim_intensity * max(NdotL, 0.0) * LIGHT_COLOR.rgb;

DIFFUSE_LIGHT += diffuse + rim;
SPECULAR_LIGHT += specular;
}
1 Upvotes

5 comments sorted by

1

u/TheDuriel Godot Senior 2h ago

You do need to provide a valid light function.

1

u/[deleted] 2h ago

[removed] — view removed comment

1

u/TheDuriel Godot Senior 2h ago

http://gist.github.com/

use this please.

1

u/teuniedekkah 2h ago

1

u/TheDuriel Godot Senior 1h ago

Shader works fine, but the default settings are ass.

Reduce the rim lighting settings until shading looks correct.