Trying to make a more specific topic to my problem, since I've realized my lighting was actually correct and has been correct (thank you, everyone!), but that my Shadow Mapping leaves something to be desired (as it's not working at all). It looks like the FBO/Shadow Map is rendering/creating the Shadow Map correctly, but that my use of it in my final Shader.
The basic idea is that I have two shader programs -- one renders the scene without shadows into the depth buffer of an FBO (or into a texture if the hardware isn't GL 3.0), and the second mixes that with the way the scene should be rendered.
Here's what the scene looks like, presently (normal view):

And this is the what the scene looks like from the Light's View:

The second uses the same projection and modelview matrices used by the Depth Buffer capture to render -- so it should be spot on, but here it looks like it's flipped the wrong way.
In the bottom right of both images, I'm just rendering the resulting Shadow Map on top of the scene post-final shader-render.
The code process is essentially:
1) Setup Shader Program to Grab Shadow Map
2) Run through rendering of all objects that generate shadows
3) Setup Shader Program to render everything AND shadow map on top of it
4) Render the Shadow Map in the bottom right corner and the other text data on the top-left.
Let's assume that I created the Shadow Map right -- and we can see the rendering of it on the bottom right. The rendering of it seems to be problematic.
Here's what my overall code looks like.
[source lang="csharp"] Rendering.ActivateShadowTextureUnit(); //Set's active Texture Unit to Unit 1 Rendering.EnableTextures(); //Enable Textures Gl.glBindTexture( Gl.GL_TEXTURE_2D, ShadowMapTextureID[0] ); //Uses the image that is rendered in the bottom right hand corner Rendering.ActivatePrimaryTextureUnit(); //Now activate the primary texture unit, where we render our normal textures in (Unit 0) Gl.glUseProgram( ViewerRenderProgram ); //Use the rendering GL Program Int32 LightModelViewProjectionMatrixLocation = Gl.glGetUniformLocation( ViewerRenderProgram, "LightModelViewProjectionMatrix" ); Gl.glUniformMatrix4fv( LightModelViewProjectionMatrixLocation, 1, Gl.GL_FALSE, LightProjectionViewMatrix ); //This is the Projection Matrix used to render light from (poorly named, sorry) Int32 WorldMatrixLocation = Gl.glGetUniformLocation( ViewerRenderProgram, "WorldMatrix" ); Gl.glUniformMatrix4fv( WorldMatrixLocation, 1, Gl.GL_FALSE, WorldMatrix ); //This is the World ModelView Matrix Int32 DiffuseMapLocation = Gl.glGetUniformLocation( ViewerRenderProgram, "DiffuseMap" ); Gl.glUniform1i( DiffuseMapLocation, 0 ); //Texture Unit 0 (where our normal textures are loaded and rendered through Int32 ShadowMapLocation = Gl.glGetUniformLocation( ViewerRenderProgram, "ShadowMap" ); Gl.glUniform1i( ShadowMapLocation, 1 ); //Texture Unit 1 (where the Shadow Map is currently bound to) Int32 MinimumShadowLocation = Gl.glGetUniformLocation( ViewerRenderProgram, "MinimumShadow" ); Gl.glUniform1f( MinimumShadowLocation, 0.8f ); //This is to run against the lambert as the "max value" -- eventually, it will be variable[/source]
Here's how I grab my Lighting Matrices...
[source lang="csharp"] Gl.glPushMatrix(); Gl.glMatrixMode( Gl.GL_PROJECTION ); Gl.glLoadIdentity(); Gl.glOrtho( -Configuration.Instance.RenderingSettings.Depth, Configuration.Instance.RenderingSettings.Depth, -Configuration.Instance.RenderingSettings.Depth, Configuration.Instance.RenderingSettings.Depth, -Configuration.Instance.RenderingSettings.Depth * 2.0d * Configuration.Instance.RenderingSettings.Zoom, Configuration.Instance.RenderingSettings.Depth * 2.0d * Configuration.Instance.RenderingSettings.Zoom ); Gl.glMatrixMode( Gl.GL_MODELVIEW ); Gl.glLoadIdentity(); Gl.glScaled( Tile.DIMENSION * Configuration.Instance.RenderingSettings.Zoom, Tile.DIMENSION * Configuration.Instance.RenderingSettings.Zoom, Tile.DIMENSION * Configuration.Instance.RenderingSettings.Zoom ); Gl.glRotated( -90.0d, 1.0d, 0.0d, 0.0d ); Gl.glRotated( Configuration.Instance.RenderingSettings.LightAngle, 1.0d, 0.0d, 0.0d ); Gl.glRotated( -90.0d, 0.0d, 0.0d, 1.0d ); Gl.glGetFloatv( Gl.GL_PROJECTION_MATRIX, LightProjectionViewMatrix ); Gl.glPopMatrix();[/source]
And this is the World Matrix:
[source lang="csharp"] Gl.glPushMatrix(); Gl.glMatrixMode( Gl.GL_MODELVIEW ); Gl.glLoadIdentity(); Gl.glScaled( Tile.DIMENSION * Configuration.Instance.RenderingSettings.Zoom, Tile.DIMENSION * Configuration.Instance.RenderingSettings.Zoom, Tile.DIMENSION * Configuration.Instance.RenderingSettings.Zoom ); Gl.glRotated( -Configuration.Instance.RenderingSettings.Tilt, 1.0f, 0.0f, 0.0f ); Gl.glRotated( Configuration.Instance.RenderingSettings.Rotation, 0.0f, 0.0f, 1.0f ); Gl.glTranslated( -pX, -pY, -pZ ); //pX, pY, pZ is the "center" of the scene that I render at Gl.glGetFloatv( Gl.GL_MODELVIEW_MATRIX, WorldMatrix ); Gl.glPophMatrix();[/source]
And finally, my Shader Code looks something like this:
[source lang="cpp"]//VERTEX uniform mat4 LightModelViewProjectionMatrix; uniform mat4 WorldMatrix; varying vec3 Normal; varying vec4 LightCoordinate; // Position in model view projection space from the lights view. varying vec4 WorldPosition; // Position in world space. void main() { Normal = gl_Normal; WorldPosition = WorldMatrix * gl_Vertex; LightCoordinate = LightModelViewProjectionMatrix * gl_Vertex; gl_Position = ftransform(); // Transform via fixed function into the viewer's view gl_TexCoord[0] = gl_MultiTexCoord0; }//FRAGMENT uniform sampler2D DiffuseMap; uniform sampler2D ShadowMap; uniform mat4 WorldMatrix; uniform float MinimumShadow; varying vec3 Normal; varying vec4 LightCoordinate; varying vec4 WorldPosition; void main() { // Direct lighting // ------------------------------ vec4 Color = gl_LightSource[0].ambient; vec3 l = normalize(gl_LightSource[0].position.xyz); // direction to the light source vec3 view_normal = normalize(gl_NormalMatrix * Normal); vec3 view_light_direction = normalize(vec3(gl_LightSource[0].position)); //(WorldMatrix * vec4( LightPosition.x, LightPosition.y, LightPosition.z, 0 ) ).xyz; //float lambert = max(dot(view_normal, view_light_direction), MinimumShadow); float lambert = max(dot(Normal, l), MinimumShadow); Color.xyz *= lambert; //Blend in Color from primary texture unit Color.wxyz *= texture2D(DiffuseMap, vec2(gl_TexCoord[0])).wxyz; // Shadow mapping // ------------------------------ vec4 lcoord = LightCoordinate; // Fragment position in light space. lcoord /= lcoord.w; // Project to cartesian space lcoord.xy = lcoord.xy * 0.5 + 0.5; // Scale since light clipping space is in [-1,1] but texture space is [0,1] float fragmentDepth = lcoord.w; // Depth of the fragment in light space. float shadowMapDepth = texture2D(ShadowMap, lcoord.xy).x; // Depth in the shadow map. float eps = 0.1; // depth bias float shadow = fragmentDepth - eps > shadowMapDepth ? 0.5: 1.0; gl_FragColor = Color * shadow;[/source]
I had assumed before, when I had a fixed position light (not a directional one), that I had been showing shadows -- this was just an error on my part. If I commented out everything under "Shadow Mapping" in the Fragment Shader, no difference was made! So, my lighting is correct. Getting the Shadow Map appears to be correct. The problem appears to be in how I'm rendering it. Perhaps I'm making a mistake? Also going to include my Shadow Map Capture stuff as well:
[source lang="cpp"]//VERTEX varying vec4 LightPosition; void main() { gl_Position = ftransform(); LightPosition = gl_Position; }//FRAGMENT varying vec4 LightPosition; void main() { gl_FragColor = vec4(LightPosition.z / LightPosition.w); }[/source]
Hopefully someone can give me some insight into what I'm doing wrong. I've been struggling to get this working for a while and I've had a lot of help from various members in the community. The issue I have appears to be the *actual* shadow mapping. And again, the resulting texture of the Shadow Map is showing in the bottom right hand corner of the screen (with glColor3f(1.0f, 1.0f, 1.0f);).
Here's also how I'm constructing the actual FBO and using it...
[source lang="csharp"] Gl.glGenTextures( 1, ShadowMapTextureID ); Gl.glBindTexture( Gl.GL_TEXTURE_2D, ShadowMapTextureID[0] ); Gl.glTexImage2D( Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, Configuration.Instance.RenderingSettings.ShadowDimension, Configuration.Instance.RenderingSettings.ShadowDimension, 0, Gl.GL_RGBA, Gl.GL_FLOAT, IntPtr.Zero ); Gl.glTexParameteri( Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_LINEAR ); Gl.glTexParameteri( Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_LINEAR ); Gl.glTexParameteri( Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP_TO_BORDER ); Gl.glTexParameteri( Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP_TO_BORDER ); Gl.glTexParameterfv( Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_BORDER_COLOR, Video.Instance.ClearColor ); Gl.glGenTextures( 1, DepthMapTextureID ); Gl.glBindTexture( Gl.GL_TEXTURE_2D, DepthMapTextureID[0] ); Gl.glTexImage2D( Gl.GL_TEXTURE_2D, 0, Gl.GL_DEPTH_COMPONENT24, Configuration.Instance.RenderingSettings.ShadowDimension, Configuration.Instance.RenderingSettings.ShadowDimension, 0, Gl.GL_DEPTH_COMPONENT, Gl.GL_UNSIGNED_BYTE, IntPtr.Zero ); Gl.glTexParameteri( Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST ); Gl.glTexParameteri( Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST ); ShadingMethodsAllowed = ShadingMethods.None | ShadingMethods.NonFBO; Gl.glGenFramebuffersEXT( 1, ShadowMapFramebuffer ); Gl.glBindFramebufferEXT( Gl.GL_FRAMEBUFFER_EXT, ShadowMapFramebuffer[0] ); Gl.glFramebufferTexture2DEXT( Gl.GL_FRAMEBUFFER_EXT, Gl.GL_COLOR_ATTACHMENT0_EXT, Gl.GL_TEXTURE_2D, ShadowMapTextureID[0], 0 ); Gl.glFramebufferTexture2DEXT( Gl.GL_FRAMEBUFFER_EXT, Gl.GL_DEPTH_ATTACHMENT_EXT, Gl.GL_TEXTURE_2D, DepthMapTextureID[0], 0 ); string ExtensionsSupported = Gl.glGetString( Gl.GL_EXTENSIONS ); if ( Gl.glCheckFramebufferStatusEXT( Gl.GL_FRAMEBUFFER_EXT ) != Gl.GL_FRAMEBUFFER_COMPLETE_EXT ) { ShadingMethodsAllowed |= ShadingMethods.FBO; } Gl.glBindFramebufferEXT( Gl.GL_FRAMEBUFFER_EXT, 0 );[/source]
Thanks for all the help in advance -- if someone can point me in a direction so that I can progress forward, I would greatly appreciate it! I apologize for all of the funky spaghetti code!








