From c8ba61ca56dfff35774c43f37dc05ec39f8bdac2 Mon Sep 17 00:00:00 2001 From: Faerbit Date: Thu, 28 May 2015 15:03:08 +0200 Subject: [PATCH] Performance optimization for deciding when the directional shadow gets rendered. --- data/shader/phong.fsh | 51 +++++++++++++++++------------------ game/graphics.cc | 63 +++++++++++++++++++++++++------------------ game/graphics.hh | 1 + 3 files changed, 63 insertions(+), 52 deletions(-) diff --git a/data/shader/phong.fsh b/data/shader/phong.fsh index 6ec710a..fffd1d8 100644 --- a/data/shader/phong.fsh +++ b/data/shader/phong.fsh @@ -47,6 +47,7 @@ uniform bool movingTexture; uniform vec2 movement; uniform vec2 movingTextureOffset; uniform float time; +uniform bool sampleDirectionalShadowSwitch; vec2 poissonDisk[16] = vec2[]( vec2( -0.94201624, -0.39906216 ), @@ -171,40 +172,38 @@ void main() // direction lighting float sunAngle = -1.0; - if(length(directionalLightVector)>0.0f) { + if(sampleDirectionalShadowSwitch) { vec3 directionalVector = normalize(directionalLightVector); sunAngle = dot(vec3(0.0, 1.0, 0.0), directionalVector); - if ( sunAngle > 0.0) { - float directionalVisibility = 1.0f; - float directionalIntensity = sunIntensity(sunAngle); - if (distanceToBorder(shadowCoord1.xy) <= 0.5 && distanceToBorder(shadowCoord1.xy) > 0.2) { - if (distanceToBorder(shadowCoord0.xy) <= 0.5 && distanceToBorder(shadowCoord0.xy) > 0.2) { - directionalVisibility = sampleDirectionalShadow(shadowMap_directional0, shadowCoord0, 0.001, directionalIntensity); - } - else if (distanceToBorder(shadowCoord0.xy) <= 0.5 && distanceToBorder(shadowCoord0.xy) > 0.0) { - float directionalVisibility0 = sampleDirectionalShadow(shadowMap_directional0, shadowCoord0, 0.001, directionalIntensity); - float directionalVisibility1 = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.002, directionalIntensity); - directionalVisibility = mix(directionalVisibility0, directionalVisibility1, distanceToBorder(shadowCoord0.xy) * 5); - } - else { - directionalVisibility = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.002, directionalIntensity); - } + float directionalVisibility = 1.0f; + float directionalIntensity = sunIntensity(sunAngle); + if (distanceToBorder(shadowCoord1.xy) <= 0.5 && distanceToBorder(shadowCoord1.xy) > 0.2) { + if (distanceToBorder(shadowCoord0.xy) <= 0.5 && distanceToBorder(shadowCoord0.xy) > 0.2) { + directionalVisibility = sampleDirectionalShadow(shadowMap_directional0, shadowCoord0, 0.001, directionalIntensity); } - else if (distanceToBorder(shadowCoord1.xy) <= 0.5 && distanceToBorder(shadowCoord1.xy) > 0.0) { + else if (distanceToBorder(shadowCoord0.xy) <= 0.5 && distanceToBorder(shadowCoord0.xy) > 0.0) { + float directionalVisibility0 = sampleDirectionalShadow(shadowMap_directional0, shadowCoord0, 0.001, directionalIntensity); float directionalVisibility1 = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.002, directionalIntensity); - float directionalVisibility2 = sampleDirectionalShadow(shadowMap_directional2, shadowCoord2, 0.01, directionalIntensity); - directionalVisibility = mix(directionalVisibility1, directionalVisibility2, distanceToBorder(shadowCoord1.xy) * 5); + directionalVisibility = mix(directionalVisibility0, directionalVisibility1, distanceToBorder(shadowCoord0.xy) * 5); } else { - directionalVisibility = sampleDirectionalShadow(shadowMap_directional2, shadowCoord2, 0.01, directionalIntensity); + directionalVisibility = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.002, directionalIntensity); } - diffuseColor += clamp(dot(normalize(vNormal), directionalVector) - *diffuseFactor*directionalIntensity*sunColor(sunAngle), 0.0, 1.0)*directionalVisibility; - vec3 cameraVector = normalize(camera - vec3(fragPosition)); - specularColor += clamp(pow((dot((cameraVector+directionalVector),normalize(vNormal))/ - (length(cameraVector+directionalVector)*length(normalize(vNormal)))),shininess), 0.0, 1.0) - *specularFactor*directionalIntensity*sunColor(sunAngle)*directionalVisibility; } + else if (distanceToBorder(shadowCoord1.xy) <= 0.5 && distanceToBorder(shadowCoord1.xy) > 0.0) { + float directionalVisibility1 = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.002, directionalIntensity); + float directionalVisibility2 = sampleDirectionalShadow(shadowMap_directional2, shadowCoord2, 0.01, directionalIntensity); + directionalVisibility = mix(directionalVisibility1, directionalVisibility2, distanceToBorder(shadowCoord1.xy) * 5); + } + else { + directionalVisibility = sampleDirectionalShadow(shadowMap_directional2, shadowCoord2, 0.01, directionalIntensity); + } + diffuseColor += clamp(dot(normalize(vNormal), directionalVector) + *diffuseFactor*directionalIntensity*sunColor(sunAngle), 0.0, 1.0)*directionalVisibility; + vec3 cameraVector = normalize(camera - vec3(fragPosition)); + specularColor += clamp(pow((dot((cameraVector+directionalVector),normalize(vNormal))/ + (length(cameraVector+directionalVector)*length(normalize(vNormal)))),shininess), 0.0, 1.0) + *specularFactor*directionalIntensity*sunColor(sunAngle)*directionalVisibility; } // point lights diff --git a/game/graphics.cc b/game/graphics.cc index 8113f73..d8cec90 100644 --- a/game/graphics.cc +++ b/game/graphics.cc @@ -30,6 +30,7 @@ Graphics::Graphics(glm::uvec2 windowSize, float nearPlane, renderFlames = true; renderWorld = true; renderDebug = false; + directionalShadowSwitch = false; } Graphics::Graphics() { @@ -196,6 +197,7 @@ void Graphics::init(Level* level) { lightingShader->setUniform("fogColorRise", level->getFogColourRise()); lightingShader->setUniform("fogColorNight", level->getFogColourNight()); lightingShader->setUniform("ambientColor", level->getAmbientLight()); + lightingShader->setUniform("sampleDirectionalShadowSwitch", false); if(level->getDirectionalLight()) { lightingShader->setUniform("directionalLightVector", level->getDirectionalLight()->getPosition()); @@ -361,37 +363,46 @@ void Graphics::render(double time) } } - // render depth textures for sun - depthShader->use(); glViewport(0, 0, windowSize.x, windowSize.y); - - + + // render depth textures for sun float sunAngle = glm::dot(glm::vec3(0.0f, 1.0f, 0.0f), glm::normalize(level->getDirectionalLight()->getPosition())); glm::vec3 sunVector = (level->getCameraCenter()->getPosition() + level->getDirectionalLight()->getPosition()); - for (unsigned int i = 0; ibind(); - glClear(GL_DEPTH_BUFFER_BIT); - if (sunAngle > 0.0f) { - float projection_size = 0.0f; - switch(i) { - case 0: - projection_size = 10.0f; - break; - case 1: - projection_size = 30.0f; - break; - case 2: - projection_size = farPlane/1.5f; - break; - } - depthViewProjectionMatrices.at(i) = glm::ortho(-projection_size, projection_size, -projection_size, projection_size, -farPlane/1.5f, farPlane/1.5f) * - glm::lookAt(sunVector, level->getCameraCenter()->getPosition(), glm::vec3(0,1,0)); - level->render(depthShader, false, -1, &depthViewProjectionMatrices.at(i)); - if (!framebuffer_directional.at(i)->isFrameBufferObjectComplete()) { - printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); - } + if (sunAngle > 0.0f) { + if (!directionalShadowSwitch) { + lightingShader->use(); + lightingShader->setUniform("sampleDirectionalShadowSwitch", true); + directionalShadowSwitch = true; } + depthShader->use(); + for (unsigned int i = 0; ibind(); + glClear(GL_DEPTH_BUFFER_BIT); + float projection_size = 0.0f; + switch(i) { + case 0: + projection_size = 10.0f; + break; + case 1: + projection_size = 30.0f; + break; + case 2: + projection_size = farPlane/1.5f; + break; + } + depthViewProjectionMatrices.at(i) = glm::ortho(-projection_size, projection_size, -projection_size, projection_size, -farPlane/1.5f, farPlane/1.5f) * + glm::lookAt(sunVector, level->getCameraCenter()->getPosition(), glm::vec3(0,1,0)); + level->render(depthShader, false, -1, &depthViewProjectionMatrices.at(i)); + if (!framebuffer_directional.at(i)->isFrameBufferObjectComplete()) { + printf("Framebuffer incomplete, unknown error occured during shadow generation!\n"); + } + } + } + else if (directionalShadowSwitch) { + lightingShader->use(); + lightingShader->setUniform("sampleDirectionalShadowSwitch", false); + directionalShadowSwitch = false; } } diff --git a/game/graphics.hh b/game/graphics.hh index 0560e27..467c00f 100644 --- a/game/graphics.hh +++ b/game/graphics.hh @@ -84,6 +84,7 @@ class Graphics { bool renderFlames; bool renderDebug; bool renderWorld; + bool directionalShadowSwitch; DebugDraw debugDrawer; SharedArrayBuffer debug_ab; SharedVertexArrayObject debug_vao;