Notes on the light function
A post for collecting my thoughts on light shaders. I will add more to it in the future
Recieving shadows
As per the docs, the shadow value is multiplied into ATTENUATION
. This can be useful for achieving a mostly unshaded look while still supporting shadows
void light () {
DIFFUSE_LIGHT += ATTENUATION;
}
Operating on the final sum
Spatial shaders provide a lot of information about the light sources, but no way to get the final shading value. You may wish to create an effect based upon the final shading of the fragment, not just the individual contribution of each light. The general approach I’ve seen is to do such effects as a post-process, but that limits us to working in screen space. Luckily, it’s pretty easy to subvert the purpose of the output, and process the final shading value in addition to each light. In the example code, I treat DIFFUSE_LIGHT
like a spare variable, and only allow SPECULAR_LIGHT
to contribute to the final color.
Sources
Spatial light built-ins
The default light function source code
Shader code
shader_type spatial;
void light() {
// light we wish to accumulate
DIFFUSE_LIGHT += ALBEDO * ATTENUATION * LIGHT_COLOR * max(dot(LIGHT,NORMAL), 0.0);
// assign the result
SPECULAR_LIGHT = round(DIFFUSE_LIGHT*16.0 - 0.5)/16.0; // posterizes the final color
//SPECULAR_LIGHT = DIFFUSE_LIGHT; // do nothing to the result
// cancel all contribution of the diffuse_light variable
SPECULAR_LIGHT -= ALBEDO * DIFFUSE_LIGHT;
}