Skip to content

Commit

Permalink
Split light sample into direct and ambient parts when using deluxemap…
Browse files Browse the repository at this point in the history
…s or per-vertex light vectors. Fixes #5813.
  • Loading branch information
SmileTheory committed Dec 10, 2012
1 parent 8424865 commit f4a0a78
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 18 deletions.
44 changes: 35 additions & 9 deletions code/rend2/glsl/lightall_fp.glsl
Expand Up @@ -300,28 +300,54 @@ void main()
#elif defined(USE_LIGHT)
worldLight = normalize(worldLight);

float surfNL = clamp(dot(surfNormal, worldLight), 0.0, 1.0);

#if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)
#if defined(r_normalAmbient)
vec3 ambientLight = directedLight * r_normalAmbient;
directedLight -= ambientLight;
#else
#if defined(USE_STANDARD_DELUXEMAP)
// Standard deluxe mapping treats the light sample as fully directed
// and doesn't compensate for light angle attenuation.
vec3 ambientLight = vec3(0.0);
#else
// Separate the light sample into directed and ambient parts.
//
// ambientMax - if the cosine of the angle between the surface
// normal and the light is below this value, the light
// is fully ambient.
// directedMax - if the cosine of the angle between the surface
// normal and the light is above this value, the light
// is fully directed.
const float ambientMax = 0.25;
const float directedMax = 0.5;

float directedScale = clamp((surfNL - ambientMax) / (directedMax - ambientMax), 0.0, 1.0);

// Scale the directed portion to compensate for the baked-in
// light angle attenuation.
directedScale /= max(surfNL, ambientMax);

#if defined(r_normalAmbient)
directedScale *= 1.0 - r_normalAmbient;
#endif

// Recover any unused light as ambient
vec3 ambientLight = directedLight;
directedLight *= directedScale;
ambientLight -= directedLight * surfNL;
#endif
directedLight /= max(dot(surfNormal, worldLight), 0.004);
#endif

float NL = clamp(dot(worldNormal, worldLight), 0.0, 1.0);
float surfNL = clamp(dot(surfNormal, worldLight), 0.0, 1.0);
NL = min(NL, surfNL * 2.0);
float NE = clamp(dot(worldNormal, SampleToView), 0.0, 1.0);

float fzero = u_MaterialInfo.x;
float shininess = u_MaterialInfo.y;

#if defined(USE_SPECULARMAP)
vec4 specular = texture2D(u_SpecularMap, tex);
//specular.rgb = clamp(specular.rgb - diffuse.rgb, 0.0, 1.0);
shininess *= specular.a;
#endif

float directedDiff = NL * CalcDiffuse(worldNormal, worldLight, SampleToView, NE, NL, fzero, shininess);
diffuse.rgb *= directedLight * directedDiff + ambientDiff * ambientLight;

Expand Down
10 changes: 1 addition & 9 deletions code/rend2/tr_light.c
Expand Up @@ -441,15 +441,7 @@ int R_LightDirForPoint( vec3_t point, vec3_t lightDir, vec3_t normal, world_t *w
Com_Memset(&ent, 0, sizeof(ent));
VectorCopy( point, ent.e.origin );
R_SetupEntityLightingGrid( &ent, world );

if ((DotProduct(ent.lightDir, ent.lightDir) < 0.9f) || (DotProduct(ent.lightDir, normal) < 0.1f))
{
VectorCopy(normal, lightDir);
}
else
{
VectorCopy(ent.lightDir, lightDir);
}
VectorCopy(ent.lightDir, lightDir);

return qtrue;
}

0 comments on commit f4a0a78

Please sign in to comment.