engine/bin/data/shaders/common/lambert.h

65 lines
3.0 KiB
C

float shadowFactor( const Light light, float def );
void lambert() {
// outcoming light from surface to eye
const vec3 Lo = normalize( -surface.position.eye );
// angle of outcoming light
const float cosLo = max(0.0, dot(surface.normal.eye, Lo));
for ( uint i = 0, shadows = 0; i < MAX_LIGHTS; ++i ) {
#if BAKING
// skip if surface is a dynamic light, we aren't baking dynamic lights
if ( lights[i].type < 0 ) continue;
#else
// skip if surface is already baked, and this isn't a dynamic light
if ( surface.material.lightmapped && lights[i].type >= 0 ) continue;
#endif
// incoming light to surface (non-const to normalize it later)
// vec3 Li = lights[i].position - surface.position.world;
vec3 Li = vec3(VIEW_MATRIX * vec4(lights[i].position, 1)) - surface.position.eye;
// magnitude of incoming light vector (for inverse-square attenuation)
const float Lmagnitude = dot(Li, Li);
// distance incoming light travels (reuse from above)
const float Ldistance = sqrt(Lmagnitude);
// "free" normalization, since we need to compute the above values anyways
Li = Li / Ldistance;
// attenuation factor
// const float Lattenuation = 1.0 / (1 + (PI * Lmagnitude));
const float Lattenuation = 1.0 / (1 + Lmagnitude);
// skip if attenuation factor is too low
// if ( Lattenuation <= LIGHT_POWER_CUTOFF ) continue;
// ray cast if our surface is occluded from the light
const float Lshadow = ( shadows++ < MAX_SHADOWS ) ? shadowFactor( lights[i], 0.0 ) : 1;
// skip if our shadow factor is too low
// if ( Lshadow <= LIGHT_POWER_CUTOFF ) continue; // in case of any divergence
// light radiance
const vec3 Lr = lights[i].color.rgb * lights[i].power * Lattenuation * Lshadow;
// skip if our radiance is too low
// if ( Lr <= LIGHT_POWER_CUTOFF ) continue;
// halfway vector
const vec3 Lh = normalize(Li + Lo);
// angle of incoming light
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
// angle of halfway light vector
const float cosLh = max(0.0, dot(surface.normal.eye, Lh));
/*
const vec3 Liu = vec3(VIEW_MATRIX * vec4(lights[i].position, 1)) - surface.position.eye;
const vec3 Li = normalize(Liu);
// const float Lattenuation = 1.0 / (PI * pow(length(Liu), 2.0));
// const float Lattenuation = 1.0 / (1 + (PI * pow(length(Liu), 2.0)));
const float Lattenuation = 1.0 / (1 + pow(length(Liu), 2.0));
const float Lshadow = ( shadows++ < MAX_SHADOWS ) ? shadowFactor( lights[i], 0.0 ) : 1;
if ( lights[i].power * Lattenuation * Lshadow <= LIGHT_POWER_CUTOFF ) continue;
const float cosLi = max(0.0, dot(surface.normal.eye, Li));
const vec3 Lr = lights[i].color.rgb * lights[i].power * Lattenuation * Lshadow;
// const vec3 Lh = normalize(Li + Lo);
// const float cosLh = max(0.0, dot(surface.normal.eye, Lh));
*/
const vec3 diffuse = surface.material.albedo.rgb;
const vec3 specular = vec3(0);
surface.light.rgb += (diffuse + specular) * Lr * cosLi;
surface.light.a += lights[i].power * Lattenuation * Lshadow;
}
}