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
uniform mat4 ModelViewProjectionMatrix[3];
uniform mat4 ModelViewProjectionMatrix[4];
layout(triangles) in;
layout(triangle_strip, max_vertices=9) out;
layout(triangle_strip, max_vertices=12) out;
in vec2 tc[3];
@ -10,7 +10,7 @@ out vec2 uv;
void main(void)
{
for (int j = 0; j<3; j++)
for (int j = 0; j<4; j++)
{
gl_Layer = j;
for(int i=0; i<3; i++)

View File

@ -8,7 +8,7 @@ uniform sampler2DArrayShadow shadowtex;
uniform vec3 direction;
uniform vec3 col;
uniform mat4 invproj;
uniform mat4 shadowmat[3];
uniform mat4 shadowmat[4];
//uniform int hasclouds;
//uniform vec2 wind;
//uniform float shadowoffset;
@ -26,7 +26,7 @@ vec3 DecodeNormal(vec2 n)
float getShadowFactor(vec3 pos, float bias)
{
if (pos.z < 10.)
if (pos.z < 5.)
{
vec4 shadowcoord = (shadowmat[0] * vec4(pos, 1.0));
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
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));
shadowcoord /= shadowcoord.w;
vec2 shadowtexcoord = shadowcoord.xy * 0.5 + 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));
shadowcoord /= shadowcoord.w;
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();
float FarValues[] =
{
5.,
10.,
60.,
75.,
oldfar,
};
float NearValues[] =
{
oldnear,
5.,
10.,
60.,
75.,
};
const core::matrix4 &SunCamViewMatrix = m_suncam->getViewMatrix();
sun_ortho_matrix.clear();
// 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->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));
}
assert(sun_ortho_matrix.size() == 3);
assert(sun_ortho_matrix.size() == 4);
irr_driver->setPhase(SHADOW_PASS);
glDisable(GL_BLEND);

View File

@ -145,10 +145,10 @@ RTT::RTT()
glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO);
glGenTextures(1, &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);
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_DEPTH_ATTACHMENT, shadowDepthTex, 0);
GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);