This is an automated email from the git hooks/post-receive script. smcv pushed a commit to annotated tag 1.42d in repository iortcw.
commit d17523d351ec3d55a576cd3c64532d662b5e157c Author: m4n4t4...@gmail.com <m4n4t4...@gmail.com@e65d2741-a53d-b2dc-ae96-bb75fa5e4c4a> Date: Fri Aug 1 19:23:06 2014 +0000 All: Rend2: Add fourth cascade for sun shadows and adjust sun shadow cvar defaults --- MP/code/rend2/glsl/shadowmask_fp.glsl | 91 ++++++++++-------- MP/code/rend2/tr_backend.c | 25 +++-- MP/code/rend2/tr_bsp.c | 3 + MP/code/rend2/tr_fbo.c | 2 +- MP/code/rend2/tr_glsl.c | 6 +- MP/code/rend2/tr_image.c | 7 +- MP/code/rend2/tr_init.c | 6 +- MP/code/rend2/tr_local.h | 11 ++- MP/code/rend2/tr_main.c | 175 +++++++++++++++++++++++----------- MP/code/rend2/tr_scene.c | 27 +++++- SP/code/rend2/glsl/shadowmask_fp.glsl | 91 ++++++++++-------- SP/code/rend2/tr_backend.c | 25 +++-- SP/code/rend2/tr_bsp.c | 3 + SP/code/rend2/tr_fbo.c | 2 +- SP/code/rend2/tr_glsl.c | 6 +- SP/code/rend2/tr_image.c | 7 +- SP/code/rend2/tr_init.c | 6 +- SP/code/rend2/tr_local.h | 11 ++- SP/code/rend2/tr_main.c | 175 +++++++++++++++++++++++----------- SP/code/rend2/tr_scene.c | 27 +++++- 20 files changed, 478 insertions(+), 228 deletions(-) diff --git a/MP/code/rend2/glsl/shadowmask_fp.glsl b/MP/code/rend2/glsl/shadowmask_fp.glsl index b489fef..8a5597a 100644 --- a/MP/code/rend2/glsl/shadowmask_fp.glsl +++ b/MP/code/rend2/glsl/shadowmask_fp.glsl @@ -1,15 +1,17 @@ uniform sampler2D u_ScreenDepthMap; -uniform sampler2D u_ShadowMap; +uniform sampler2DShadow u_ShadowMap; #if defined(USE_SHADOW_CASCADE) -uniform sampler2D u_ShadowMap2; -uniform sampler2D u_ShadowMap3; +uniform sampler2DShadow u_ShadowMap2; +uniform sampler2DShadow u_ShadowMap3; +uniform sampler2DShadow u_ShadowMap4; #endif uniform mat4 u_ShadowMvp; #if defined(USE_SHADOW_CASCADE) uniform mat4 u_ShadowMvp2; uniform mat4 u_ShadowMvp3; +uniform mat4 u_ShadowMvp4; #endif uniform vec3 u_ViewOrigin; @@ -39,94 +41,103 @@ float random( const vec2 p ) return mod( 123456789., 1e-7 + 256. * dot(p,r) ); } -float PCF(const sampler2D shadowmap, const vec2 st, const float dist) +float PCF(const sampler2DShadow shadowmap, const vec2 st, const float dist) { float mult; float scale = 2.0 / r_shadowMapSize; +#if 0 + // from http://http.developer.nvidia.com/GPUGems/gpugems_ch11.html + vec2 offset = vec2(greaterThan(fract(var_DepthTex.xy * r_FBufScale * 0.5), vec2(0.25))); + offset.y += offset.x; + if (offset.y > 1.1) offset.y = 0.0; + + mult = shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5, 0.5)) * scale, dist)).r + + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5, 0.5)) * scale, dist)).r + + shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5, -1.5)) * scale, dist)).r + + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5, -1.5)) * scale, dist)).r; + + mult *= 0.25; +#endif + #if defined(USE_SHADOW_FILTER) float r = random(var_DepthTex.xy); float sinr = sin(r) * scale; float cosr = cos(r) * scale; mat2 rmat = mat2(cosr, sinr, -sinr, cosr); - mult = step(dist, texture2D(shadowmap, st + rmat * vec2(-0.7055767, 0.196515)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(0.3524343, -0.7791386)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(0.2391056, 0.9189604)).r); + mult = shadow2D(shadowmap, vec3(st + rmat * vec2(-0.7055767, 0.196515), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.3524343, -0.7791386), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.2391056, 0.9189604), dist)).r; #if defined(USE_SHADOW_FILTER2) - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(-0.07580382, -0.09224417)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(0.5784913, -0.002528916)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(0.192888, 0.4064181)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(-0.6335801, -0.5247476)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(-0.5579782, 0.7491854)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(0.7320465, 0.6317794)).r); + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.07580382, -0.09224417), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.5784913, -0.002528916), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.192888, 0.4064181), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.6335801, -0.5247476), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.5579782, 0.7491854), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.7320465, 0.6317794), dist)).r; mult *= 0.11111; #else mult *= 0.33333; #endif #else - mult = step(dist, texture2D(shadowmap, st).r); + mult = shadow2D(shadowmap, vec3(st, dist)); #endif - + return mult; } float getLinearDepth(sampler2D depthMap, vec2 tex, float zFarDivZNear) { - float sampleZDivW = texture2D(depthMap, tex).r; - sampleZDivW -= DEPTH_MAX_ERROR; - return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); + float sampleZDivW = texture2D(depthMap, tex).r - DEPTH_MAX_ERROR; + return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); } void main() { float result; - - float depth = getLinearDepth(u_ScreenDepthMap, var_DepthTex, u_ViewInfo.x); - float sampleZ = u_ViewInfo.y * depth; + float depth = getLinearDepth(u_ScreenDepthMap, var_DepthTex, u_ViewInfo.x); vec4 biasPos = vec4(u_ViewOrigin + var_ViewDir * (depth - 0.5 / u_ViewInfo.x), 1.0); - + vec4 shadowpos = u_ShadowMvp * biasPos; - -#if defined(USE_SHADOW_CASCADE) - const float fadeTo = 1.0; - result = fadeTo; -#else - result = 0.0; -#endif - if (all(lessThanEqual(abs(shadowpos.xyz), vec3(abs(shadowpos.w))))) +#if defined(USE_SHADOW_CASCADE) + if (all(lessThan(abs(shadowpos.xyz), vec3(abs(shadowpos.w))))) { - shadowpos.xyz = shadowpos.xyz / shadowpos.w * 0.5 + 0.5; +#endif + shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5); result = PCF(u_ShadowMap, shadowpos.xy, shadowpos.z); - } #if defined(USE_SHADOW_CASCADE) + } else { shadowpos = u_ShadowMvp2 * biasPos; - if (all(lessThanEqual(abs(shadowpos.xyz), vec3(abs(shadowpos.w))))) + if (all(lessThan(abs(shadowpos.xyz), vec3(abs(shadowpos.w))))) { - shadowpos.xyz = shadowpos.xyz / shadowpos.w * 0.5 + 0.5; + shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5); result = PCF(u_ShadowMap2, shadowpos.xy, shadowpos.z); } else { shadowpos = u_ShadowMvp3 * biasPos; - if (all(lessThanEqual(abs(shadowpos.xyz), vec3(abs(shadowpos.w))))) + if (all(lessThan(abs(shadowpos.xyz), vec3(abs(shadowpos.w))))) { - shadowpos.xyz = shadowpos.xyz / shadowpos.w * 0.5 + 0.5; + shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5); result = PCF(u_ShadowMap3, shadowpos.xy, shadowpos.z); - - float fade = clamp(sampleZ / r_shadowCascadeZFar * 10.0 - 9.0, 0.0, 1.0); - result = mix(result, fadeTo, fade); + } + else + { + shadowpos = u_ShadowMvp4 * biasPos; + shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5); + result = PCF(u_ShadowMap4, shadowpos.xy, shadowpos.z); } } } #endif - + gl_FragColor = vec4(vec3(result), 1.0); } diff --git a/MP/code/rend2/tr_backend.c b/MP/code/rend2/tr_backend.c index a0f9eb5..812aa66 100644 --- a/MP/code/rend2/tr_backend.c +++ b/MP/code/rend2/tr_backend.c @@ -1379,13 +1379,24 @@ const void *RB_DrawSurfs( const void *data ) { GLSL_BindProgram(&tr.shadowmaskShader); GL_BindToTMU(tr.renderDepthImage, TB_COLORMAP); - GL_BindToTMU(tr.sunShadowDepthImage[0], TB_SHADOWMAP); - GL_BindToTMU(tr.sunShadowDepthImage[1], TB_SHADOWMAP2); - GL_BindToTMU(tr.sunShadowDepthImage[2], TB_SHADOWMAP3); - GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP, backEnd.refdef.sunShadowMvp[0]); - GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP2, backEnd.refdef.sunShadowMvp[1]); - GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP3, backEnd.refdef.sunShadowMvp[2]); + if (r_shadowCascadeZFar->integer != 0) + { + GL_BindToTMU(tr.sunShadowDepthImage[0], TB_SHADOWMAP); + GL_BindToTMU(tr.sunShadowDepthImage[1], TB_SHADOWMAP2); + GL_BindToTMU(tr.sunShadowDepthImage[2], TB_SHADOWMAP3); + GL_BindToTMU(tr.sunShadowDepthImage[3], TB_SHADOWMAP4); + + GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP, backEnd.refdef.sunShadowMvp[0]); + GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP2, backEnd.refdef.sunShadowMvp[1]); + GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP3, backEnd.refdef.sunShadowMvp[2]); + GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP4, backEnd.refdef.sunShadowMvp[3]); + } + else + { + GL_BindToTMU(tr.sunShadowDepthImage[3], TB_SHADOWMAP); + GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP, backEnd.refdef.sunShadowMvp[3]); + } GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWORIGIN, backEnd.refdef.vieworg); { @@ -1939,6 +1950,8 @@ const void *RB_PostProcess(const void *data) FBO_BlitFromTexture(tr.sunShadowDepthImage[1], NULL, NULL, NULL, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 256, 0, 128, 128); FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, NULL, dstBox, NULL, NULL, 0); + VectorSet4(dstBox, 384, 0, 128, 128); + FBO_BlitFromTexture(tr.sunShadowDepthImage[3], NULL, NULL, NULL, dstBox, NULL, NULL, 0); } if (0) diff --git a/MP/code/rend2/tr_bsp.c b/MP/code/rend2/tr_bsp.c index db88eb1..e903b15 100644 --- a/MP/code/rend2/tr_bsp.c +++ b/MP/code/rend2/tr_bsp.c @@ -3681,6 +3681,9 @@ void RE_LoadWorldMap( const char *name ) { tr.toneMinAvgMaxLevel[1] = -2.0f; tr.toneMinAvgMaxLevel[2] = 0.0f; + // reset last cascade sun direction so last shadow cascade is rerendered + VectorClear(tr.lastCascadeSunDirection); + tr.worldMapLoaded = qtrue; // load it diff --git a/MP/code/rend2/tr_fbo.c b/MP/code/rend2/tr_fbo.c index c642b73..4070c6e 100644 --- a/MP/code/rend2/tr_fbo.c +++ b/MP/code/rend2/tr_fbo.c @@ -484,7 +484,7 @@ void FBO_Init(void) if (tr.sunShadowDepthImage[0]) { - for ( i = 0; i < 3; i++) + for ( i = 0; i < 4; i++) { tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height); FBO_Bind(tr.sunShadowFbo[i]); diff --git a/MP/code/rend2/tr_glsl.c b/MP/code/rend2/tr_glsl.c index c304f2b..ba75215 100644 --- a/MP/code/rend2/tr_glsl.c +++ b/MP/code/rend2/tr_glsl.c @@ -79,10 +79,12 @@ static uniformInfo_t uniformsInfo[] = { "u_ShadowMap", GLSL_INT }, { "u_ShadowMap2", GLSL_INT }, { "u_ShadowMap3", GLSL_INT }, + { "u_ShadowMap4", GLSL_INT }, { "u_ShadowMvp", GLSL_MAT16 }, { "u_ShadowMvp2", GLSL_MAT16 }, { "u_ShadowMvp3", GLSL_MAT16 }, + { "u_ShadowMvp4", GLSL_MAT16 }, { "u_EnableTextures", GLSL_VEC4 }, @@ -1308,7 +1310,8 @@ void GLSL_InitGPUShaders(void) if (r_shadowFilter->integer >= 2) Q_strcat(extradefines, 1024, "#define USE_SHADOW_FILTER2\n"); - Q_strcat(extradefines, 1024, "#define USE_SHADOW_CASCADE\n"); + if (r_shadowCascadeZFar->integer != 0) + Q_strcat(extradefines, 1024, "#define USE_SHADOW_CASCADE\n"); Q_strcat(extradefines, 1024, va("#define r_shadowMapSize %d\n", r_shadowMapSize->integer)); Q_strcat(extradefines, 1024, va("#define r_shadowCascadeZFar %f\n", r_shadowCascadeZFar->value)); @@ -1326,6 +1329,7 @@ void GLSL_InitGPUShaders(void) GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP, TB_SHADOWMAP); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP2, TB_SHADOWMAP2); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP3, TB_SHADOWMAP3); + GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP4, TB_SHADOWMAP4); qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.shadowmaskShader); diff --git a/MP/code/rend2/tr_image.c b/MP/code/rend2/tr_image.c index b04226c..1eb06bc 100644 --- a/MP/code/rend2/tr_image.c +++ b/MP/code/rend2/tr_image.c @@ -3168,9 +3168,14 @@ void R_CreateBuiltinImages( void ) { if (r_sunlightMode->integer) { - for ( x = 0; x < 3; x++) + for ( x = 0; x < 4; x++) { tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB); + GL_Bind(tr.sunShadowDepthImage[x]); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); } tr.screenShadowImage = R_CreateImage("*screenShadow", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8); diff --git a/MP/code/rend2/tr_init.c b/MP/code/rend2/tr_init.c index 2500e56..b4c2670 100644 --- a/MP/code/rend2/tr_init.c +++ b/MP/code/rend2/tr_init.c @@ -1340,9 +1340,9 @@ void R_Register( void ) { 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_shadowMapSize = ri.Cvar_Get( "r_shadowMapSize", "1024", CVAR_ARCHIVE | CVAR_LATCH ); - r_shadowCascadeZNear = ri.Cvar_Get( "r_shadowCascadeZNear", "4", CVAR_ARCHIVE | CVAR_LATCH ); - r_shadowCascadeZFar = ri.Cvar_Get( "r_shadowCascadeZFar", "3072", CVAR_ARCHIVE | CVAR_LATCH ); - r_shadowCascadeZBias = ri.Cvar_Get( "r_shadowCascadeZBias", "-320", CVAR_ARCHIVE | CVAR_LATCH ); + r_shadowCascadeZNear = ri.Cvar_Get( "r_shadowCascadeZNear", "8", CVAR_ARCHIVE | CVAR_LATCH ); + r_shadowCascadeZFar = ri.Cvar_Get( "r_shadowCascadeZFar", "1024", CVAR_ARCHIVE | CVAR_LATCH ); + r_shadowCascadeZBias = ri.Cvar_Get( "r_shadowCascadeZBias", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_ignoreDstAlpha = ri.Cvar_Get( "r_ignoreDstAlpha", "1", CVAR_ARCHIVE | CVAR_LATCH ); // diff --git a/MP/code/rend2/tr_local.h b/MP/code/rend2/tr_local.h index ce82ea3..6b3cf59 100644 --- a/MP/code/rend2/tr_local.h +++ b/MP/code/rend2/tr_local.h @@ -406,6 +406,7 @@ enum TB_SPECULARMAP = 4, TB_SHADOWMAP = 5, TB_CUBEMAP = 6, + TB_SHADOWMAP4 = 6, NUM_TEXTURE_BUNDLES = 7 }; @@ -718,10 +719,12 @@ typedef enum UNIFORM_SHADOWMAP, UNIFORM_SHADOWMAP2, UNIFORM_SHADOWMAP3, + UNIFORM_SHADOWMAP4, UNIFORM_SHADOWMVP, UNIFORM_SHADOWMVP2, UNIFORM_SHADOWMVP3, + UNIFORM_SHADOWMVP4, UNIFORM_ENABLETEXTURES, @@ -849,7 +852,7 @@ typedef struct { int num_pshadows; struct pshadow_s *pshadows; - float sunShadowMvp[3][16]; + float sunShadowMvp[4][16]; float sunDir[4]; float sunCol[4]; float sunAmbCol[4]; @@ -1659,7 +1662,7 @@ typedef struct { image_t *calcLevelsImage; image_t *targetLevelsImage; image_t *fixedLevelsImage; - image_t *sunShadowDepthImage[3]; + image_t *sunShadowDepthImage[4]; image_t *screenShadowImage; image_t *screenSsaoImage; image_t *hdrDepthImage; @@ -1676,7 +1679,7 @@ typedef struct { FBO_t *quarterFbo[2]; FBO_t *calcLevelsFbo; FBO_t *targetLevelsFbo; - FBO_t *sunShadowFbo[3]; + FBO_t *sunShadowFbo[4]; FBO_t *screenShadowFbo; FBO_t *screenSsaoFbo; FBO_t *hdrDepthFbo; @@ -1752,6 +1755,8 @@ typedef struct { vec3_t sunLight; // from the sky shader for this level vec3_t sunDirection; + vec3_t lastCascadeSunDirection; + float lastCascadeSunMvp[16]; //----(SA) added float lightGridMulAmbient; // lightgrid multipliers specified in sky shader diff --git a/MP/code/rend2/tr_main.c b/MP/code/rend2/tr_main.c index 881c031..2c6798d 100644 --- a/MP/code/rend2/tr_main.c +++ b/MP/code/rend2/tr_main.c @@ -2853,13 +2853,15 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level) break; } - VectorCopy(fd->vieworg, lightOrigin); - + if (level != 3) + VectorCopy(fd->vieworg, lightOrigin); + else + VectorCopy(tr.world->lightGridOrigin, lightOrigin); // Make up a projection VectorScale(lightDir, -1.0f, lightViewAxis[0]); - if (lightViewIndependentOfCameraView) + if (level == 3 || lightViewIndependentOfCameraView) { // Use world up as light view up VectorSet(lightViewAxis[2], 0, 0, 1); @@ -2879,7 +2881,7 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level) // Check if too close to parallel to light direction if (abs(DotProduct(lightViewAxis[2], lightViewAxis[0])) > 0.9f) { - if (lightViewIndependentOfCameraView) + if (level == 3 || lightViewIndependentOfCameraView) { // Use world left as light view up VectorSet(lightViewAxis[2], 0, 1, 0); @@ -2916,56 +2918,116 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level) ClearBounds(lightviewBounds[0], lightviewBounds[1]); - // add view near plane - lx = splitZNear * tan(fd->fov_x * M_PI / 360.0f); - ly = splitZNear * tan(fd->fov_y * M_PI / 360.0f); - VectorMA(fd->vieworg, splitZNear, fd->viewaxis[0], base); - - VectorMA(base, lx, fd->viewaxis[1], point); - VectorMA(point, ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - VectorMA(base, -lx, fd->viewaxis[1], point); - VectorMA(point, ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - VectorMA(base, lx, fd->viewaxis[1], point); - VectorMA(point, -ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - VectorMA(base, -lx, fd->viewaxis[1], point); - VectorMA(point, -ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - - // add view far plane - lx = splitZFar * tan(fd->fov_x * M_PI / 360.0f); - ly = splitZFar * tan(fd->fov_y * M_PI / 360.0f); - VectorMA(fd->vieworg, splitZFar, fd->viewaxis[0], base); - - VectorMA(base, lx, fd->viewaxis[1], point); - VectorMA(point, ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - VectorMA(base, -lx, fd->viewaxis[1], point); - VectorMA(point, ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - VectorMA(base, lx, fd->viewaxis[1], point); - VectorMA(point, -ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - VectorMA(base, -lx, fd->viewaxis[1], point); - VectorMA(point, -ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + if (level != 3) + { + // add view near plane + lx = splitZNear * tan(fd->fov_x * M_PI / 360.0f); + ly = splitZNear * tan(fd->fov_y * M_PI / 360.0f); + VectorMA(fd->vieworg, splitZNear, fd->viewaxis[0], base); + + VectorMA(base, lx, fd->viewaxis[1], point); + VectorMA(point, ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + VectorMA(base, -lx, fd->viewaxis[1], point); + VectorMA(point, ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + VectorMA(base, lx, fd->viewaxis[1], point); + VectorMA(point, -ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + VectorMA(base, -lx, fd->viewaxis[1], point); + VectorMA(point, -ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + // add view far plane + lx = splitZFar * tan(fd->fov_x * M_PI / 360.0f); + ly = splitZFar * tan(fd->fov_y * M_PI / 360.0f); + VectorMA(fd->vieworg, splitZFar, fd->viewaxis[0], base); + + VectorMA(base, lx, fd->viewaxis[1], point); + VectorMA(point, ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + VectorMA(base, -lx, fd->viewaxis[1], point); + VectorMA(point, ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + VectorMA(base, lx, fd->viewaxis[1], point); + VectorMA(point, -ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + VectorMA(base, -lx, fd->viewaxis[1], point); + VectorMA(point, -ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + } + else + { + // use light grid size as level size + // FIXME: could be tighter + vec3_t bounds; + + bounds[0] = tr.world->lightGridSize[0] * tr.world->lightGridBounds[0]; + bounds[1] = tr.world->lightGridSize[1] * tr.world->lightGridBounds[1]; + bounds[2] = tr.world->lightGridSize[2] * tr.world->lightGridBounds[2]; + + point[0] = tr.world->lightGridOrigin[0]; + point[1] = tr.world->lightGridOrigin[1]; + point[2] = tr.world->lightGridOrigin[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0] + bounds[0]; + point[1] = tr.world->lightGridOrigin[1]; + point[2] = tr.world->lightGridOrigin[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0]; + point[1] = tr.world->lightGridOrigin[1] + bounds[1]; + point[2] = tr.world->lightGridOrigin[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0] + bounds[0]; + point[1] = tr.world->lightGridOrigin[1] + bounds[1]; + point[2] = tr.world->lightGridOrigin[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0]; + point[1] = tr.world->lightGridOrigin[1]; + point[2] = tr.world->lightGridOrigin[2] + bounds[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0] + bounds[0]; + point[1] = tr.world->lightGridOrigin[1]; + point[2] = tr.world->lightGridOrigin[2] + bounds[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0]; + point[1] = tr.world->lightGridOrigin[1] + bounds[1]; + point[2] = tr.world->lightGridOrigin[2] + bounds[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0] + bounds[0]; + point[1] = tr.world->lightGridOrigin[1] + bounds[1]; + point[2] = tr.world->lightGridOrigin[2] + bounds[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + } if (!glRefConfig.depthClamp) lightviewBounds[0][0] = lightviewBounds[1][0] - 8192; @@ -2995,8 +3057,8 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level) VectorScale(lightviewBounds[1], worldUnitsPerTexel, lightviewBounds[1]); } - //ri.Printf(PRINT_ALL, "znear %f zfar %f\n", lightviewBounds[0][0], lightviewBounds[1][0]); - //ri.Printf(PRINT_ALL, "fovx %f fovy %f xmin %f xmax %f ymin %f ymax %f\n", fd->fov_x, fd->fov_y, xmin, xmax, ymin, ymax); + //ri.Printf(PRINT_ALL, "level %d znear %f zfar %f\n", level, lightviewBounds[0][0], lightviewBounds[1][0]); + //ri.Printf(PRINT_ALL, "xmin %f xmax %f ymin %f ymax %f\n", lightviewBounds[0][1], lightviewBounds[1][1], -lightviewBounds[1][2], -lightviewBounds[0][2]); } @@ -3137,6 +3199,7 @@ void R_RenderCubemapSide( int cubemapIndex, int cubemapSide, qboolean subscene ) R_RenderSunShadowMaps(&refdef, 0); R_RenderSunShadowMaps(&refdef, 1); R_RenderSunShadowMaps(&refdef, 2); + R_RenderSunShadowMaps(&refdef, 3); } } diff --git a/MP/code/rend2/tr_scene.c b/MP/code/rend2/tr_scene.c index 8d87c8d..68cd57c 100644 --- a/MP/code/rend2/tr_scene.c +++ b/MP/code/rend2/tr_scene.c @@ -616,9 +616,30 @@ void RE_RenderScene( const refdef_t *fd ) { // playing with even more shadows if(glRefConfig.framebufferObject && r_sunlightMode->integer && !( fd->rdflags & RDF_NOWORLDMODEL ) && (r_forceSun->integer || tr.sunShadows)) { - R_RenderSunShadowMaps(fd, 0); - R_RenderSunShadowMaps(fd, 1); - R_RenderSunShadowMaps(fd, 2); + if (r_shadowCascadeZFar != 0) + { + R_RenderSunShadowMaps(fd, 0); + R_RenderSunShadowMaps(fd, 1); + R_RenderSunShadowMaps(fd, 2); + } + else + { + Mat4Zero(tr.refdef.sunShadowMvp[0]); + Mat4Zero(tr.refdef.sunShadowMvp[1]); + Mat4Zero(tr.refdef.sunShadowMvp[2]); + } + + // only rerender last cascade if sun has changed position + if (r_forceSun->integer == 2 || !VectorCompare(tr.refdef.sunDir, tr.lastCascadeSunDirection)) + { + VectorCopy(tr.refdef.sunDir, tr.lastCascadeSunDirection); + R_RenderSunShadowMaps(fd, 3); + Mat4Copy(tr.refdef.sunShadowMvp[3], tr.lastCascadeSunMvp); + } + else + { + Mat4Copy(tr.lastCascadeSunMvp, tr.refdef.sunShadowMvp[3]); + } } // playing with cube maps diff --git a/SP/code/rend2/glsl/shadowmask_fp.glsl b/SP/code/rend2/glsl/shadowmask_fp.glsl index b489fef..8a5597a 100644 --- a/SP/code/rend2/glsl/shadowmask_fp.glsl +++ b/SP/code/rend2/glsl/shadowmask_fp.glsl @@ -1,15 +1,17 @@ uniform sampler2D u_ScreenDepthMap; -uniform sampler2D u_ShadowMap; +uniform sampler2DShadow u_ShadowMap; #if defined(USE_SHADOW_CASCADE) -uniform sampler2D u_ShadowMap2; -uniform sampler2D u_ShadowMap3; +uniform sampler2DShadow u_ShadowMap2; +uniform sampler2DShadow u_ShadowMap3; +uniform sampler2DShadow u_ShadowMap4; #endif uniform mat4 u_ShadowMvp; #if defined(USE_SHADOW_CASCADE) uniform mat4 u_ShadowMvp2; uniform mat4 u_ShadowMvp3; +uniform mat4 u_ShadowMvp4; #endif uniform vec3 u_ViewOrigin; @@ -39,94 +41,103 @@ float random( const vec2 p ) return mod( 123456789., 1e-7 + 256. * dot(p,r) ); } -float PCF(const sampler2D shadowmap, const vec2 st, const float dist) +float PCF(const sampler2DShadow shadowmap, const vec2 st, const float dist) { float mult; float scale = 2.0 / r_shadowMapSize; +#if 0 + // from http://http.developer.nvidia.com/GPUGems/gpugems_ch11.html + vec2 offset = vec2(greaterThan(fract(var_DepthTex.xy * r_FBufScale * 0.5), vec2(0.25))); + offset.y += offset.x; + if (offset.y > 1.1) offset.y = 0.0; + + mult = shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5, 0.5)) * scale, dist)).r + + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5, 0.5)) * scale, dist)).r + + shadow2D(shadowmap, vec3(st + (offset + vec2(-1.5, -1.5)) * scale, dist)).r + + shadow2D(shadowmap, vec3(st + (offset + vec2( 0.5, -1.5)) * scale, dist)).r; + + mult *= 0.25; +#endif + #if defined(USE_SHADOW_FILTER) float r = random(var_DepthTex.xy); float sinr = sin(r) * scale; float cosr = cos(r) * scale; mat2 rmat = mat2(cosr, sinr, -sinr, cosr); - mult = step(dist, texture2D(shadowmap, st + rmat * vec2(-0.7055767, 0.196515)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(0.3524343, -0.7791386)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(0.2391056, 0.9189604)).r); + mult = shadow2D(shadowmap, vec3(st + rmat * vec2(-0.7055767, 0.196515), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.3524343, -0.7791386), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.2391056, 0.9189604), dist)).r; #if defined(USE_SHADOW_FILTER2) - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(-0.07580382, -0.09224417)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(0.5784913, -0.002528916)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(0.192888, 0.4064181)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(-0.6335801, -0.5247476)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(-0.5579782, 0.7491854)).r); - mult += step(dist, texture2D(shadowmap, st + rmat * vec2(0.7320465, 0.6317794)).r); + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.07580382, -0.09224417), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.5784913, -0.002528916), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.192888, 0.4064181), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.6335801, -0.5247476), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(-0.5579782, 0.7491854), dist)).r; + mult += shadow2D(shadowmap, vec3(st + rmat * vec2(0.7320465, 0.6317794), dist)).r; mult *= 0.11111; #else mult *= 0.33333; #endif #else - mult = step(dist, texture2D(shadowmap, st).r); + mult = shadow2D(shadowmap, vec3(st, dist)); #endif - + return mult; } float getLinearDepth(sampler2D depthMap, vec2 tex, float zFarDivZNear) { - float sampleZDivW = texture2D(depthMap, tex).r; - sampleZDivW -= DEPTH_MAX_ERROR; - return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); + float sampleZDivW = texture2D(depthMap, tex).r - DEPTH_MAX_ERROR; + return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); } void main() { float result; - - float depth = getLinearDepth(u_ScreenDepthMap, var_DepthTex, u_ViewInfo.x); - float sampleZ = u_ViewInfo.y * depth; + float depth = getLinearDepth(u_ScreenDepthMap, var_DepthTex, u_ViewInfo.x); vec4 biasPos = vec4(u_ViewOrigin + var_ViewDir * (depth - 0.5 / u_ViewInfo.x), 1.0); - + vec4 shadowpos = u_ShadowMvp * biasPos; - -#if defined(USE_SHADOW_CASCADE) - const float fadeTo = 1.0; - result = fadeTo; -#else - result = 0.0; -#endif - if (all(lessThanEqual(abs(shadowpos.xyz), vec3(abs(shadowpos.w))))) +#if defined(USE_SHADOW_CASCADE) + if (all(lessThan(abs(shadowpos.xyz), vec3(abs(shadowpos.w))))) { - shadowpos.xyz = shadowpos.xyz / shadowpos.w * 0.5 + 0.5; +#endif + shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5); result = PCF(u_ShadowMap, shadowpos.xy, shadowpos.z); - } #if defined(USE_SHADOW_CASCADE) + } else { shadowpos = u_ShadowMvp2 * biasPos; - if (all(lessThanEqual(abs(shadowpos.xyz), vec3(abs(shadowpos.w))))) + if (all(lessThan(abs(shadowpos.xyz), vec3(abs(shadowpos.w))))) { - shadowpos.xyz = shadowpos.xyz / shadowpos.w * 0.5 + 0.5; + shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5); result = PCF(u_ShadowMap2, shadowpos.xy, shadowpos.z); } else { shadowpos = u_ShadowMvp3 * biasPos; - if (all(lessThanEqual(abs(shadowpos.xyz), vec3(abs(shadowpos.w))))) + if (all(lessThan(abs(shadowpos.xyz), vec3(abs(shadowpos.w))))) { - shadowpos.xyz = shadowpos.xyz / shadowpos.w * 0.5 + 0.5; + shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5); result = PCF(u_ShadowMap3, shadowpos.xy, shadowpos.z); - - float fade = clamp(sampleZ / r_shadowCascadeZFar * 10.0 - 9.0, 0.0, 1.0); - result = mix(result, fadeTo, fade); + } + else + { + shadowpos = u_ShadowMvp4 * biasPos; + shadowpos.xyz = shadowpos.xyz * (0.5 / shadowpos.w) + vec3(0.5); + result = PCF(u_ShadowMap4, shadowpos.xy, shadowpos.z); } } } #endif - + gl_FragColor = vec4(vec3(result), 1.0); } diff --git a/SP/code/rend2/tr_backend.c b/SP/code/rend2/tr_backend.c index b038784..3fcb7d9 100644 --- a/SP/code/rend2/tr_backend.c +++ b/SP/code/rend2/tr_backend.c @@ -1617,13 +1617,24 @@ const void *RB_DrawSurfs( const void *data ) { GLSL_BindProgram(&tr.shadowmaskShader); GL_BindToTMU(tr.renderDepthImage, TB_COLORMAP); - GL_BindToTMU(tr.sunShadowDepthImage[0], TB_SHADOWMAP); - GL_BindToTMU(tr.sunShadowDepthImage[1], TB_SHADOWMAP2); - GL_BindToTMU(tr.sunShadowDepthImage[2], TB_SHADOWMAP3); - GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP, backEnd.refdef.sunShadowMvp[0]); - GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP2, backEnd.refdef.sunShadowMvp[1]); - GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP3, backEnd.refdef.sunShadowMvp[2]); + if (r_shadowCascadeZFar->integer != 0) + { + GL_BindToTMU(tr.sunShadowDepthImage[0], TB_SHADOWMAP); + GL_BindToTMU(tr.sunShadowDepthImage[1], TB_SHADOWMAP2); + GL_BindToTMU(tr.sunShadowDepthImage[2], TB_SHADOWMAP3); + GL_BindToTMU(tr.sunShadowDepthImage[3], TB_SHADOWMAP4); + + GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP, backEnd.refdef.sunShadowMvp[0]); + GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP2, backEnd.refdef.sunShadowMvp[1]); + GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP3, backEnd.refdef.sunShadowMvp[2]); + GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP4, backEnd.refdef.sunShadowMvp[3]); + } + else + { + GL_BindToTMU(tr.sunShadowDepthImage[3], TB_SHADOWMAP); + GLSL_SetUniformMat4(&tr.shadowmaskShader, UNIFORM_SHADOWMVP, backEnd.refdef.sunShadowMvp[3]); + } GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWORIGIN, backEnd.refdef.vieworg); { @@ -2177,6 +2188,8 @@ const void *RB_PostProcess(const void *data) FBO_BlitFromTexture(tr.sunShadowDepthImage[1], NULL, NULL, NULL, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 256, 0, 128, 128); FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, NULL, dstBox, NULL, NULL, 0); + VectorSet4(dstBox, 384, 0, 128, 128); + FBO_BlitFromTexture(tr.sunShadowDepthImage[3], NULL, NULL, NULL, dstBox, NULL, NULL, 0); } if (0) diff --git a/SP/code/rend2/tr_bsp.c b/SP/code/rend2/tr_bsp.c index 3dde8f9..76e8731 100644 --- a/SP/code/rend2/tr_bsp.c +++ b/SP/code/rend2/tr_bsp.c @@ -3666,6 +3666,9 @@ void RE_LoadWorldMap( const char *name ) { tr.toneMinAvgMaxLevel[1] = -2.0f; tr.toneMinAvgMaxLevel[2] = 0.0f; + // reset last cascade sun direction so last shadow cascade is rerendered + VectorClear(tr.lastCascadeSunDirection); + tr.worldMapLoaded = qtrue; // load it diff --git a/SP/code/rend2/tr_fbo.c b/SP/code/rend2/tr_fbo.c index c642b73..4070c6e 100644 --- a/SP/code/rend2/tr_fbo.c +++ b/SP/code/rend2/tr_fbo.c @@ -484,7 +484,7 @@ void FBO_Init(void) if (tr.sunShadowDepthImage[0]) { - for ( i = 0; i < 3; i++) + for ( i = 0; i < 4; i++) { tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height); FBO_Bind(tr.sunShadowFbo[i]); diff --git a/SP/code/rend2/tr_glsl.c b/SP/code/rend2/tr_glsl.c index c304f2b..ba75215 100644 --- a/SP/code/rend2/tr_glsl.c +++ b/SP/code/rend2/tr_glsl.c @@ -79,10 +79,12 @@ static uniformInfo_t uniformsInfo[] = { "u_ShadowMap", GLSL_INT }, { "u_ShadowMap2", GLSL_INT }, { "u_ShadowMap3", GLSL_INT }, + { "u_ShadowMap4", GLSL_INT }, { "u_ShadowMvp", GLSL_MAT16 }, { "u_ShadowMvp2", GLSL_MAT16 }, { "u_ShadowMvp3", GLSL_MAT16 }, + { "u_ShadowMvp4", GLSL_MAT16 }, { "u_EnableTextures", GLSL_VEC4 }, @@ -1308,7 +1310,8 @@ void GLSL_InitGPUShaders(void) if (r_shadowFilter->integer >= 2) Q_strcat(extradefines, 1024, "#define USE_SHADOW_FILTER2\n"); - Q_strcat(extradefines, 1024, "#define USE_SHADOW_CASCADE\n"); + if (r_shadowCascadeZFar->integer != 0) + Q_strcat(extradefines, 1024, "#define USE_SHADOW_CASCADE\n"); Q_strcat(extradefines, 1024, va("#define r_shadowMapSize %d\n", r_shadowMapSize->integer)); Q_strcat(extradefines, 1024, va("#define r_shadowCascadeZFar %f\n", r_shadowCascadeZFar->value)); @@ -1326,6 +1329,7 @@ void GLSL_InitGPUShaders(void) GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP, TB_SHADOWMAP); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP2, TB_SHADOWMAP2); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP3, TB_SHADOWMAP3); + GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP4, TB_SHADOWMAP4); qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.shadowmaskShader); diff --git a/SP/code/rend2/tr_image.c b/SP/code/rend2/tr_image.c index 33803ca..cf51f5d 100644 --- a/SP/code/rend2/tr_image.c +++ b/SP/code/rend2/tr_image.c @@ -3179,9 +3179,14 @@ void R_CreateBuiltinImages( void ) { if (r_sunlightMode->integer) { - for ( x = 0; x < 3; x++) + for ( x = 0; x < 4; x++) { tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB); + GL_Bind(tr.sunShadowDepthImage[x]); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); } tr.screenShadowImage = R_CreateImage("*screenShadow", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8); diff --git a/SP/code/rend2/tr_init.c b/SP/code/rend2/tr_init.c index 7642744..1a52d9c 100644 --- a/SP/code/rend2/tr_init.c +++ b/SP/code/rend2/tr_init.c @@ -1364,9 +1364,9 @@ void R_Register( void ) { 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_shadowMapSize = ri.Cvar_Get( "r_shadowMapSize", "1024", CVAR_ARCHIVE | CVAR_LATCH ); - r_shadowCascadeZNear = ri.Cvar_Get( "r_shadowCascadeZNear", "4", CVAR_ARCHIVE | CVAR_LATCH ); - r_shadowCascadeZFar = ri.Cvar_Get( "r_shadowCascadeZFar", "3072", CVAR_ARCHIVE | CVAR_LATCH ); - r_shadowCascadeZBias = ri.Cvar_Get( "r_shadowCascadeZBias", "-320", CVAR_ARCHIVE | CVAR_LATCH ); + r_shadowCascadeZNear = ri.Cvar_Get( "r_shadowCascadeZNear", "8", CVAR_ARCHIVE | CVAR_LATCH ); + r_shadowCascadeZFar = ri.Cvar_Get( "r_shadowCascadeZFar", "1024", CVAR_ARCHIVE | CVAR_LATCH ); + r_shadowCascadeZBias = ri.Cvar_Get( "r_shadowCascadeZBias", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_ignoreDstAlpha = ri.Cvar_Get( "r_ignoreDstAlpha", "1", CVAR_ARCHIVE | CVAR_LATCH ); // diff --git a/SP/code/rend2/tr_local.h b/SP/code/rend2/tr_local.h index e6be278..1bf8958 100644 --- a/SP/code/rend2/tr_local.h +++ b/SP/code/rend2/tr_local.h @@ -408,6 +408,7 @@ enum TB_SPECULARMAP = 4, TB_SHADOWMAP = 5, TB_CUBEMAP = 6, + TB_SHADOWMAP4 = 6, NUM_TEXTURE_BUNDLES = 7 }; @@ -723,10 +724,12 @@ typedef enum UNIFORM_SHADOWMAP, UNIFORM_SHADOWMAP2, UNIFORM_SHADOWMAP3, + UNIFORM_SHADOWMAP4, UNIFORM_SHADOWMVP, UNIFORM_SHADOWMVP2, UNIFORM_SHADOWMVP3, + UNIFORM_SHADOWMVP4, UNIFORM_ENABLETEXTURES, @@ -853,7 +856,7 @@ typedef struct { int num_pshadows; struct pshadow_s *pshadows; - float sunShadowMvp[3][16]; + float sunShadowMvp[4][16]; float sunDir[4]; float sunCol[4]; float sunAmbCol[4]; @@ -1672,7 +1675,7 @@ typedef struct { image_t *calcLevelsImage; image_t *targetLevelsImage; image_t *fixedLevelsImage; - image_t *sunShadowDepthImage[3]; + image_t *sunShadowDepthImage[4]; image_t *screenShadowImage; image_t *screenSsaoImage; image_t *hdrDepthImage; @@ -1689,7 +1692,7 @@ typedef struct { FBO_t *quarterFbo[2]; FBO_t *calcLevelsFbo; FBO_t *targetLevelsFbo; - FBO_t *sunShadowFbo[3]; + FBO_t *sunShadowFbo[4]; FBO_t *screenShadowFbo; FBO_t *screenSsaoFbo; FBO_t *hdrDepthFbo; @@ -1766,6 +1769,8 @@ typedef struct { vec3_t sunLight; // from the sky shader for this level vec3_t sunDirection; + vec3_t lastCascadeSunDirection; + float lastCascadeSunMvp[16]; //----(SA) added float lightGridMulAmbient; // lightgrid multipliers specified in sky shader diff --git a/SP/code/rend2/tr_main.c b/SP/code/rend2/tr_main.c index 815dad1..fcc9db9 100644 --- a/SP/code/rend2/tr_main.c +++ b/SP/code/rend2/tr_main.c @@ -2901,13 +2901,15 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level) break; } - VectorCopy(fd->vieworg, lightOrigin); - + if (level != 3) + VectorCopy(fd->vieworg, lightOrigin); + else + VectorCopy(tr.world->lightGridOrigin, lightOrigin); // Make up a projection VectorScale(lightDir, -1.0f, lightViewAxis[0]); - if (lightViewIndependentOfCameraView) + if (level == 3 || lightViewIndependentOfCameraView) { // Use world up as light view up VectorSet(lightViewAxis[2], 0, 0, 1); @@ -2927,7 +2929,7 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level) // Check if too close to parallel to light direction if (abs(DotProduct(lightViewAxis[2], lightViewAxis[0])) > 0.9f) { - if (lightViewIndependentOfCameraView) + if (level == 3 || lightViewIndependentOfCameraView) { // Use world left as light view up VectorSet(lightViewAxis[2], 0, 1, 0); @@ -2964,56 +2966,116 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level) ClearBounds(lightviewBounds[0], lightviewBounds[1]); - // add view near plane - lx = splitZNear * tan(fd->fov_x * M_PI / 360.0f); - ly = splitZNear * tan(fd->fov_y * M_PI / 360.0f); - VectorMA(fd->vieworg, splitZNear, fd->viewaxis[0], base); - - VectorMA(base, lx, fd->viewaxis[1], point); - VectorMA(point, ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - VectorMA(base, -lx, fd->viewaxis[1], point); - VectorMA(point, ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - VectorMA(base, lx, fd->viewaxis[1], point); - VectorMA(point, -ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - VectorMA(base, -lx, fd->viewaxis[1], point); - VectorMA(point, -ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - - // add view far plane - lx = splitZFar * tan(fd->fov_x * M_PI / 360.0f); - ly = splitZFar * tan(fd->fov_y * M_PI / 360.0f); - VectorMA(fd->vieworg, splitZFar, fd->viewaxis[0], base); - - VectorMA(base, lx, fd->viewaxis[1], point); - VectorMA(point, ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - VectorMA(base, -lx, fd->viewaxis[1], point); - VectorMA(point, ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - VectorMA(base, lx, fd->viewaxis[1], point); - VectorMA(point, -ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); - - VectorMA(base, -lx, fd->viewaxis[1], point); - VectorMA(point, -ly, fd->viewaxis[2], point); - Mat4Transform(lightViewMatrix, point, lightViewPoint); - AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + if (level != 3) + { + // add view near plane + lx = splitZNear * tan(fd->fov_x * M_PI / 360.0f); + ly = splitZNear * tan(fd->fov_y * M_PI / 360.0f); + VectorMA(fd->vieworg, splitZNear, fd->viewaxis[0], base); + + VectorMA(base, lx, fd->viewaxis[1], point); + VectorMA(point, ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + VectorMA(base, -lx, fd->viewaxis[1], point); + VectorMA(point, ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + VectorMA(base, lx, fd->viewaxis[1], point); + VectorMA(point, -ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + VectorMA(base, -lx, fd->viewaxis[1], point); + VectorMA(point, -ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + // add view far plane + lx = splitZFar * tan(fd->fov_x * M_PI / 360.0f); + ly = splitZFar * tan(fd->fov_y * M_PI / 360.0f); + VectorMA(fd->vieworg, splitZFar, fd->viewaxis[0], base); + + VectorMA(base, lx, fd->viewaxis[1], point); + VectorMA(point, ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + VectorMA(base, -lx, fd->viewaxis[1], point); + VectorMA(point, ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + VectorMA(base, lx, fd->viewaxis[1], point); + VectorMA(point, -ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + VectorMA(base, -lx, fd->viewaxis[1], point); + VectorMA(point, -ly, fd->viewaxis[2], point); + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + } + else + { + // use light grid size as level size + // FIXME: could be tighter + vec3_t bounds; + + bounds[0] = tr.world->lightGridSize[0] * tr.world->lightGridBounds[0]; + bounds[1] = tr.world->lightGridSize[1] * tr.world->lightGridBounds[1]; + bounds[2] = tr.world->lightGridSize[2] * tr.world->lightGridBounds[2]; + + point[0] = tr.world->lightGridOrigin[0]; + point[1] = tr.world->lightGridOrigin[1]; + point[2] = tr.world->lightGridOrigin[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0] + bounds[0]; + point[1] = tr.world->lightGridOrigin[1]; + point[2] = tr.world->lightGridOrigin[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0]; + point[1] = tr.world->lightGridOrigin[1] + bounds[1]; + point[2] = tr.world->lightGridOrigin[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0] + bounds[0]; + point[1] = tr.world->lightGridOrigin[1] + bounds[1]; + point[2] = tr.world->lightGridOrigin[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0]; + point[1] = tr.world->lightGridOrigin[1]; + point[2] = tr.world->lightGridOrigin[2] + bounds[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0] + bounds[0]; + point[1] = tr.world->lightGridOrigin[1]; + point[2] = tr.world->lightGridOrigin[2] + bounds[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0]; + point[1] = tr.world->lightGridOrigin[1] + bounds[1]; + point[2] = tr.world->lightGridOrigin[2] + bounds[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + + point[0] = tr.world->lightGridOrigin[0] + bounds[0]; + point[1] = tr.world->lightGridOrigin[1] + bounds[1]; + point[2] = tr.world->lightGridOrigin[2] + bounds[2]; + Mat4Transform(lightViewMatrix, point, lightViewPoint); + AddPointToBounds(lightViewPoint, lightviewBounds[0], lightviewBounds[1]); + } if (!glRefConfig.depthClamp) lightviewBounds[0][0] = lightviewBounds[1][0] - 8192; @@ -3043,8 +3105,8 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level) VectorScale(lightviewBounds[1], worldUnitsPerTexel, lightviewBounds[1]); } - //ri.Printf(PRINT_ALL, "znear %f zfar %f\n", lightviewBounds[0][0], lightviewBounds[1][0]); - //ri.Printf(PRINT_ALL, "fovx %f fovy %f xmin %f xmax %f ymin %f ymax %f\n", fd->fov_x, fd->fov_y, xmin, xmax, ymin, ymax); + //ri.Printf(PRINT_ALL, "level %d znear %f zfar %f\n", level, lightviewBounds[0][0], lightviewBounds[1][0]); + //ri.Printf(PRINT_ALL, "xmin %f xmax %f ymin %f ymax %f\n", lightviewBounds[0][1], lightviewBounds[1][1], -lightviewBounds[1][2], -lightviewBounds[0][2]); } @@ -3185,6 +3247,7 @@ void R_RenderCubemapSide( int cubemapIndex, int cubemapSide, qboolean subscene ) R_RenderSunShadowMaps(&refdef, 0); R_RenderSunShadowMaps(&refdef, 1); R_RenderSunShadowMaps(&refdef, 2); + R_RenderSunShadowMaps(&refdef, 3); } } diff --git a/SP/code/rend2/tr_scene.c b/SP/code/rend2/tr_scene.c index 06e3dc5..72ac184 100644 --- a/SP/code/rend2/tr_scene.c +++ b/SP/code/rend2/tr_scene.c @@ -629,9 +629,30 @@ void RE_RenderScene( const refdef_t *fd ) { // playing with even more shadows if(glRefConfig.framebufferObject && r_sunlightMode->integer && !( fd->rdflags & RDF_NOWORLDMODEL ) && (r_forceSun->integer || tr.sunShadows)) { - R_RenderSunShadowMaps(fd, 0); - R_RenderSunShadowMaps(fd, 1); - R_RenderSunShadowMaps(fd, 2); + if (r_shadowCascadeZFar != 0) + { + R_RenderSunShadowMaps(fd, 0); + R_RenderSunShadowMaps(fd, 1); + R_RenderSunShadowMaps(fd, 2); + } + else + { + Mat4Zero(tr.refdef.sunShadowMvp[0]); + Mat4Zero(tr.refdef.sunShadowMvp[1]); + Mat4Zero(tr.refdef.sunShadowMvp[2]); + } + + // only rerender last cascade if sun has changed position + if (r_forceSun->integer == 2 || !VectorCompare(tr.refdef.sunDir, tr.lastCascadeSunDirection)) + { + VectorCopy(tr.refdef.sunDir, tr.lastCascadeSunDirection); + R_RenderSunShadowMaps(fd, 3); + Mat4Copy(tr.refdef.sunShadowMvp[3], tr.lastCascadeSunMvp); + } + else + { + Mat4Copy(tr.lastCascadeSunMvp, tr.refdef.sunShadowMvp[3]); + } } // playing with cube maps -- Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/iortcw.git _______________________________________________ Pkg-games-commits mailing list Pkg-games-commits@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits