summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/renderergl2/glsl/shadowmask_fp.glsl91
-rw-r--r--src/renderergl2/tr_backend.c27
-rw-r--r--src/renderergl2/tr_bsp.c3
-rw-r--r--src/renderergl2/tr_fbo.c2
-rw-r--r--src/renderergl2/tr_glsl.c6
-rw-r--r--src/renderergl2/tr_image.c7
-rw-r--r--src/renderergl2/tr_init.c6
-rw-r--r--src/renderergl2/tr_local.h11
-rw-r--r--src/renderergl2/tr_main.c177
-rw-r--r--src/renderergl2/tr_scene.c27
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