From ce815825a76e29a09738349aa767a339fb2af9d5 Mon Sep 17 00:00:00 2001 From: Tyler Wozniak Date: Tue, 6 May 2014 13:41:22 -0400 Subject: [PATCH 1/2] 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 ) { From d3d95169a75d5581974dd989d46c27ac2f2da8f9 Mon Sep 17 00:00:00 2001 From: Tyler Wozniak Date: Wed, 14 May 2014 14:33:51 -0400 Subject: [PATCH 2/2] Working rendering is better than optimized rendering. Normals no longer decoded in order to fix weird pepper effect. --- source/graphics/adapters/adapter.d | 2 +- source/graphics/shaders/glsl/directionallight.d | 2 +- source/graphics/shaders/glsl/geometry.d | 4 ++-- source/graphics/shaders/glsl/pointlight.d | 2 +- source/utility/input.d | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/graphics/adapters/adapter.d b/source/graphics/adapters/adapter.d index 4a6dd2e1..0cbcc7b7 100644 --- a/source/graphics/adapters/adapter.d +++ b/source/graphics/adapters/adapter.d @@ -119,7 +119,7 @@ public: glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); glBindTexture( GL_TEXTURE_2D, _normalRenderTexture ); - glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB16F, width, height, 0, GL_RGB, GL_FLOAT, null ); + glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_FLOAT, null ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); diff --git a/source/graphics/shaders/glsl/directionallight.d b/source/graphics/shaders/glsl/directionallight.d index 34ac4d83..d359145a 100644 --- a/source/graphics/shaders/glsl/directionallight.d +++ b/source/graphics/shaders/glsl/directionallight.d @@ -90,7 +90,7 @@ immutable string directionallightFS = q{ { vec3 textureColor = texture( diffuseTexture, fUV ).xyz; float specularIntensity = texture( diffuseTexture, fUV ).w; - vec3 normal_v = decode(texture( normalTexture, fUV ).xy); + vec3 normal_v = texture( normalTexture, fUV ).xyz; vec3 lightDir_v = -normalize( light.direction ); // Reconstruct position from Depth diff --git a/source/graphics/shaders/glsl/geometry.d b/source/graphics/shaders/glsl/geometry.d index 34b48ef4..b8478f94 100644 --- a/source/graphics/shaders/glsl/geometry.d +++ b/source/graphics/shaders/glsl/geometry.d @@ -48,7 +48,7 @@ immutable string geometryFS = q{ flat in uint fObjectId; layout( location = 0 ) out vec4 color; - layout( location = 1 ) out vec3 normal_v; + layout( location = 1 ) out vec4 normal_v; uniform sampler2D diffuseTexture; uniform sampler2D normalTexture; @@ -78,7 +78,7 @@ immutable string geometryFS = q{ // specular intensity vec3 specularSample = texture( specularTexture, fUV ).xyz; color.w = ( specularSample.x + specularSample.y + specularSample.z ) / 3; - normal_v = vec3( encode( calculateMappedNormal()), float(fObjectId) ); + normal_v = vec4( calculateMappedNormal(), float(fObjectId) ); } }; diff --git a/source/graphics/shaders/glsl/pointlight.d b/source/graphics/shaders/glsl/pointlight.d index 05ad4669..459f5f7a 100644 --- a/source/graphics/shaders/glsl/pointlight.d +++ b/source/graphics/shaders/glsl/pointlight.d @@ -71,7 +71,7 @@ immutable string pointlightFS = q{ vec2 UV = ( ( fPosition_s.xy / fPosition_s.w ) + 1 ) / 2; vec3 textureColor = texture( diffuseTexture, UV ).xyz; float specularIntensity = texture( diffuseTexture, UV ).w; - vec3 normal_v = decode(texture( normalTexture, UV ).xy); + vec3 normal_v = texture( normalTexture, UV ).xyz; // Reconstruct position from depth float depth = texture( depthTexture, UV ).x; diff --git a/source/utility/input.d b/source/utility/input.d index 03cb73f8..d19cab30 100644 --- a/source/utility/input.d +++ b/source/utility/input.d @@ -435,7 +435,7 @@ public static: { glBindFramebuffer( GL_FRAMEBUFFER, Graphics.deferredFrameBuffer ); glReadBuffer( GL_COLOR_ATTACHMENT1 ); - glReadPixels( x, y, 1, 1, GL_BLUE, GL_FLOAT, &fId); + glReadPixels( x, y, 1, 1, GL_ALPHA, GL_FLOAT, &fId); uint id = cast(int)(fId); glBindFramebuffer( GL_FRAMEBUFFER, 0 );