diff --git a/code/renderergl2/glsl/lightall_fp.glsl b/code/renderergl2/glsl/lightall_fp.glsl index d77cd7c7..027b54a5 100644 --- a/code/renderergl2/glsl/lightall_fp.glsl +++ b/code/renderergl2/glsl/lightall_fp.glsl @@ -143,6 +143,35 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) return bestDepth; } + +float LightRay(vec2 dp, vec2 ds, sampler2D normalMap) +{ + const int linearSearchSteps = 16; + + // current size of search window + float size = 1.0 / float(linearSearchSteps); + + // current height from initial texel depth + float height = 0.0; + + float startDepth = SampleDepth(normalMap, dp); + + // find a collision or escape + for(int i = 0; i < linearSearchSteps - 1; ++i) + { + height += size; + + if (startDepth < height) + return 1.0; + + float t = SampleDepth(normalMap, dp + ds * height); + + if (startDepth > t + height) + return 0.0; + } + + return 1.0; +} #endif vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness) @@ -252,7 +281,7 @@ void main() vec2 texCoords = var_TexCoords.xy; #if defined(USE_PARALLAXMAP) - vec3 offsetDir = viewDir * tangentToWorld; + vec3 offsetDir = E * tangentToWorld; offsetDir.xy *= -u_NormalScale.a / offsetDir.z; @@ -319,6 +348,13 @@ void main() #endif #endif + #if defined(USE_PARALLAXMAP) && defined(USE_PARALLAXMAP_SHADOWS) + offsetDir = L * tangentToWorld; + offsetDir.xy *= u_NormalScale.a / offsetDir.z; + lightColor *= LightRay(texCoords, offsetDir.xy, u_NormalMap); + #endif + + #if !defined(USE_LIGHT_VECTOR) ambientColor = lightColor; float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0); @@ -457,6 +493,12 @@ void main() // enable when point lights are supported as primary lights //lightColor *= CalcLightAttenuation(float(u_PrimaryLightDir.w > 0.0), u_PrimaryLightDir.w / sqrLightDist); + #if defined(USE_PARALLAXMAP) && defined(USE_PARALLAXMAP_SHADOWS) + offsetDir = L2 * tangentToWorld; + offsetDir.xy *= u_NormalScale.a / offsetDir.z; + lightColor *= LightRay(texCoords, offsetDir.xy, u_NormalMap); + #endif + gl_FragColor.rgb += lightColor * reflectance * NL2; #endif diff --git a/code/renderergl2/tr_glsl.c b/code/renderergl2/tr_glsl.c index 4ed49370..0d95d0df 100644 --- a/code/renderergl2/tr_glsl.c +++ b/code/renderergl2/tr_glsl.c @@ -1122,6 +1122,9 @@ void GLSL_InitGPUShaders(void) Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n"); if (r_parallaxMapping->integer > 1) Q_strcat(extradefines, 1024, "#define USE_RELIEFMAP\n"); + + if (r_parallaxMapShadows->integer) + Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP_SHADOWS\n"); } } diff --git a/code/renderergl2/tr_init.c b/code/renderergl2/tr_init.c index ce48925d..06b78173 100644 --- a/code/renderergl2/tr_init.c +++ b/code/renderergl2/tr_init.c @@ -131,6 +131,7 @@ cvar_t *r_normalMapping; cvar_t *r_specularMapping; cvar_t *r_deluxeMapping; cvar_t *r_parallaxMapping; +cvar_t *r_parallaxMapShadows; cvar_t *r_cubeMapping; cvar_t *r_cubemapSize; cvar_t *r_deluxeSpecular; @@ -1235,6 +1236,7 @@ void R_Register( void ) r_specularMapping = ri.Cvar_Get( "r_specularMapping", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); + r_parallaxMapShadows = ri.Cvar_Get( "r_parallaxMapShadows", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_cubemapSize = ri.Cvar_Get( "r_cubemapSize", "128", CVAR_ARCHIVE | CVAR_LATCH ); r_deluxeSpecular = ri.Cvar_Get("r_deluxeSpecular", "0.3", CVAR_ARCHIVE | CVAR_LATCH); diff --git a/code/renderergl2/tr_local.h b/code/renderergl2/tr_local.h index ea6d70fe..12b469c7 100644 --- a/code/renderergl2/tr_local.h +++ b/code/renderergl2/tr_local.h @@ -1771,6 +1771,7 @@ extern cvar_t *r_normalMapping; extern cvar_t *r_specularMapping; extern cvar_t *r_deluxeMapping; extern cvar_t *r_parallaxMapping; +extern cvar_t *r_parallaxMapShadows; extern cvar_t *r_cubeMapping; extern cvar_t *r_cubemapSize; extern cvar_t *r_deluxeSpecular; diff --git a/opengl2-readme.md b/opengl2-readme.md index 7e572611..c1a031c7 100644 --- a/opengl2-readme.md +++ b/opengl2-readme.md @@ -184,6 +184,11 @@ Cvars for advanced material usage: 1 - Use parallax occlusion mapping. 2 - Use relief mapping. (slower) +* `r_parallaxMapShadows` - Enable self-shadowing on parallax map + supported materials. + 0 - No. (default) + 1 - Yes. + * `r_baseSpecular` - Set the specular reflectance of materials which don't include a specular map or use the specularReflectance keyword.