From 52a36c9b18b0de3701f4e62b774937ca87ed108a Mon Sep 17 00:00:00 2001 From: Faerbit Date: Sun, 31 May 2015 17:36:21 +0200 Subject: [PATCH] Added additional directional shadow maps for better looking sun shadows. --- data/shader/phong.fsh | 61 ++++++++++++++++++++++++++++++++----------- data/shader/phong.vsh | 4 +++ game/graphics.cc | 26 +++++++++++------- 3 files changed, 66 insertions(+), 25 deletions(-) diff --git a/data/shader/phong.fsh b/data/shader/phong.fsh index edd5190..29b199c 100644 --- a/data/shader/phong.fsh +++ b/data/shader/phong.fsh @@ -6,6 +6,8 @@ in vec4 fragPosition; in vec4 shadowCoord0; in vec4 shadowCoord1; in vec4 shadowCoord2; +in vec4 shadowCoord3; +in vec4 shadowCoord4; out vec4 oColor; @@ -13,6 +15,8 @@ uniform sampler2D uTexture; uniform sampler2DShadow shadowMap_directional0; uniform sampler2DShadow shadowMap_directional1; uniform sampler2DShadow shadowMap_directional2; +uniform sampler2DShadow shadowMap_directional3; +uniform sampler2DShadow shadowMap_directional4; uniform samplerCubeShadow shadowMap_cube0; uniform samplerCubeShadow shadowMap_cube1; uniform samplerCubeShadow shadowMap_cube2; @@ -210,26 +214,46 @@ void main() sunAngle = dot(vec3(0.0, 1.0, 0.0), directionalVector); 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); + if (distanceToBorder(shadowCoord3.xy) <= 0.5 && distanceToBorder(shadowCoord3.xy) > 0.2) { + if (distanceToBorder(shadowCoord2.xy) <= 0.5 && distanceToBorder(shadowCoord2.xy) > 0.2) { + 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.001, directionalIntensity); + directionalVisibility = mix(directionalVisibility0, directionalVisibility1, distanceToBorder(shadowCoord0.xy) * 5); + } + else { + directionalVisibility = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.001, directionalIntensity); + } + } + else if (distanceToBorder(shadowCoord1.xy) <= 0.5 && distanceToBorder(shadowCoord1.xy) > 0.0) { + float directionalVisibility1 = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.001, directionalIntensity); + float directionalVisibility2 = sampleDirectionalShadow(shadowMap_directional2, shadowCoord2, 0.002, directionalIntensity); + directionalVisibility = mix(directionalVisibility1, directionalVisibility2, distanceToBorder(shadowCoord1.xy) * 5); + } + else { + directionalVisibility = sampleDirectionalShadow(shadowMap_directional2, shadowCoord2, 0.002, 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 if (distanceToBorder(shadowCoord2.xy) <= 0.5 && distanceToBorder(shadowCoord2.xy) > 0.0) { + float directionalVisibility2 = sampleDirectionalShadow(shadowMap_directional2, shadowCoord2, 0.002, directionalIntensity); + float directionalVisibility3 = sampleDirectionalShadow(shadowMap_directional3, shadowCoord3, 0.005, directionalIntensity); + directionalVisibility = mix(directionalVisibility2, directionalVisibility3, distanceToBorder(shadowCoord2.xy) * 5); } else { - directionalVisibility = sampleDirectionalShadow(shadowMap_directional1, shadowCoord1, 0.002, directionalIntensity); + directionalVisibility = sampleDirectionalShadow(shadowMap_directional3, shadowCoord3, 0.005, directionalIntensity); } } - 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 if (distanceToBorder(shadowCoord3.xy) <= 0.5 && distanceToBorder(shadowCoord3.xy) > 0.0) { + float directionalVisibility3 = sampleDirectionalShadow(shadowMap_directional3, shadowCoord3, 0.005, directionalIntensity); + float directionalVisibility4 = sampleDirectionalShadow(shadowMap_directional4, shadowCoord4, 0.01, directionalIntensity); + directionalVisibility = mix(directionalVisibility3, directionalVisibility4, distanceToBorder(shadowCoord3.xy) * 5); } else { - directionalVisibility = sampleDirectionalShadow(shadowMap_directional2, shadowCoord2, 0.01, directionalIntensity); + directionalVisibility = sampleDirectionalShadow(shadowMap_directional4, shadowCoord4, 0.01, directionalIntensity); } diffuseColor += clamp(dot(normalize(vNormal), directionalVector) *diffuseFactor*directionalIntensity*sunColor(sunAngle), 0.0, 1.0)*directionalVisibility; @@ -242,7 +266,14 @@ void main() // point lights float visibility = 1.0; for(int i = 0; igetPhysics()->getWorld()->setDebugDrawer(&debugDrawer); - depth_directionalMaps = std::vector(3); - framebuffer_directional = std::vector(3); + depth_directionalMaps = std::vector(5); + framebuffer_directional = std::vector(5); for (unsigned int i = 0; isetMinFilter(GL_NEAREST); @@ -235,20 +235,20 @@ void Graphics::bindTextureUnits(){ if (level->getLights()->size() > 0) { for(unsigned int i = 0; isetTexture("shadowMap_cube" + std::to_string(i), depth_cubeMaps.at(i), textureCount + i + 5); + lightingShader->setTexture("shadowMap_cube" + std::to_string(i), depth_cubeMaps.at(i), textureCount + i + 7); } } flamePostShader->use(); - flamePostShader->setTexture("light_fbo", light_fbo_color_texture, textureCount + 15); + flamePostShader->setTexture("light_fbo", light_fbo_color_texture, textureCount + 17); skydomeShader->use(); - skydomeShader->setTexture("dayTexture", level->getSkydome()->getDayTexture(), textureCount + 16); - skydomeShader->setTexture("nightTexture", level->getSkydome()->getNightTexture(), textureCount + 17); + skydomeShader->setTexture("dayTexture", level->getSkydome()->getDayTexture(), textureCount + 18); + skydomeShader->setTexture("nightTexture", level->getSkydome()->getNightTexture(), textureCount + 19); loadingShader->use(); - loadingShader->setTexture("screen", loadingScreen, textureCount + 18); - loadingShader->setTexture("screenContinue", loadingContinueScreen, textureCount + 19); - printf("This application used %d texture units.\n", textureCount + 19); + loadingShader->setTexture("screen", loadingScreen, textureCount + 20); + loadingShader->setTexture("screenContinue", loadingContinueScreen, textureCount + 21); + printf("This application used %d texture units.\n", textureCount + 21); } void Graphics::renderLoadingScreen() { @@ -385,9 +385,15 @@ void Graphics::render(double time) projection_size = 10.0f; break; case 1: - projection_size = 30.0f; + projection_size = 20.0f; break; case 2: + projection_size = 40.0f; + break; + case 3: + projection_size = 60.0f; + break; + case 4: projection_size = farPlane/1.5f; break; }