Need some insights for canvas light shaders

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Euklid

I started toying around with 2d light shaders but think I have problems understanding how this is handled in Godot.

Basically I tried to write a cel shader for the 2d lighting with normal maps.

First I calculate the angle between light and normal vector:

shader_type canvas_item;

uniform float cutoff = -0.2;

void light() {     
    vec3 normalVector;
    vec2 lightVector;
    lightVector = normalize(LIGHT_VEC);    //get light to fragment vector
    normalVector = normalize(NORMAL);  //get fragment normal vector

    //calc angle between 2d light vector and normal x,y coordinates
    float dotProd = lightVector.x * normalVector.x + lightVector.y * normalVector.y;
    //if(dotProd < 0.0) dotProd = 0.0;

Then my approach would be to set the generated light either to full illumination above a certain cutoff:
(-> light vector = normal vector * -1) to get a single color highlight
or set the light vector to zero (-> LIGHT_VEC.xy = vec2(0.0,0.0):wink: to get no illumination.

LIGHT = LIGHT;
    if(dotProd > cutoff) LIGHT_VEC.xy = vec2(0.0,0.0);
    else 
    {	
    	//LIGHT = vec4(1.0,1.0,1.0,1.0);
    	LIGHT_VEC.x = NORMAL.x * -1.0;
    	LIGHT_VEC.y = NORMAL.y * -1.0;
    }
}

but here the stuff I don’t understand occurs. I would have expected to get a dot product (angle) in the range [-1:1]. In open GL I would limit the range to [0:1] and could use that value as lighting amount.
Then do a hard cutoff “angle < cutoff = no light”, “angle > cutoff = full light”.

But this approach results in a flipped lighting, meaning the light comes from the left and my sprite is illuminated from the right.
In my Godot code the cel shading only works if I set the cutoff to a negative value. Best results with -0.2.

The other poroblem I have is that the cel shader disables the shadow function from LightOccluder2D. So how is the light occluder calculated. And is there a better approach to implement my cel shader? I’m not really sure if setting the LightVector is the proper way to modify the lighting and suspect that the shadow works the same way by modifying the light vector.

Any help is welcome!