From b38e24c3db50a28e3f5c0a365020299caba89e2c Mon Sep 17 00:00:00 2001 From: Faerbit Date: Thu, 4 Dec 2014 14:46:39 +0100 Subject: [PATCH 1/7] Disable culling because it seems to give slightly worse FPS. --- graphics.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/graphics.cc b/graphics.cc index 9f2bf18..0f6845f 100644 --- a/graphics.cc +++ b/graphics.cc @@ -29,7 +29,7 @@ void Graphics::init() { lightingShader = ShaderProgramCreator("phong").attributeLocations( vao->getAttributeLocations()).create(); - depthTexture = SharedTexture2D( new Texture2D(glm::vec2(windowSize.x, windowSize.y), GL_DEPTH24_STENCIL8)); + depthTexture = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH24_STENCIL8)); depthTexture->setMinFilter(GL_LINEAR); depthTexture->setMagFilter(GL_LINEAR); depthTexture->setCompareMode(GL_COMPARE_REF_TO_TEXTURE); @@ -57,7 +57,6 @@ void Graphics::render(Level* level) // render depth texture for sun framebuffer->bind(); glClear(GL_DEPTH_BUFFER_BIT); - glCullFace(GL_FRONT); depthShader->use(); glm::vec3 sunVector = (level->getCameraCenter()->getPosition() + level->getDirectionalLight()->getPosition()); glm::mat4 depthViewProjectionMatrix = glm::ortho(-20, 20, -20, 20, -20, 40) * @@ -71,7 +70,6 @@ void Graphics::render(Level* level) // final render pass glBindFramebuffer(GL_FRAMEBUFFER, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glCullFace(GL_BACK); lightingShader->use(); From e005c974396c2c37a3a2aabe40b5c6502b617964 Mon Sep 17 00:00:00 2001 From: Faerbit Date: Thu, 4 Dec 2014 14:53:07 +0100 Subject: [PATCH 2/7] Implemented poisson sampling. --- Shader/phong.fsh | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/Shader/phong.fsh b/Shader/phong.fsh index 74564e1..5574051 100644 --- a/Shader/phong.fsh +++ b/Shader/phong.fsh @@ -26,6 +26,25 @@ uniform float fogEnd; uniform vec4 fogColor; uniform vec3 cameraCenter; +vec2 poissonDisk[16] = vec2[]( + vec2( -0.94201624, -0.39906216 ), + vec2( 0.94558609, -0.76890725 ), + vec2( -0.094184101, -0.92938870 ), + vec2( 0.34495938, 0.29387760 ), + vec2( -0.91588581, 0.45771432 ), + vec2( -0.81544232, -0.87912464 ), + vec2( -0.38277543, 0.27676845 ), + vec2( 0.97484398, 0.75648379 ), + vec2( 0.44323325, -0.97511554 ), + vec2( 0.53742981, -0.47373420 ), + vec2( -0.26496911, -0.41893023 ), + vec2( 0.79197514, 0.19090188 ), + vec2( -0.24188840, 0.99706507 ), + vec2( -0.81409955, 0.91437590 ), + vec2( 0.19984126, 0.78641367 ), + vec2( 0.14383161, -0.14100790 ) +); + void main() { vec3 ambientColor = ambientFactor * ambientColor; @@ -61,15 +80,12 @@ void main() // shadows float bias = 0.001*tan(acos(clamp(dot(vNormal, -directionalLightVector), 0.0, 1.0))); bias = clamp(bias, 0.0, 0.01); - vec3 biasedShadowCoord = vec3(shadowCoord); - biasedShadowCoord.z = shadowCoord.z - bias; float visibility = 1.0; if (shadowCoord.x > 0.0 && shadowCoord.x < 1.0) { if (shadowCoord.y > 0.0 && shadowCoord.y < 1.0) { - visibility = texture(shadowMap, biasedShadowCoord); - //if (texture(shadowMap, vec3(shadowCoord), bias) < shadowCoord.z) { - //visibility = 0.5; - //} + for (int i=0; i<16; i++) { + visibility -= 0.0625*(1.0-texture(shadowMap, vec3(shadowCoord.xy + poissonDisk[i]/700.0, (shadowCoord.z - bias)/shadowCoord.w))); + } } } From 0cb741dbc33de10d9aaf95b9934a0aa9302db741 Mon Sep 17 00:00:00 2001 From: Faerbit Date: Thu, 4 Dec 2014 15:08:08 +0100 Subject: [PATCH 3/7] Implemented early bailing. --- Shader/phong.fsh | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/Shader/phong.fsh b/Shader/phong.fsh index 5574051..3d9d719 100644 --- a/Shader/phong.fsh +++ b/Shader/phong.fsh @@ -83,8 +83,17 @@ void main() float visibility = 1.0; if (shadowCoord.x > 0.0 && shadowCoord.x < 1.0) { if (shadowCoord.y > 0.0 && shadowCoord.y < 1.0) { - for (int i=0; i<16; i++) { - visibility -= 0.0625*(1.0-texture(shadowMap, vec3(shadowCoord.xy + poissonDisk[i]/700.0, (shadowCoord.z - bias)/shadowCoord.w))); + for (int i=0; i<4; i++) { + visibility -= directionalIntensity/16*(1.0-texture(shadowMap, vec3(shadowCoord.xy + poissonDisk[i]/700.0, (shadowCoord.z - bias)/shadowCoord.w))); + } + if (visibility == 1.0-(directionalIntensity/16)*4) + { + visibility = 1.0-directionalIntensity; + } + else if (visibility != 1.0) { + for (int i=0; i<12; i++) { + visibility -= directionalIntensity/16*(1.0-texture(shadowMap, vec3(shadowCoord.xy + poissonDisk[i]/700.0, (shadowCoord.z - bias)/shadowCoord.w))); + } } } } From 1c687f5759712a43cf439a9a0799d0609078f40f Mon Sep 17 00:00:00 2001 From: Faerbit Date: Thu, 4 Dec 2014 17:19:58 +0100 Subject: [PATCH 4/7] Implemented cascaded shadow mapping. --- Shader/phong.fsh | 53 ++++++++++++++++++++--------- Shader/phong.vsh | 12 +++++-- graphics.cc | 87 +++++++++++++++++++++++++++++++++++++----------- graphics.hh | 8 +++-- 4 files changed, 119 insertions(+), 41 deletions(-) diff --git a/Shader/phong.fsh b/Shader/phong.fsh index 3d9d719..9d78f8f 100644 --- a/Shader/phong.fsh +++ b/Shader/phong.fsh @@ -3,12 +3,16 @@ in vec3 vNormal; in vec2 vTexCoord; in vec4 fragPosition; -in vec4 shadowCoord; +in vec4 shadowCoord_near; +in vec4 shadowCoord_middle; +in vec4 shadowCoord_far; out vec4 oColor; uniform sampler2D uTexture; -uniform sampler2DShadow shadowMap; +uniform sampler2DShadow shadowMap_near; +uniform sampler2DShadow shadowMap_middle; +uniform sampler2DShadow shadowMap_far; uniform vec3 ambientColor; uniform float ambientFactor; uniform float diffuseFactor; @@ -45,6 +49,25 @@ vec2 poissonDisk[16] = vec2[]( vec2( 0.14383161, -0.14100790 ) ); +float sampleShadow(sampler2DShadow shadowMap, vec4 shadowCoord) { + float visibility = 1.0; + float bias = 0.001*tan(acos(clamp(dot(vNormal, -directionalLightVector), 0.0, 1.0))); + bias = clamp(bias, 0.0, 0.01); + for (int i=0; i<4; i++) { + visibility -= directionalIntensity/16*(1.0-texture(shadowMap, vec3(shadowCoord.xy + poissonDisk[i]/700.0, (shadowCoord.z - bias)/shadowCoord.w))); + } + if (visibility == 1.0-(directionalIntensity/16)*4) + { + visibility = 1.0-directionalIntensity; + } + else if (visibility != 1.0) { + for (int i=0; i<12; i++) { + visibility -= directionalIntensity/16*(1.0-texture(shadowMap, vec3(shadowCoord.xy + poissonDisk[i]/700.0, (shadowCoord.z - bias)/shadowCoord.w))); + } + } + return visibility; +} + void main() { vec3 ambientColor = ambientFactor * ambientColor; @@ -78,24 +101,22 @@ void main() } // shadows - float bias = 0.001*tan(acos(clamp(dot(vNormal, -directionalLightVector), 0.0, 1.0))); - bias = clamp(bias, 0.0, 0.01); float visibility = 1.0; - if (shadowCoord.x > 0.0 && shadowCoord.x < 1.0) { - if (shadowCoord.y > 0.0 && shadowCoord.y < 1.0) { - for (int i=0; i<4; i++) { - visibility -= directionalIntensity/16*(1.0-texture(shadowMap, vec3(shadowCoord.xy + poissonDisk[i]/700.0, (shadowCoord.z - bias)/shadowCoord.w))); + if ((shadowCoord_far.x > 0.0 && shadowCoord_far.x < 1.0) && + (shadowCoord_far.y > 0.0 && shadowCoord_far.y < 1.0)) { + if ((shadowCoord_middle.x > 0.0 && shadowCoord_middle.x < 1.0) && + (shadowCoord_middle.y > 0.0 && shadowCoord_middle.y < 1.0)) { + if ((shadowCoord_near.x > 0.0 && shadowCoord_near.x < 1.0) && + (shadowCoord_near.y > 0.0 && shadowCoord_near.y < 1.0)) { + visibility = sampleShadow(shadowMap_near, shadowCoord_near); } - if (visibility == 1.0-(directionalIntensity/16)*4) - { - visibility = 1.0-directionalIntensity; - } - else if (visibility != 1.0) { - for (int i=0; i<12; i++) { - visibility -= directionalIntensity/16*(1.0-texture(shadowMap, vec3(shadowCoord.xy + poissonDisk[i]/700.0, (shadowCoord.z - bias)/shadowCoord.w))); - } + else { + visibility = sampleShadow(shadowMap_middle, shadowCoord_middle); } } + else { + visibility = sampleShadow(shadowMap_far, shadowCoord_far); + } } specularColor *= visibility; diff --git a/Shader/phong.vsh b/Shader/phong.vsh index df35a04..d2f840e 100644 --- a/Shader/phong.vsh +++ b/Shader/phong.vsh @@ -2,7 +2,9 @@ uniform mat4 modelMatrix; uniform mat4 lightingViewProjectionMatrix; -uniform mat4 shadowMVP; +uniform mat4 shadowMVP_near; +uniform mat4 shadowMVP_middle; +uniform mat4 shadowMVP_far; in vec3 aPosition; in vec3 aNormal; @@ -11,13 +13,17 @@ in vec2 aTexCoord; out vec3 vNormal; out vec2 vTexCoord; out vec4 fragPosition; -out vec4 shadowCoord; +out vec4 shadowCoord_near; +out vec4 shadowCoord_middle; +out vec4 shadowCoord_far; void main() { fragPosition = modelMatrix * vec4(aPosition, 1.0); vNormal = inverse(transpose(mat3(modelMatrix))) * aNormal; vTexCoord = aTexCoord; - shadowCoord = shadowMVP * modelMatrix * vec4(aPosition, 1.0); + shadowCoord_near = shadowMVP_near * modelMatrix * vec4(aPosition, 1.0); + shadowCoord_middle = shadowMVP_middle * modelMatrix * vec4(aPosition, 1.0); + shadowCoord_far = shadowMVP_far * modelMatrix * vec4(aPosition, 1.0); gl_Position = lightingViewProjectionMatrix * modelMatrix * vec4(aPosition, 1.0); } diff --git a/graphics.cc b/graphics.cc index 0f6845f..06f3bf6 100644 --- a/graphics.cc +++ b/graphics.cc @@ -29,19 +29,35 @@ void Graphics::init() { lightingShader = ShaderProgramCreator("phong").attributeLocations( vao->getAttributeLocations()).create(); - depthTexture = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH24_STENCIL8)); - depthTexture->setMinFilter(GL_LINEAR); - depthTexture->setMagFilter(GL_LINEAR); - depthTexture->setCompareMode(GL_COMPARE_REF_TO_TEXTURE); - - framebuffer = SharedFrameBufferObject(new FrameBufferObject()); - framebuffer->setDepthTexture(depthTexture); - framebuffer->validate(); - depthShader = ShaderProgramCreator("depth") - .attributeLocations(vao->getAttributeLocations()) - .fragmentDataLocations(framebuffer->getAttachmentLocations()) - .create(); + .attributeLocations(vao->getAttributeLocations()).create(); + + depthTexture_near = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH24_STENCIL8)); + depthTexture_near->setMinFilter(GL_NEAREST); + depthTexture_near->setMagFilter(GL_NEAREST); + depthTexture_near->setCompareMode(GL_COMPARE_REF_TO_TEXTURE); + + framebuffer_near = SharedFrameBufferObject(new FrameBufferObject()); + framebuffer_near->setDepthTexture(depthTexture_near); + framebuffer_near->validate(); + + depthTexture_middle = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH24_STENCIL8)); + depthTexture_middle->setMinFilter(GL_NEAREST); + depthTexture_middle->setMagFilter(GL_NEAREST); + depthTexture_middle->setCompareMode(GL_COMPARE_REF_TO_TEXTURE); + + framebuffer_middle = SharedFrameBufferObject(new FrameBufferObject()); + framebuffer_middle->setDepthTexture(depthTexture_middle); + framebuffer_middle->validate(); + + depthTexture_far = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH24_STENCIL8)); + depthTexture_far->setMinFilter(GL_NEAREST); + depthTexture_far->setMagFilter(GL_NEAREST); + depthTexture_far->setCompareMode(GL_COMPARE_REF_TO_TEXTURE); + + framebuffer_far = SharedFrameBufferObject(new FrameBufferObject()); + framebuffer_far->setDepthTexture(depthTexture_far); + framebuffer_far->validate(); } GLFWwindow* Graphics::getWindow() { @@ -55,15 +71,38 @@ glm::uvec2 Graphics::getWindowSize() { void Graphics::render(Level* level) { // render depth texture for sun - framebuffer->bind(); + // near pass + framebuffer_near->bind(); glClear(GL_DEPTH_BUFFER_BIT); depthShader->use(); glm::vec3 sunVector = (level->getCameraCenter()->getPosition() + level->getDirectionalLight()->getPosition()); - glm::mat4 depthViewProjectionMatrix = glm::ortho(-20, 20, -20, 20, -20, 40) * + glm::mat4 depthViewProjectionMatrix_near = glm::ortho(-5, 5, -5, 5, -5, 5) * glm::lookAt(sunVector, level->getCameraCenter()->getPosition(), glm::vec3(0,1,0)); - depthShader->setUniform("viewProjectionMatrix", depthViewProjectionMatrix); + depthShader->setUniform("viewProjectionMatrix", depthViewProjectionMatrix_near); level->render(depthShader, false); - if (!framebuffer->isFrameBufferObjectComplete()) { + if (!framebuffer_near->isFrameBufferObjectComplete()) { + printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); + } + + // middle pass + framebuffer_middle->bind(); + glClear(GL_DEPTH_BUFFER_BIT); + glm::mat4 depthViewProjectionMatrix_middle = glm::ortho(-20, 20, -20, 20, -20, 20) * + glm::lookAt(sunVector, level->getCameraCenter()->getPosition(), glm::vec3(0,1,0)); + depthShader->setUniform("viewProjectionMatrix", depthViewProjectionMatrix_middle); + level->render(depthShader, false); + if (!framebuffer_middle->isFrameBufferObjectComplete()) { + printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); + } + + // far pass + framebuffer_far->bind(); + glClear(GL_DEPTH_BUFFER_BIT); + glm::mat4 depthViewProjectionMatrix_far = glm::ortho(-farPlane/2.0f, farPlane/2.0f, -farPlane/2.0f, farPlane/2.0f, -farPlane/2.0f, farPlane/2.0f) * + glm::lookAt(sunVector, level->getCameraCenter()->getPosition(), glm::vec3(0,1,0)); + depthShader->setUniform("viewProjectionMatrix", depthViewProjectionMatrix_far); + level->render(depthShader, false); + if (!framebuffer_far->isFrameBufferObjectComplete()) { printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); } @@ -85,10 +124,16 @@ void Graphics::render(Level* level) 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 ); - glm::mat4 depthBiasMVP = biasMatrix*depthViewProjectionMatrix; + glm::mat4 depthBiasMVP_near = biasMatrix*depthViewProjectionMatrix_near; + glm::mat4 depthBiasMVP_middle = biasMatrix*depthViewProjectionMatrix_middle; + glm::mat4 depthBiasMVP_far = biasMatrix*depthViewProjectionMatrix_far; - lightingShader->setUniform("shadowMVP", depthBiasMVP); - lightingShader->setTexture("shadowMap", depthTexture, 1); + lightingShader->setUniform("shadowMVP_near", depthBiasMVP_near); + lightingShader->setTexture("shadowMap_near", depthTexture_near, 1); + lightingShader->setUniform("shadowMVP_middle", depthBiasMVP_middle); + lightingShader->setTexture("shadowMap_middle", depthTexture_middle, 2); + lightingShader->setUniform("shadowMVP_far", depthBiasMVP_far); + lightingShader->setTexture("shadowMap_far", depthTexture_far, 3); //set lighting parameters if (level->getLights().size() > 0) { @@ -142,7 +187,9 @@ void Graphics::render(Level* level) void Graphics::resize(glm::uvec2 windowSize) { this->windowSize = windowSize; - depthTexture->resize(glm::vec2(windowSize.x, windowSize.y)); + depthTexture_near->resize(glm::vec2(windowSize.x, windowSize.y)); + depthTexture_middle->resize(glm::vec2(windowSize.x, windowSize.y)); + depthTexture_far->resize(glm::vec2(windowSize.x, windowSize.y)); } glm::mat4 Graphics::buildFrustum( float phiInDegree, float _near, float _far, float aspectRatio) { diff --git a/graphics.hh b/graphics.hh index 73aa112..a807d11 100644 --- a/graphics.hh +++ b/graphics.hh @@ -30,8 +30,12 @@ class Graphics { GLFWwindow* window; ACGL::OpenGL::SharedShaderProgram lightingShader; ACGL::OpenGL::SharedShaderProgram depthShader; - ACGL::OpenGL::SharedTexture2D depthTexture; - ACGL::OpenGL::SharedFrameBufferObject framebuffer; + ACGL::OpenGL::SharedTexture2D depthTexture_near; + ACGL::OpenGL::SharedFrameBufferObject framebuffer_near; + ACGL::OpenGL::SharedTexture2D depthTexture_middle; + ACGL::OpenGL::SharedFrameBufferObject framebuffer_middle; + ACGL::OpenGL::SharedTexture2D depthTexture_far; + ACGL::OpenGL::SharedFrameBufferObject framebuffer_far; }; #endif From 9e4cc5e4f7a3cf85f76634873df70e697e4bcf2a Mon Sep 17 00:00:00 2001 From: Faerbit Date: Thu, 4 Dec 2014 17:39:35 +0100 Subject: [PATCH 5/7] Setting wrap mode of depthTextures to CLAMP_TO_EDGE to remove seams. --- graphics.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/graphics.cc b/graphics.cc index 06f3bf6..a506a64 100644 --- a/graphics.cc +++ b/graphics.cc @@ -35,6 +35,8 @@ void Graphics::init() { depthTexture_near = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH24_STENCIL8)); depthTexture_near->setMinFilter(GL_NEAREST); depthTexture_near->setMagFilter(GL_NEAREST); + depthTexture_near->setWrapS(GL_CLAMP_TO_EDGE); + depthTexture_near->setWrapT(GL_CLAMP_TO_EDGE); depthTexture_near->setCompareMode(GL_COMPARE_REF_TO_TEXTURE); framebuffer_near = SharedFrameBufferObject(new FrameBufferObject()); @@ -44,6 +46,8 @@ void Graphics::init() { depthTexture_middle = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH24_STENCIL8)); depthTexture_middle->setMinFilter(GL_NEAREST); depthTexture_middle->setMagFilter(GL_NEAREST); + depthTexture_middle->setWrapS(GL_CLAMP_TO_EDGE); + depthTexture_middle->setWrapT(GL_CLAMP_TO_EDGE); depthTexture_middle->setCompareMode(GL_COMPARE_REF_TO_TEXTURE); framebuffer_middle = SharedFrameBufferObject(new FrameBufferObject()); @@ -53,6 +57,8 @@ void Graphics::init() { depthTexture_far = SharedTexture2D( new Texture2D(windowSize, GL_DEPTH24_STENCIL8)); depthTexture_far->setMinFilter(GL_NEAREST); depthTexture_far->setMagFilter(GL_NEAREST); + depthTexture_far->setWrapS(GL_CLAMP_TO_EDGE); + depthTexture_far->setWrapT(GL_CLAMP_TO_EDGE); depthTexture_far->setCompareMode(GL_COMPARE_REF_TO_TEXTURE); framebuffer_far = SharedFrameBufferObject(new FrameBufferObject()); From 8eb0f6719a4cfd634853fa61b5e5fb647af890e4 Mon Sep 17 00:00:00 2001 From: Faerbit Date: Thu, 4 Dec 2014 18:58:16 +0100 Subject: [PATCH 6/7] Now generating Mipmaps for textures. --- material.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/material.cc b/material.cc index b8639fd..d084f5e 100644 --- a/material.cc +++ b/material.cc @@ -3,6 +3,7 @@ Material::Material(std::string filePath, float ambientFactor, float diffuseFactor, float specularFactor, float shininess) { reference = ACGL::OpenGL::Texture2DFileManager::the()->get(ACGL::OpenGL::Texture2DCreator(filePath)); + reference->generateMipmaps(); this->ambientFactor = ambientFactor; this->diffuseFactor = diffuseFactor; this->specularFactor = specularFactor; From b9b7a6e7b4379484c8fbcfc44b308fa0da4d7b6d Mon Sep 17 00:00:00 2001 From: Faerbit Date: Fri, 5 Dec 2014 00:57:17 +0100 Subject: [PATCH 7/7] Put some code in a function. --- Shader/phong.fsh | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/Shader/phong.fsh b/Shader/phong.fsh index 9d78f8f..efe797c 100644 --- a/Shader/phong.fsh +++ b/Shader/phong.fsh @@ -68,6 +68,12 @@ float sampleShadow(sampler2DShadow shadowMap, vec4 shadowCoord) { return visibility; } +float distanceToBorder(vec2 vector) { + float xDistance = min(vector.x, 1.0-vector.x); + float yDistance = min(vector.y, 1.0-vector.y); + return min(xDistance, yDistance); +} + void main() { vec3 ambientColor = ambientFactor * ambientColor; @@ -102,22 +108,17 @@ void main() // shadows float visibility = 1.0; - if ((shadowCoord_far.x > 0.0 && shadowCoord_far.x < 1.0) && - (shadowCoord_far.y > 0.0 && shadowCoord_far.y < 1.0)) { - if ((shadowCoord_middle.x > 0.0 && shadowCoord_middle.x < 1.0) && - (shadowCoord_middle.y > 0.0 && shadowCoord_middle.y < 1.0)) { - if ((shadowCoord_near.x > 0.0 && shadowCoord_near.x < 1.0) && - (shadowCoord_near.y > 0.0 && shadowCoord_near.y < 1.0)) { + if (distanceToBorder(shadowCoord_middle.xy) <= 0.5 && distanceToBorder(shadowCoord_middle.xy) > 0.0) { + if (distanceToBorder(shadowCoord_near.xy) <= 0.5 && distanceToBorder(shadowCoord_near.xy) > 0.0) { visibility = sampleShadow(shadowMap_near, shadowCoord_near); - } - else { - visibility = sampleShadow(shadowMap_middle, shadowCoord_middle); - } } else { - visibility = sampleShadow(shadowMap_far, shadowCoord_far); + visibility = sampleShadow(shadowMap_middle, shadowCoord_middle); } } + else { + visibility = sampleShadow(shadowMap_far, shadowCoord_far); + } specularColor *= visibility; diffuseColor *= visibility;