Shadow: Use 4 cascades.

Now that we use GS and textures array it's easier to add a cascade.
4 is still not optimal but I'd like to avoid cascade count inflation as
much as possible ; 4 x 1024x1024 has the bandwidth requirement of the
single 2048x2048 shadowmaps we previously had.
This commit is contained in:
Vincent Lejeune 2014-02-11 21:49:46 +01:00
parent 934d1f10b8
commit 70f89a8bce
4 changed files with 23 additions and 14 deletions

View File

@ -1,8 +1,8 @@
#version 330 core #version 330 core
uniform mat4 ModelViewProjectionMatrix[3]; uniform mat4 ModelViewProjectionMatrix[4];
layout(triangles) in; layout(triangles) in;
layout(triangle_strip, max_vertices=9) out; layout(triangle_strip, max_vertices=12) out;
in vec2 tc[3]; in vec2 tc[3];
@ -10,7 +10,7 @@ out vec2 uv;
void main(void) void main(void)
{ {
for (int j = 0; j<3; j++) for (int j = 0; j<4; j++)
{ {
gl_Layer = j; gl_Layer = j;
for(int i=0; i<3; i++) for(int i=0; i<3; i++)

View File

@ -8,7 +8,7 @@ uniform sampler2DArrayShadow shadowtex;
uniform vec3 direction; uniform vec3 direction;
uniform vec3 col; uniform vec3 col;
uniform mat4 invproj; uniform mat4 invproj;
uniform mat4 shadowmat[3]; uniform mat4 shadowmat[4];
//uniform int hasclouds; //uniform int hasclouds;
//uniform vec2 wind; //uniform vec2 wind;
//uniform float shadowoffset; //uniform float shadowoffset;
@ -26,7 +26,7 @@ vec3 DecodeNormal(vec2 n)
float getShadowFactor(vec3 pos, float bias) float getShadowFactor(vec3 pos, float bias)
{ {
if (pos.z < 10.) if (pos.z < 5.)
{ {
vec4 shadowcoord = (shadowmat[0] * vec4(pos, 1.0)); vec4 shadowcoord = (shadowmat[0] * vec4(pos, 1.0));
shadowcoord /= shadowcoord.w; shadowcoord /= shadowcoord.w;
@ -43,19 +43,26 @@ float getShadowFactor(vec3 pos, float bias)
// bias += smoothstep(0.001, 0.1, moved) * 0.014; // According to the warping // bias += smoothstep(0.001, 0.1, moved) * 0.014; // According to the warping
return texture(shadowtex, vec4(shadowtexcoord, 0., 0.5 * (shadowcoord.z + bias * 0.001) + 0.5)); return texture(shadowtex, vec4(shadowtexcoord, 0., 0.5 * (shadowcoord.z + bias * 0.001) + 0.5));
} }
else if (pos.z < 60) else if (pos.z < 10.)
{ {
vec4 shadowcoord = (shadowmat[1] * vec4(pos, 1.0)); vec4 shadowcoord = (shadowmat[1] * vec4(pos, 1.0));
shadowcoord /= shadowcoord.w; shadowcoord /= shadowcoord.w;
vec2 shadowtexcoord = shadowcoord.xy * 0.5 + 0.5; vec2 shadowtexcoord = shadowcoord.xy * 0.5 + 0.5;
return texture(shadowtex, vec4(shadowtexcoord, 1., 0.5 * (shadowcoord.z + bias * 0.001) + 0.5)); return texture(shadowtex, vec4(shadowtexcoord, 1., 0.5 * (shadowcoord.z + bias * 0.001) + 0.5));
} }
else else if (pos.z < 75.)
{ {
vec4 shadowcoord = (shadowmat[2] * vec4(pos, 1.0)); vec4 shadowcoord = (shadowmat[2] * vec4(pos, 1.0));
shadowcoord /= shadowcoord.w; shadowcoord /= shadowcoord.w;
vec2 shadowtexcoord = shadowcoord.xy * 0.5 + 0.5; vec2 shadowtexcoord = shadowcoord.xy * 0.5 + 0.5;
return texture(shadowtex, vec4(shadowtexcoord, 2., 0.5 * (shadowcoord.z + bias) + 0.5)); return texture(shadowtex, vec4(shadowtexcoord, 2., 0.5 * (shadowcoord.z + bias * 0.001) + 0.5));
}
else
{
vec4 shadowcoord = (shadowmat[3] * vec4(pos, 1.0));
shadowcoord /= shadowcoord.w;
vec2 shadowtexcoord = shadowcoord.xy * 0.5 + 0.5;
return texture(shadowtex, vec4(shadowtexcoord, 3., 0.5 * (shadowcoord.z + bias) + 0.5));
} }
} }

View File

@ -484,22 +484,24 @@ void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb,
const float oldnear = camnode->getNearValue(); const float oldnear = camnode->getNearValue();
float FarValues[] = float FarValues[] =
{ {
5.,
10., 10.,
60., 75.,
oldfar, oldfar,
}; };
float NearValues[] = float NearValues[] =
{ {
oldnear, oldnear,
5.,
10., 10.,
60., 75.,
}; };
const core::matrix4 &SunCamViewMatrix = m_suncam->getViewMatrix(); const core::matrix4 &SunCamViewMatrix = m_suncam->getViewMatrix();
sun_ortho_matrix.clear(); sun_ortho_matrix.clear();
// Build the 3 ortho projection (for the 3 shadow resolution levels) // Build the 3 ortho projection (for the 3 shadow resolution levels)
for (unsigned i = 0; i < 3; i++) for (unsigned i = 0; i < 4; i++)
{ {
camnode->setFarValue(FarValues[i]); camnode->setFarValue(FarValues[i]);
camnode->setNearValue(NearValues[i]); camnode->setNearValue(NearValues[i]);
@ -554,7 +556,7 @@ void IrrDriver::renderShadows(//ShadowImportanceProvider * const sicb,
sun_ortho_matrix.push_back(getVideoDriver()->getTransform(video::ETS_PROJECTION) * getVideoDriver()->getTransform(video::ETS_VIEW)); sun_ortho_matrix.push_back(getVideoDriver()->getTransform(video::ETS_PROJECTION) * getVideoDriver()->getTransform(video::ETS_VIEW));
} }
assert(sun_ortho_matrix.size() == 3); assert(sun_ortho_matrix.size() == 4);
irr_driver->setPhase(SHADOW_PASS); irr_driver->setPhase(SHADOW_PASS);
glDisable(GL_BLEND); glDisable(GL_BLEND);

View File

@ -145,10 +145,10 @@ RTT::RTT()
glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO); glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO);
glGenTextures(1, &shadowColorTex); glGenTextures(1, &shadowColorTex);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowColorTex); glBindTexture(GL_TEXTURE_2D_ARRAY, shadowColorTex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8, 1024, 1024, 3, 0, GL_RED, GL_UNSIGNED_BYTE, 0); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_R8, 1024, 1024, 4, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
glGenTextures(1, &shadowDepthTex); glGenTextures(1, &shadowDepthTex);
glBindTexture(GL_TEXTURE_2D_ARRAY, shadowDepthTex); glBindTexture(GL_TEXTURE_2D_ARRAY, shadowDepthTex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT24, 1024, 1024, 3, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0); glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH_COMPONENT24, 1024, 1024, 4, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, shadowColorTex, 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, shadowColorTex, 0);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowDepthTex, 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowDepthTex, 0);
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER); GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);