Add sunlight/lightmap merging by multiply (r_sunlightMode 1)

Merge additive sunlight and map lighting into one GLSL shader (r_sunlightMode 2)
Change single lightmap blends to use lightall
This commit is contained in:
SmileTheory 2013-04-02 00:17:24 -07:00
parent 66acde6d60
commit 28e14c4546
8 changed files with 195 additions and 306 deletions

View file

@ -27,11 +27,19 @@ uniform int u_TCGen0;
#endif #endif
#if defined(USE_LIGHT_VECTOR) #if defined(USE_LIGHT_VECTOR)
uniform vec4 u_LightOrigin;
uniform vec3 u_DirectedLight; uniform vec3 u_DirectedLight;
uniform vec3 u_AmbientLight; uniform vec3 u_AmbientLight;
uniform float u_LightRadius; uniform float u_LightRadius;
#endif #endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
uniform vec3 u_PrimaryLightColor;
uniform vec3 u_PrimaryLightAmbient;
uniform float u_PrimaryLightRadius;
#endif
#if defined(USE_LIGHT) #if defined(USE_LIGHT)
uniform vec2 u_MaterialInfo; uniform vec2 u_MaterialInfo;
#endif #endif
@ -62,9 +70,14 @@ varying vec3 var_Bitangent;
varying vec3 var_VertLight; varying vec3 var_VertLight;
#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) #if defined(USE_LIGHT) && !defined(USE_DELUXEMAP)
varying vec3 var_WorldLight; varying vec3 var_LightDirection;
#endif #endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
varying vec3 var_PrimaryLightDirection;
#endif
#define EPSILON 0.00000001 #define EPSILON 0.00000001
#if defined(USE_PARALLAXMAP) #if defined(USE_PARALLAXMAP)
@ -199,14 +212,14 @@ float CalcSpecular(float NH, float NL, float NE, float EH, float fzero, float sh
void main() void main()
{ {
#if !defined(USE_FAST_LIGHT) && (defined(USE_LIGHT) || defined(USE_NORMALMAP)) #if !defined(USE_FAST_LIGHT) && (defined(USE_LIGHT) || defined(USE_NORMALMAP))
vec3 surfNormal = normalize(var_Normal); vec3 surfN = normalize(var_Normal);
#endif #endif
#if defined(USE_DELUXEMAP) #if defined(USE_DELUXEMAP)
vec3 worldLight = 2.0 * texture2D(u_DeluxeMap, var_LightTex).xyz - vec3(1.0); vec3 L = 2.0 * texture2D(u_DeluxeMap, var_LightTex).xyz - vec3(1.0);
//worldLight += var_WorldLight * 0.0001; //L += var_LightDirection * 0.0001;
#elif defined(USE_LIGHT) #elif defined(USE_LIGHT)
vec3 worldLight = var_WorldLight; vec3 L = var_LightDirection;
#endif #endif
#if defined(USE_LIGHTMAP) #if defined(USE_LIGHTMAP)
@ -214,101 +227,110 @@ void main()
#if defined(RGBE_LIGHTMAP) #if defined(RGBE_LIGHTMAP)
lightSample.rgb *= exp2(lightSample.a * 255.0 - 128.0); lightSample.rgb *= exp2(lightSample.a * 255.0 - 128.0);
#endif #endif
vec3 directedLight = lightSample.rgb; vec3 lightColor = lightSample.rgb;
#elif defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT) #elif defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT)
#if defined(USE_INVSQRLIGHT) #if defined(USE_INVSQRLIGHT)
float intensity = 1.0 / dot(worldLight, worldLight); float intensity = 1.0 / dot(L, L);
#else #else
float intensity = clamp((1.0 - dot(worldLight, worldLight) / (u_LightRadius * u_LightRadius)) * 1.07, 0.0, 1.0); float intensity = clamp((1.0 - dot(L, L) / (u_LightRadius * u_LightRadius)) * 1.07, 0.0, 1.0);
#endif #endif
vec3 directedLight = u_DirectedLight * intensity; vec3 lightColor = u_DirectedLight * intensity;
vec3 ambientLight = u_AmbientLight; vec3 ambientColor = u_AmbientLight;
#if defined(USE_SHADOWMAP)
vec2 shadowTex = gl_FragCoord.xy * r_FBufScale;
directedLight *= texture2D(u_ShadowMap, shadowTex).r;
#endif
#elif defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT) #elif defined(USE_LIGHT_VERTEX) && !defined(USE_FAST_LIGHT)
vec3 directedLight = var_VertLight; vec3 lightColor = var_VertLight;
#endif #endif
#if defined(USE_TCGEN) || defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) #if defined(USE_TCGEN) || defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
vec3 SampleToView = normalize(var_SampleToView); vec3 E = normalize(var_SampleToView);
#endif #endif
vec2 tex = var_DiffuseTex; vec2 texCoords = var_DiffuseTex;
float ambientDiff = 1.0; float ambientDiff = 1.0;
#if defined(USE_NORMALMAP) #if defined(USE_NORMALMAP)
#if defined(USE_VERT_TANGENT_SPACE) #if defined(USE_VERT_TANGENT_SPACE)
vec3 tangent = var_Tangent; mat3 tangentToWorld = mat3(var_Tangent, var_Bitangent, var_Normal);
vec3 bitangent = var_Bitangent;
#else #else
vec3 q0 = dFdx(var_Position); vec3 q0 = dFdx(var_Position);
vec3 q1 = dFdy(var_Position); vec3 q1 = dFdy(var_Position);
vec2 st0 = dFdx(tex); vec2 st0 = dFdx(texCoords);
vec2 st1 = dFdy(tex); vec2 st1 = dFdy(texCoords);
float dir = sign(st1.t * st0.s - st0.t * st1.s); float dir = sign(st1.t * st0.s - st0.t * st1.s);
vec3 tangent = normalize( q0 * st1.t - q1 * st0.t) * dir; vec3 tangent = normalize(q0 * st1.t - q1 * st0.t) * dir;
vec3 bitangent = -normalize( q0 * st1.s - q1 * st0.s) * dir; vec3 bitangent = -normalize(q0 * st1.s - q1 * st0.s) * dir;
#endif
mat3 tangentToWorld = mat3(tangent, bitangent, var_Normal); mat3 tangentToWorld = mat3(tangent, bitangent, var_Normal);
#endif
#if defined(USE_PARALLAXMAP) #if defined(USE_PARALLAXMAP)
vec3 offsetDir = normalize(SampleToView * tangentToWorld); vec3 offsetDir = normalize(E * tangentToWorld);
#if 0
float height = SampleHeight(u_NormalMap, tex);
float pdist = 0.05 * height - (0.05 / 2.0);
#else
offsetDir.xy *= -0.05 / offsetDir.z; offsetDir.xy *= -0.05 / offsetDir.z;
float pdist = RayIntersectDisplaceMap(tex, offsetDir.xy, u_NormalMap);
#endif texCoords += offsetDir.xy * RayIntersectDisplaceMap(texCoords, offsetDir.xy, u_NormalMap);
tex += offsetDir.xy * pdist;
#endif #endif
vec3 texN;
#if defined(SWIZZLE_NORMALMAP) #if defined(SWIZZLE_NORMALMAP)
vec3 normal = 2.0 * texture2D(u_NormalMap, tex).agb - 1.0; texN.xy = 2.0 * texture2D(u_NormalMap, texCoords).ag - 1.0;
#else #else
vec3 normal = 2.0 * texture2D(u_NormalMap, tex).rgb - 1.0; texN.xy = 2.0 * texture2D(u_NormalMap, texCoords).rg - 1.0;
#endif #endif
normal.z = sqrt(clamp(1.0 - dot(normal.xy, normal.xy), 0.0, 1.0)); texN.z = sqrt(clamp(1.0 - dot(texN.xy, texN.xy), 0.0, 1.0));
vec3 worldNormal = tangentToWorld * normal; vec3 N = tangentToWorld * texN;
#if defined(r_normalAmbient) #if defined(r_normalAmbient)
ambientDiff = 0.781341 * normal.z + 0.218659; ambientDiff = 0.781341 * texN.z + 0.218659;
#endif #endif
#elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) #elif defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
vec3 worldNormal = surfNormal; vec3 N = surfN;
#endif #endif
#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || (defined(USE_TCGEN) && defined(USE_NORMALMAP)) #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) || (defined(USE_TCGEN) && defined(USE_NORMALMAP))
worldNormal = normalize(worldNormal); N = normalize(N);
#endif #endif
#if defined(USE_TCGEN) && defined(USE_NORMALMAP) #if defined(USE_TCGEN) && defined(USE_NORMALMAP)
if (u_TCGen0 == TCGEN_ENVIRONMENT_MAPPED) if (u_TCGen0 == TCGEN_ENVIRONMENT_MAPPED)
{ {
tex = -reflect(normalize(SampleToView), worldNormal).yz * vec2(0.5, -0.5) + 0.5; texCoords = -reflect(E, N).yz * vec2(0.5, -0.5) + 0.5;
} }
#endif #endif
vec4 diffuse = texture2D(u_DiffuseMap, tex); vec4 diffuse = texture2D(u_DiffuseMap, texCoords);
#if defined(USE_LIGHT) && defined(USE_FAST_LIGHT) #if defined(USE_LIGHT) && defined(USE_FAST_LIGHT)
#if defined(USE_LIGHTMAP) #if defined(USE_LIGHTMAP)
diffuse.rgb *= directedLight; diffuse.rgb *= lightColor;
#endif #endif
#elif defined(USE_LIGHT) #elif defined(USE_LIGHT)
worldLight = normalize(worldLight); L = normalize(L);
float surfNL = clamp(dot(surfNormal, worldLight), 0.0, 1.0); float surfNL = clamp(dot(surfN, L), 0.0, 1.0);
#if defined(USE_SHADOWMAP)
vec2 shadowTex = gl_FragCoord.xy * r_FBufScale;
float shadowValue = texture2D(u_ShadowMap, shadowTex).r;
// surfaces not facing the light are always shadowed
shadowValue *= step(0.0, dot(surfN, var_PrimaryLightDirection));
#if defined(SHADOWMAP_MODULATE)
//vec3 shadowColor = min(u_PrimaryLightAmbient, lightColor);
vec3 shadowColor = u_PrimaryLightAmbient * lightColor;
#if 0
// Only shadow when the world light is parallel to the primary light
shadowValue = 1.0 + (shadowValue - 1.0) * clamp(dot(L, var_PrimaryLightDirection), 0.0, 1.0);
#endif
lightColor = mix(shadowColor, lightColor, shadowValue);
#endif
#endif
#if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX) #if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)
#if defined(USE_STANDARD_DELUXEMAP) #if defined(USE_STANDARD_DELUXEMAP)
// Standard deluxe mapping treats the light sample as fully directed // Standard deluxe mapping treats the light sample as fully directed
// and doesn't compensate for light angle attenuation. // and doesn't compensate for light angle attenuation.
vec3 ambientLight = vec3(0.0); vec3 ambientColor = vec3(0.0);
#else #else
// Separate the light sample into directed and ambient parts. // Separate the light sample into directed and ambient parts.
// //
@ -332,45 +354,71 @@ void main()
#endif #endif
// Recover any unused light as ambient // Recover any unused light as ambient
vec3 ambientLight = directedLight; vec3 ambientColor = lightColor;
directedLight *= directedScale; lightColor *= directedScale;
ambientLight -= directedLight * surfNL; ambientColor -= lightColor * surfNL;
#endif #endif
#endif #endif
float NL = clamp(dot(worldNormal, worldLight), 0.0, 1.0); float NL = clamp(dot(N, L), 0.0, 1.0);
float NE = clamp(dot(worldNormal, SampleToView), 0.0, 1.0); float NE = clamp(dot(N, E), 0.0, 1.0);
float fzero = u_MaterialInfo.x; float fzero = u_MaterialInfo.x;
float shininess = u_MaterialInfo.y; float shininess = u_MaterialInfo.y;
#if defined(USE_SPECULARMAP) #if defined(USE_SPECULARMAP)
vec4 specular = texture2D(u_SpecularMap, tex); vec4 specular = texture2D(u_SpecularMap, texCoords);
//specular.rgb = clamp(specular.rgb - diffuse.rgb, 0.0, 1.0); //specular.rgb = clamp(specular.rgb - diffuse.rgb, 0.0, 1.0);
shininess *= specular.a; shininess *= specular.a;
#endif #endif
float directedDiff = NL * CalcDiffuse(worldNormal, worldLight, SampleToView, NE, NL, fzero, shininess); float diffuseIntensity = NL * CalcDiffuse(N, L, E, NE, NL, fzero, shininess);
diffuse.rgb *= directedLight * directedDiff + ambientDiff * ambientLight; #if defined(USE_PRIMARY_LIGHT)
vec3 L2 = var_PrimaryLightDirection;
float NL2 = clamp(dot(N, L2), 0.0, 1.0);
float diffuseIntensity2 = NL2 * CalcDiffuse(N, L2, E, NE, NL2, fzero, shininess);
#if defined(USE_SHADOWMAP)
diffuseIntensity2 *= shadowValue;
#endif
diffuse.rgb *= lightColor * diffuseIntensity + u_PrimaryLightColor * diffuseIntensity2 + ambientDiff * ambientColor;
#else
diffuse.rgb *= lightColor * diffuseIntensity + ambientDiff * ambientColor;
#endif
#if defined(USE_SPECULARMAP) #if defined(USE_SPECULARMAP)
vec3 halfAngle = normalize(worldLight + SampleToView); vec3 H = normalize(L + E);
float EH = clamp(dot(SampleToView, halfAngle), 0.0, 1.0); float EH = clamp(dot(E, H), 0.0, 1.0);
float NH = clamp(dot(worldNormal, halfAngle), 0.0, 1.0); float NH = clamp(dot(N, H), 0.0, 1.0);
float directedSpec = NL * CalcSpecular(NH, NL, NE, EH, fzero, shininess); float specularIntensity = NL * CalcSpecular(NH, NL, NE, EH, fzero, shininess);
#if defined(r_normalAmbient) #if defined(r_normalAmbient)
vec3 ambientHalf = normalize(surfNormal + SampleToView); vec3 ambientHalf = normalize(surfN + E);
float ambientSpec = max(dot(ambientHalf, worldNormal) + 0.5, 0.0); float ambientSpec = max(dot(ambientHalf, N) + 0.5, 0.0);
ambientSpec *= ambientSpec * 0.44; ambientSpec *= ambientSpec * 0.44;
ambientSpec = pow(ambientSpec, shininess) * fzero; ambientSpec = pow(ambientSpec, shininess) * fzero;
specular.rgb *= directedSpec * directedLight + ambientSpec * ambientLight; #else
#else float ambientSpec = 0.0;
specular.rgb *= directedSpec * directedLight; #endif
#endif #if defined(USE_PRIMARY_LIGHT)
#endif vec3 H2 = normalize(L2 + E);
float EH2 = clamp(dot(E, H2), 0.0, 1.0);
float NH2 = clamp(dot(N, H2), 0.0, 1.0);
float specularIntensity2 = NL * CalcSpecular(NH2, NL2, NE, EH2, fzero, shininess);
#if defined(USE_SHADOWMAP)
specularIntensity2 *= shadowValue;
#endif
specular.rgb *= specularIntensity * lightColor + specularIntensity2 * u_PrimaryLightColor + ambientSpec * ambientColor;
#else
specular.rgb *= specularIntensity * lightColor + ambientSpec * ambientColor;
#endif
#endif
#endif #endif
gl_FragColor = diffuse; gl_FragColor = diffuse;

View file

@ -61,6 +61,10 @@ uniform float u_LightRadius;
#endif #endif
#endif #endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
uniform vec4 u_PrimaryLightOrigin;
#endif
varying vec2 var_DiffuseTex; varying vec2 var_DiffuseTex;
#if defined(USE_LIGHTMAP) #if defined(USE_LIGHTMAP)
@ -91,7 +95,11 @@ varying vec3 var_VertLight;
#endif #endif
#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) #if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT)
varying vec3 var_WorldLight; varying vec3 var_LightDirection;
#endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
varying vec3 var_PrimaryLightDirection;
#endif #endif
#if defined(USE_TCGEN) #if defined(USE_TCGEN)
@ -124,7 +132,7 @@ vec2 ModTexCoords(vec2 st, vec3 position, vec4 texMatrix, vec4 offTurb)
float phase = offTurb.w; float phase = offTurb.w;
vec2 st2 = vec2(dot(st, texMatrix.xz), dot(st, texMatrix.yw)) + offTurb.xy; vec2 st2 = vec2(dot(st, texMatrix.xz), dot(st, texMatrix.yw)) + offTurb.xy;
vec3 offsetPos = position / 1024.0; vec3 offsetPos = vec3(0); //position / 1024.0;
offsetPos.x += offsetPos.z; offsetPos.x += offsetPos.z;
vec2 texOffset = sin((offsetPos.xy + vec2(phase)) * 2.0 * M_PI); vec2 texOffset = sin((offsetPos.xy + vec2(phase)) * 2.0 * M_PI);
@ -155,7 +163,7 @@ void main()
gl_Position = u_ModelViewProjectionMatrix * position; gl_Position = u_ModelViewProjectionMatrix * position;
#if (defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) #if (defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX)) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT)
vec3 worldLight = attr_LightDirection; vec3 L = attr_LightDirection;
#endif #endif
#if defined(USE_MODELMATRIX) #if defined(USE_MODELMATRIX)
@ -167,7 +175,7 @@ void main()
#endif #endif
#if defined(USE_LIGHTMAP) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT) #if defined(USE_LIGHTMAP) && !defined(USE_DELUXEMAP) && !defined(USE_FAST_LIGHT)
worldLight = (u_ModelMatrix * vec4(worldLight, 0.0)).xyz; L = (u_ModelMatrix * vec4(L, 0.0)).xyz;
#endif #endif
#endif #endif
@ -175,24 +183,20 @@ void main()
var_Position = position.xyz; var_Position = position.xyz;
#endif #endif
#if defined(USE_TCGEN) || defined(USE_NORMALMAP) || defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
vec3 SampleToView = u_ViewOrigin - position.xyz;
#endif
#if defined(USE_TCGEN) || defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) #if defined(USE_TCGEN) || defined(USE_NORMALMAP) || (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT))
var_SampleToView = SampleToView; var_SampleToView = u_ViewOrigin - position.xyz;
#endif #endif
#if defined(USE_TCGEN) #if defined(USE_TCGEN)
vec2 tex = GenTexCoords(u_TCGen0, position.xyz, normal, u_TCGen0Vector0, u_TCGen0Vector1); vec2 texCoords = GenTexCoords(u_TCGen0, position.xyz, normal, u_TCGen0Vector0, u_TCGen0Vector1);
#else #else
vec2 tex = attr_TexCoord0.st; vec2 texCoords = attr_TexCoord0.st;
#endif #endif
#if defined(USE_TCMOD) #if defined(USE_TCMOD)
var_DiffuseTex = ModTexCoords(tex, position.xyz, u_DiffuseTexMatrix, u_DiffuseTexOffTurb); var_DiffuseTex = ModTexCoords(texCoords, position.xyz, u_DiffuseTexMatrix, u_DiffuseTexOffTurb);
#else #else
var_DiffuseTex = tex; var_DiffuseTex = texCoords;
#endif #endif
#if defined(USE_LIGHTMAP) #if defined(USE_LIGHTMAP)
@ -209,10 +213,10 @@ void main()
#if defined(USE_LIGHT) && !defined(USE_DELUXEMAP) #if defined(USE_LIGHT) && !defined(USE_DELUXEMAP)
#if defined(USE_LIGHT_VECTOR) #if defined(USE_LIGHT_VECTOR)
vec3 worldLight = u_LightOrigin.xyz - (position.xyz * u_LightOrigin.w); vec3 L = u_LightOrigin.xyz - (position.xyz * u_LightOrigin.w);
#endif #endif
#if !defined(USE_FAST_LIGHT) #if !defined(USE_FAST_LIGHT)
var_WorldLight = worldLight; var_LightDirection = L;
#endif #endif
#endif #endif
@ -226,12 +230,16 @@ void main()
#if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT) #if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT)
#if defined(USE_INVSQRLIGHT) #if defined(USE_INVSQRLIGHT)
float intensity = 1.0 / dot(worldLight, worldLight); float intensity = 1.0 / dot(L, L);
#else #else
float intensity = clamp((1.0 - dot(worldLight, worldLight) / (u_LightRadius * u_LightRadius)) * 1.07, 0.0, 1.0); float intensity = clamp((1.0 - dot(L, L) / (u_LightRadius * u_LightRadius)) * 1.07, 0.0, 1.0);
#endif #endif
float NL = clamp(dot(normal, normalize(worldLight)), 0.0, 1.0); float NL = clamp(dot(normal, normalize(L)), 0.0, 1.0);
var_Color.rgb *= u_DirectedLight * intensity * NL + u_AmbientLight; var_Color.rgb *= u_DirectedLight * intensity * NL + u_AmbientLight;
#endif #endif
#if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP)
var_PrimaryLightDirection = u_PrimaryLightOrigin.xyz - (position.xyz * u_PrimaryLightOrigin.w);
#endif
} }

View file

@ -86,7 +86,7 @@ void main()
vec4 shadowpos = u_ShadowMvp * biasPos; vec4 shadowpos = u_ShadowMvp * biasPos;
#if defined(USE_SHADOW_CASCADE) #if defined(USE_SHADOW_CASCADE)
const float fadeTo = 0.5; const float fadeTo = 1.0;
result = fadeTo; result = fadeTo;
#else #else
result = 0.0; result = 0.0;

View file

@ -131,7 +131,12 @@ static uniformInfo_t uniformsInfo[] =
{ "u_InvTexRes", GLSL_VEC2 }, { "u_InvTexRes", GLSL_VEC2 },
{ "u_AutoExposureMinMax", GLSL_VEC2 }, { "u_AutoExposureMinMax", GLSL_VEC2 },
{ "u_ToneMinAvgMaxLinear", GLSL_VEC3 } { "u_ToneMinAvgMaxLinear", GLSL_VEC3 },
{ "u_PrimaryLightOrigin", GLSL_VEC4 },
{ "u_PrimaryLightColor", GLSL_VEC3 },
{ "u_PrimaryLightAmbient", GLSL_VEC3 },
{ "u_PrimaryLightRadius", GLSL_FLOAT }
}; };
@ -1106,8 +1111,15 @@ void GLSL_InitGPUShaders(void)
Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n"); Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n");
if (i & LIGHTDEF_USE_SHADOWMAP) if (i & LIGHTDEF_USE_SHADOWMAP)
{
Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n"); Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");
if (r_sunlightMode->integer == 1)
Q_strcat(extradefines, 1024, "#define SHADOWMAP_MODULATE\n");
else if (r_sunlightMode->integer == 2)
Q_strcat(extradefines, 1024, "#define USE_PRIMARY_LIGHT\n");
}
if (i & LIGHTDEF_USE_TCGEN_AND_TCMOD) if (i & LIGHTDEF_USE_TCGEN_AND_TCMOD)
{ {
Q_strcat(extradefines, 1024, "#define USE_TCGEN\n"); Q_strcat(extradefines, 1024, "#define USE_TCGEN\n");

View file

@ -144,6 +144,7 @@ cvar_t *r_forceSun;
cvar_t *r_forceSunMapLightScale; cvar_t *r_forceSunMapLightScale;
cvar_t *r_forceSunLightScale; cvar_t *r_forceSunLightScale;
cvar_t *r_forceSunAmbientScale; cvar_t *r_forceSunAmbientScale;
cvar_t *r_sunlightMode;
cvar_t *r_drawSunRays; cvar_t *r_drawSunRays;
cvar_t *r_sunShadows; cvar_t *r_sunShadows;
cvar_t *r_shadowFilter; cvar_t *r_shadowFilter;
@ -1195,10 +1196,11 @@ void R_Register( void )
r_genNormalMaps = ri.Cvar_Get( "r_genNormalMaps", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_genNormalMaps = ri.Cvar_Get( "r_genNormalMaps", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_forceSun = ri.Cvar_Get( "r_forceSun", "0", CVAR_CHEAT ); r_forceSun = ri.Cvar_Get( "r_forceSun", "0", CVAR_CHEAT );
r_forceSunMapLightScale = ri.Cvar_Get( "r_forceSunMapLightScale", "0.5", CVAR_CHEAT ); r_forceSunMapLightScale = ri.Cvar_Get( "r_forceSunMapLightScale", "1.0", CVAR_CHEAT );
r_forceSunLightScale = ri.Cvar_Get( "r_forceSunLightScale", "0.5", CVAR_CHEAT ); r_forceSunLightScale = ri.Cvar_Get( "r_forceSunLightScale", "1.0", CVAR_CHEAT );
r_forceSunAmbientScale = ri.Cvar_Get( "r_forceSunAmbientScale", "0.2", CVAR_CHEAT ); r_forceSunAmbientScale = ri.Cvar_Get( "r_forceSunAmbientScale", "0.75", CVAR_CHEAT );
r_drawSunRays = ri.Cvar_Get( "r_drawSunRays", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_drawSunRays = ri.Cvar_Get( "r_drawSunRays", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_sunlightMode = ri.Cvar_Get( "r_sunlightMode", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_sunShadows = ri.Cvar_Get( "r_sunShadows", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_sunShadows = ri.Cvar_Get( "r_sunShadows", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_shadowFilter = ri.Cvar_Get( "r_shadowFilter", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_shadowFilter = ri.Cvar_Get( "r_shadowFilter", "1", CVAR_ARCHIVE | CVAR_LATCH );

View file

@ -790,6 +790,11 @@ typedef enum
UNIFORM_AUTOEXPOSUREMINMAX, UNIFORM_AUTOEXPOSUREMINMAX,
UNIFORM_TONEMINAVGMAXLINEAR, UNIFORM_TONEMINAVGMAXLINEAR,
UNIFORM_PRIMARYLIGHTORIGIN,
UNIFORM_PRIMARYLIGHTCOLOR,
UNIFORM_PRIMARYLIGHTAMBIENT,
UNIFORM_PRIMARYLIGHTRADIUS,
UNIFORM_COUNT UNIFORM_COUNT
} uniform_t; } uniform_t;
@ -1969,6 +1974,7 @@ extern cvar_t *r_forceSun;
extern cvar_t *r_forceSunMapLightScale; extern cvar_t *r_forceSunMapLightScale;
extern cvar_t *r_forceSunLightScale; extern cvar_t *r_forceSunLightScale;
extern cvar_t *r_forceSunAmbientScale; extern cvar_t *r_forceSunAmbientScale;
extern cvar_t *r_sunlightMode;
extern cvar_t *r_drawSunRays; extern cvar_t *r_drawSunRays;
extern cvar_t *r_sunShadows; extern cvar_t *r_sunShadows;
extern cvar_t *r_shadowFilter; extern cvar_t *r_shadowFilter;

View file

@ -878,209 +878,6 @@ static void ForwardDlight( void ) {
} }
static void ForwardSunlight( void ) {
// int l;
//vec3_t origin;
//float scale;
int stage;
int stageGlState[2];
qboolean alphaOverride = qfalse;
int deformGen;
vec5_t deformParams;
vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0};
float eyeT = 0;
shaderCommands_t *input = &tess;
ComputeDeformValues(&deformGen, deformParams);
ComputeFogValues(fogDistanceVector, fogDepthVector, &eyeT);
// deal with vertex alpha blended surfaces
if (input->xstages[0] && input->xstages[1] &&
(input->xstages[1]->alphaGen == AGEN_VERTEX || input->xstages[1]->alphaGen == AGEN_ONE_MINUS_VERTEX))
{
stageGlState[0] = input->xstages[0]->stateBits & (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS);
if (stageGlState[0] == 0 || stageGlState[0] == (GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO))
{
stageGlState[1] = input->xstages[1]->stateBits & (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS);
if (stageGlState[1] == (GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA))
{
alphaOverride = qtrue;
stageGlState[0] = GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL;
stageGlState[1] = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL;
}
else if (stageGlState[1] == (GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA | GLS_DSTBLEND_SRC_ALPHA))
{
alphaOverride = qtrue;
stageGlState[0] = GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL;
stageGlState[1] = GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL;
}
}
}
if (!alphaOverride)
{
stageGlState[0] =
stageGlState[1] = GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL;
}
for ( stage = 0; stage < 2 /*MAX_SHADER_STAGES */; stage++ )
{
shaderStage_t *pStage = input->xstages[stage];
shaderProgram_t *sp;
vec4_t vector;
matrix_t matrix;
if ( !pStage )
{
break;
}
//VectorCopy( dl->transformed, origin );
//if (pStage->glslShaderGroup == tr.lightallShader)
{
int index = pStage->glslShaderIndex;
index &= ~(LIGHTDEF_LIGHTTYPE_MASK | LIGHTDEF_USE_DELUXEMAP);
index |= LIGHTDEF_USE_LIGHT_VECTOR | LIGHTDEF_USE_SHADOWMAP;
if (backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity)
{
index |= LIGHTDEF_ENTITY;
}
sp = &tr.lightallShader[index];
}
backEnd.pc.c_lightallDraws++;
GLSL_BindProgram(sp);
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
GLSL_SetUniformVec3(sp, UNIFORM_VIEWORIGIN, backEnd.viewParms.or.origin);
GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);
GLSL_SetUniformInt(sp, UNIFORM_DEFORMGEN, deformGen);
if (deformGen != DGEN_NONE)
{
GLSL_SetUniformFloat5(sp, UNIFORM_DEFORMPARAMS, deformParams);
GLSL_SetUniformFloat(sp, UNIFORM_TIME, tess.shaderTime);
}
if ( input->fogNum ) {
vec4_t fogColorMask;
GLSL_SetUniformVec4(sp, UNIFORM_FOGDISTANCE, fogDistanceVector);
GLSL_SetUniformVec4(sp, UNIFORM_FOGDEPTH, fogDepthVector);
GLSL_SetUniformFloat(sp, UNIFORM_FOGEYET, eyeT);
ComputeFogColorMask(pStage, fogColorMask);
GLSL_SetUniformVec4(sp, UNIFORM_FOGCOLORMASK, fogColorMask);
}
{
vec4_t baseColor;
vec4_t vertColor;
ComputeShaderColors(pStage, baseColor, vertColor);
if (alphaOverride)
{
if (input->xstages[1]->alphaGen == AGEN_VERTEX)
{
baseColor[3] = 0.0f;
vertColor[3] = 1.0f;
}
else if (input->xstages[1]->alphaGen == AGEN_ONE_MINUS_VERTEX)
{
baseColor[3] = 1.0f;
vertColor[3] = -1.0f;
}
}
GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, baseColor);
GLSL_SetUniformVec4(sp, UNIFORM_VERTCOLOR, vertColor);
}
if (pStage->alphaGen == AGEN_PORTAL)
{
GLSL_SetUniformFloat(sp, UNIFORM_PORTALRANGE, tess.shader->portalRange);
}
GLSL_SetUniformInt(sp, UNIFORM_COLORGEN, pStage->rgbGen);
GLSL_SetUniformInt(sp, UNIFORM_ALPHAGEN, pStage->alphaGen);
GLSL_SetUniformVec3(sp, UNIFORM_DIRECTEDLIGHT, backEnd.refdef.sunCol);
GLSL_SetUniformVec3(sp, UNIFORM_AMBIENTLIGHT, backEnd.refdef.sunAmbCol);
GLSL_SetUniformVec4(sp, UNIFORM_LIGHTORIGIN, backEnd.refdef.sunDir);
GLSL_SetUniformFloat(sp, UNIFORM_LIGHTRADIUS, 9999999999.9f);
GLSL_SetUniformVec2(sp, UNIFORM_MATERIALINFO, pStage->materialInfo);
GL_State( stageGlState[stage] );
GLSL_SetUniformMatrix16(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
if (pStage->bundle[TB_DIFFUSEMAP].image[0])
R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP);
if (pStage->bundle[TB_NORMALMAP].image[0])
R_BindAnimatedImageToTMU( &pStage->bundle[TB_NORMALMAP], TB_NORMALMAP);
if (pStage->bundle[TB_SPECULARMAP].image[0])
R_BindAnimatedImageToTMU( &pStage->bundle[TB_SPECULARMAP], TB_SPECULARMAP);
/*
{
GL_BindToTMU(tr.sunShadowDepthImage[0], TB_SHADOWMAP);
GL_BindToTMU(tr.sunShadowDepthImage[1], TB_SHADOWMAP2);
GL_BindToTMU(tr.sunShadowDepthImage[2], TB_SHADOWMAP3);
GLSL_SetUniformMatrix16(sp, UNIFORM_SHADOWMVP, backEnd.refdef.sunShadowMvp[0]);
GLSL_SetUniformMatrix16(sp, UNIFORM_SHADOWMVP2, backEnd.refdef.sunShadowMvp[1]);
GLSL_SetUniformMatrix16(sp, UNIFORM_SHADOWMVP3, backEnd.refdef.sunShadowMvp[2]);
}
*/
GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP);
ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix );
VectorSet4(vector, matrix[0], matrix[1], matrix[4], matrix[5]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, vector);
VectorSet4(vector, matrix[8], matrix[9], matrix[12], matrix[13]);
GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, vector);
GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen);
//
// draw
//
if (input->multiDrawPrimitives)
{
R_DrawMultiElementsVBO(input->multiDrawPrimitives, input->multiDrawMinIndex, input->multiDrawMaxIndex, input->multiDrawNumIndexes, input->multiDrawFirstIndex);
}
else
{
R_DrawElementsVBO(input->numIndexes, input->firstIndex, input->minIndex, input->maxIndex);
}
backEnd.pc.c_totalIndexes += tess.numIndexes;
backEnd.pc.c_dlightIndexes += tess.numIndexes;
}
}
static void ProjectPshadowVBOGLSL( void ) { static void ProjectPshadowVBOGLSL( void ) {
int l; int l;
vec3_t origin; vec3_t origin;
@ -1329,7 +1126,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
index |= LIGHTDEF_ENTITY; index |= LIGHTDEF_ENTITY;
} }
if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && ((index & LIGHTDEF_USE_LIGHTMAP) || (index & LIGHTDEF_USE_LIGHT_VERTEX))) if (r_sunlightMode->integer && (backEnd.viewParms.flags & VPF_USESUNLIGHT) && (index & LIGHTDEF_LIGHTTYPE_MASK))
{ {
index |= LIGHTDEF_USE_SHADOWMAP; index |= LIGHTDEF_USE_SHADOWMAP;
} }
@ -1497,12 +1294,12 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )
{ {
int i; int i;
if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && ((pStage->glslShaderIndex & LIGHTDEF_USE_LIGHTMAP) || (pStage->glslShaderIndex & LIGHTDEF_USE_LIGHT_VERTEX))) if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && (pStage->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK))
{ {
GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP); GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP);
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_AMBIENTLIGHT, backEnd.refdef.sunAmbCol); GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTAMBIENT, backEnd.refdef.sunAmbCol);
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DIRECTEDLIGHT, backEnd.refdef.sunCol); GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, backEnd.refdef.sunCol);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_LIGHTORIGIN, backEnd.refdef.sunDir); GLSL_SetUniformVec4(sp, UNIFORM_PRIMARYLIGHTORIGIN, backEnd.refdef.sunDir);
} }
if ((r_lightmap->integer == 1 || r_lightmap->integer == 2) && pStage->bundle[TB_LIGHTMAP].image[0]) if ((r_lightmap->integer == 1 || r_lightmap->integer == 2) && pStage->bundle[TB_LIGHTMAP].image[0])
@ -1795,14 +1592,6 @@ void RB_StageIteratorGeneric( void )
} }
} }
#if 0
if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && tess.shader->sort <= SS_OPAQUE
//if ((tr.sunShadows || r_forceSunlight->value > 0.0f) && tess.shader->sort <= SS_OPAQUE
&& !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) && tess.xstages[0]->glslShaderGroup == tr.lightallShader) {
ForwardSunlight();
}
#endif
// //
// now do fog // now do fog
// //

View file

@ -2493,6 +2493,30 @@ static qboolean CollapseStagesToGLSL(void)
if (numStages == i && i >= 2 && CollapseMultitexture()) if (numStages == i && i >= 2 && CollapseMultitexture())
numStages--; numStages--;
// convert any remaining lightmap stages to a lighting pass with a white texture
// only do this with r_sunlightMode non-zero, as it's only for correct shadows.
if (r_sunlightMode->integer)
{
for (i = 0; i < MAX_SHADER_STAGES; i++)
{
shaderStage_t *pStage = &stages[i];
if (!pStage->active)
continue;
if (pStage->bundle[TB_DIFFUSEMAP].isLightmap)
{
pStage->glslShaderGroup = tr.lightallShader;
pStage->glslShaderIndex = LIGHTDEF_USE_LIGHTMAP;
if (r_deluxeMapping->integer && tr.worldDeluxeMapping)
pStage->glslShaderIndex |= LIGHTDEF_USE_DELUXEMAP;
pStage->bundle[TB_LIGHTMAP] = pStage->bundle[TB_DIFFUSEMAP];
pStage->bundle[TB_DIFFUSEMAP].image[0] = tr.whiteImage;
pStage->bundle[TB_DIFFUSEMAP].isLightmap = qfalse;
}
}
}
return numStages; return numStages;
} }