From ce815825a76e29a09738349aa767a339fb2af9d5 Mon Sep 17 00:00:00 2001 From: Tyler Wozniak Date: Tue, 6 May 2014 13:41:22 -0400 Subject: [PATCH] Shadows on Directional Lights are now optional --- source/components/lights.d | 63 ++++++++++--------- source/graphics/adapters/adapter.d | 61 +++++++++--------- .../graphics/shaders/glsl/directionallight.d | 3 +- source/graphics/shaders/shaders.d | 3 + source/utility/config.d | 4 +- 5 files changed, 74 insertions(+), 60 deletions(-) diff --git a/source/components/lights.d b/source/components/lights.d index 7f7b015e..9252f41f 100644 --- a/source/components/lights.d +++ b/source/components/lights.d @@ -16,14 +16,18 @@ class Light : IComponent { private: vec3 _color; + bool _castShadows; public: /// The color the light gives off. mixin( Property!( _color, AccessModifier.Public ) ); + /// If it should cast shadows + mixin( Property!( _castShadows ) ); this( vec3 color ) { this.color = color; + _castShadows = false; } static this() @@ -73,38 +77,41 @@ public: mixin( Property!( _projView ) ); mixin( Property!( _shadowMapSize ) ); - this( vec3 color, vec3 direction ) + this( vec3 color, vec3 direction, bool castShadows ) { this.direction = direction; super( color ); - - // generate framebuffer for shadow map - shadowMapFrameBuffer = 0; - glGenFramebuffers( 1, cast(uint*)&_shadowMapFrameBuffer ); - glBindFramebuffer( GL_FRAMEBUFFER, _shadowMapFrameBuffer ); - - // generate depth texture of shadow map - shadowMapSize = 2048; - glGenTextures( 1, cast(uint*)&_shadowMapTexture ); - glBindTexture( GL_TEXTURE_2D, _shadowMapTexture ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, shadowMapSize, shadowMapSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, null ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); - - glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _shadowMapTexture, 0 ); - - // don't want any info besides depth - glDrawBuffer( GL_NONE ); - // don't want to read from gpu - glReadBuffer( GL_NONE ); - - // check for success - if( glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE ) + this.castShadows = castShadows; + if( castShadows ) { - logFatal("Shadow map frame buffer failure."); - assert(false); + // generate framebuffer for shadow map + shadowMapFrameBuffer = 0; + glGenFramebuffers( 1, cast(uint*)&_shadowMapFrameBuffer ); + glBindFramebuffer( GL_FRAMEBUFFER, _shadowMapFrameBuffer ); + + // generate depth texture of shadow map + shadowMapSize = 2048; + glGenTextures( 1, cast(uint*)&_shadowMapTexture ); + glBindTexture( GL_TEXTURE_2D, _shadowMapTexture ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, shadowMapSize, shadowMapSize, 0, GL_DEPTH_COMPONENT, GL_FLOAT, null ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + + glFramebufferTexture2D( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, _shadowMapTexture, 0 ); + + // don't want any info besides depth + glDrawBuffer( GL_NONE ); + // don't want to read from gpu + glReadBuffer( GL_NONE ); + + // check for success + if( glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE ) + { + logFatal("Shadow map frame buffer failure."); + assert(false); + } } } diff --git a/source/graphics/adapters/adapter.d b/source/graphics/adapters/adapter.d index 8297f032..4a6dd2e1 100644 --- a/source/graphics/adapters/adapter.d +++ b/source/graphics/adapters/adapter.d @@ -264,51 +264,52 @@ public: */ void shadowPass() { - - foreach( light; directionalLights ) { - glBindFramebuffer( GL_FRAMEBUFFER, light.shadowMapFrameBuffer ); - glClear( GL_DEPTH_BUFFER_BIT ); - glViewport( 0, 0, light.shadowMapSize, light.shadowMapSize ); - - // determine the world space volume for all objects - AABB frustum; - foreach( object; scene.objects ) + if( light.castShadows ) { - if( object.mesh && object.stateFlags.drawMesh ) + glBindFramebuffer( GL_FRAMEBUFFER, light.shadowMapFrameBuffer ); + glClear( GL_DEPTH_BUFFER_BIT ); + glViewport( 0, 0, light.shadowMapSize, light.shadowMapSize ); + + // determine the world space volume for all objects + AABB frustum; + foreach( object; scene.objects ) { - frustum.expand( (object.transform.matrix * vec4(object.mesh.boundingBox.min, 1.0f)).xyz ); - frustum.expand( (object.transform.matrix * vec4(object.mesh.boundingBox.max, 1.0f)).xyz ); + if( object.mesh && object.stateFlags.drawMesh ) + { + frustum.expand( (object.transform.matrix * vec4(object.mesh.boundingBox.min, 1.0f)).xyz ); + frustum.expand( (object.transform.matrix * vec4(object.mesh.boundingBox.max, 1.0f)).xyz ); + } } - } - light.calculateProjView( frustum ); + light.calculateProjView( frustum ); - foreach( object; scene.objects ) - { - if( object.mesh && object.stateFlags.drawMesh ) + foreach( object; scene.objects ) { - // set the shader - Shader shader = object.mesh.animated - ? Shaders.animatedShadowMap - : Shaders.shadowMap; + if( object.mesh && object.stateFlags.drawMesh ) + { + // set the shader + Shader shader = object.mesh.animated + ? Shaders.animatedShadowMap + : Shaders.shadowMap; - glUseProgram( shader.programID ); - glBindVertexArray( object.mesh.glVertexArray ); + glUseProgram( shader.programID ); + glBindVertexArray( object.mesh.glVertexArray ); - shader.bindUniformMatrix4fv( shader.WorldViewProjection, - light.projView * object.transform.matrix); + shader.bindUniformMatrix4fv( shader.WorldViewProjection, + light.projView * object.transform.matrix); - if( object.mesh.animated ) - shader.bindUniformMatrix4fvArray( shader.Bones, object.animation.currBoneTransforms ); + if( object.mesh.animated ) + shader.bindUniformMatrix4fvArray( shader.Bones, object.animation.currBoneTransforms ); - glDrawElements( GL_TRIANGLES, object.mesh.numVertices, GL_UNSIGNED_INT, null ); + glDrawElements( GL_TRIANGLES, object.mesh.numVertices, GL_UNSIGNED_INT, null ); - glBindVertexArray(0); + glBindVertexArray(0); + } } + glBindFramebuffer( GL_FRAMEBUFFER, 0 ); } - glBindFramebuffer( GL_FRAMEBUFFER, 0 ); } foreach( light; pointLights ){} diff --git a/source/graphics/shaders/glsl/directionallight.d b/source/graphics/shaders/glsl/directionallight.d index 65a8335c..34ac4d83 100644 --- a/source/graphics/shaders/glsl/directionallight.d +++ b/source/graphics/shaders/glsl/directionallight.d @@ -39,6 +39,7 @@ immutable string directionallightFS = q{ { vec3 color; vec3 direction; + float shadowless; }; in vec4 fPosition_s; @@ -111,6 +112,6 @@ immutable string directionallightFS = q{ // specularIntensity is the light's contribution vec3 specular = ( pow( specularScale, 8 ) * light.color * specularIntensity); - color = shadowValue(position_v) * vec4( ( diffuse + specular ), 1.0f ); + color = max( light.shadowless , shadowValue(position_v) ) * vec4( ( diffuse + specular ), 1.0f ); } }; \ No newline at end of file diff --git a/source/graphics/shaders/shaders.d b/source/graphics/shaders/shaders.d index 4de005f0..af587076 100644 --- a/source/graphics/shaders/shaders.d +++ b/source/graphics/shaders/shaders.d @@ -38,6 +38,7 @@ private enum ShaderUniform LightRadius = "light.radius", LightFalloffRate = "light.falloffRate", LightPosition = "light.pos_v", + LightShadowless = "light.shadowless", EyePosition = "eyePosition_w", /// Animations Bones = "bones", @@ -340,6 +341,7 @@ public: { bindUniform3f( LightDirection, light.direction); bindUniform3f( LightColor, light.color ); + bindUniform1f( LightShadowless, cast(float)(!light.castShadows) ); } /** @@ -349,6 +351,7 @@ public: { bindUniform3f( LightDirection, ( transform * vec4( light.direction, 0.0f ) ).xyz ); bindUniform3f( LightColor, light.color ); + bindUniform1f( LightShadowless, cast(float)(!light.castShadows) ); } /** diff --git a/source/utility/config.d b/source/utility/config.d index 09596122..4b4ede8b 100644 --- a/source/utility/config.d +++ b/source/utility/config.d @@ -87,9 +87,11 @@ static this() { vec3 color; vec3 dir; + bool shadows = false; node.tryFind( "Color", color ); node.tryFind( "Direction", dir ); - return cast(Light)new DirectionalLight( color, dir ); + node.tryFind( "CastShadows", shadows ); + return cast(Light)new DirectionalLight( color, dir, shadows ); } ); constructor.addConstructorMapping( "!Light-Ambient", ( ref Node node ) {