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;
}
Tags
light
The shader code and all code snippets in this post are under MIT license and can be used freely. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from celyk

Trail dewiggle

Ray-box setup

Placeholder

Related shaders

Modulate Before Light

2D Rim Light

2D Rim Light

guest

0 Comments
Inline Feedbacks
View all comments