mirror of
https://github.com/UberGames/lilium-voyager.git
synced 2024-11-10 06:31:47 +00:00
Split light sample into direct and ambient parts when using deluxemaps or per-vertex light vectors. Fixes #5813.
This commit is contained in:
parent
8424865879
commit
f4a0a78b43
2 changed files with 40 additions and 22 deletions
|
@ -300,28 +300,54 @@ void main()
|
|||
#elif defined(USE_LIGHT)
|
||||
worldLight = normalize(worldLight);
|
||||
|
||||
#if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)
|
||||
#if defined(r_normalAmbient)
|
||||
vec3 ambientLight = directedLight * r_normalAmbient;
|
||||
directedLight -= ambientLight;
|
||||
#else
|
||||
vec3 ambientLight = vec3(0.0);
|
||||
#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);
|
||||
|
||||
#if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)
|
||||
#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
|
||||
#endif
|
||||
|
||||
float NL = clamp(dot(worldNormal, worldLight), 0.0, 1.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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
Loading…
Reference in a new issue