diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/renderergl2/glsl/shadowmask_fp.glsl | 91 | ||||
-rw-r--r-- | src/renderergl2/tr_backend.c | 27 | ||||
-rw-r--r-- | src/renderergl2/tr_bsp.c | 3 | ||||
-rw-r--r-- | src/renderergl2/tr_fbo.c | 2 | ||||
-rw-r--r-- | src/renderergl2/tr_glsl.c | 6 | ||||
-rw-r--r-- | src/renderergl2/tr_image.c | 7 | ||||
-rw-r--r-- | src/renderergl2/tr_init.c | 6 | ||||
-rw-r--r-- | src/renderergl2/tr_local.h | 11 | ||||
-rw-r--r-- | src/renderergl2/tr_main.c | 177 | ||||
-rw-r--r-- | src/renderergl2/tr_scene.c | 27 |
10 files changed, 241 insertions, 116 deletions
diff --git a/src/renderergl2/glsl/shadowmask_fp.glsl b/src/renderergl2/glsl/shadowmask_fp.glsl index b489fef5..8a5597a9 100644 --- a/src/renderergl2/glsl/shadowmask_fp.glsl +++ b/src/renderergl2/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/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index 5761481b..964da39a 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -1123,13 +1123,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); { @@ -1682,6 +1693,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/src/renderergl2/tr_bsp.c b/src/renderergl2/tr_bsp.c index 06075d7b..93302a46 100644 --- a/src/renderergl2/tr_bsp.c +++ b/src/renderergl2/tr_bsp.c @@ -3314,6 +3314,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/src/renderergl2/tr_fbo.c b/src/renderergl2/tr_fbo.c index c642b732..4070c6ef 100644 --- a/src/renderergl2/tr_fbo.c +++ b/src/renderergl2/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/src/renderergl2/tr_glsl.c b/src/renderergl2/tr_glsl.c index ed078ddf..cb00e91c 100644 --- a/src/renderergl2/tr_glsl.c +++ b/src/renderergl2/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 }, @@ -1302,7 +1304,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)); @@ -1320,6 +1323,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/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index b7237f53..75626531 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -2931,9 +2931,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/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index 51cd3b47..d5a0fc4a 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -1153,9 +1153,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/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index 6ade112d..5e6bf768 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -365,6 +365,7 @@ enum TB_SPECULARMAP = 4, TB_SHADOWMAP = 5, TB_CUBEMAP = 6, + TB_SHADOWMAP4 = 6, NUM_TEXTURE_BUNDLES = 7 }; @@ -634,10 +635,12 @@ typedef enum UNIFORM_SHADOWMAP, UNIFORM_SHADOWMAP2, UNIFORM_SHADOWMAP3, + UNIFORM_SHADOWMAP4, UNIFORM_SHADOWMVP, UNIFORM_SHADOWMVP2, UNIFORM_SHADOWMVP3, + UNIFORM_SHADOWMVP4, UNIFORM_ENABLETEXTURES, @@ -761,7 +764,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]; @@ -1535,7 +1538,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; @@ -1552,7 +1555,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; @@ -1624,6 +1627,8 @@ typedef struct { qboolean sunShadows; vec3_t sunLight; // from the sky shader for this level vec3_t sunDirection; + vec3_t lastCascadeSunDirection; + float lastCascadeSunMvp[16]; frontEndCounters_t pc; int frontEndMsec; // not in pc due to clearing issue diff --git a/src/renderergl2/tr_main.c b/src/renderergl2/tr_main.c index 9f58866c..85a56b10 100644 --- a/src/renderergl2/tr_main.c +++ b/src/renderergl2/tr_main.c @@ -2573,14 +2573,16 @@ void R_RenderSunShadowMaps(const refdef_t *fd, int level) //splitZFar = 3072; 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); @@ -2600,7 +2602,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); @@ -2637,56 +2639,117 @@ 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]); + 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]); + - 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; @@ -2716,11 +2779,10 @@ 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]); } - { int firstDrawSurf; @@ -2858,6 +2920,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/src/renderergl2/tr_scene.c b/src/renderergl2/tr_scene.c index 42350365..51bb412e 100644 --- a/src/renderergl2/tr_scene.c +++ b/src/renderergl2/tr_scene.c @@ -499,9 +499,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 |