Shadow mapping implementation not working?
I am trying to implement Shadow Mapping in my program using Java/LWJGL/OpenGL/GLSL, but I cannot get it to work properly. Let’s start off with a screenshot first, then the relevant code and lastly some remarks I have on them:
My scene without shadows:
My scene with shadows:
What you see in point pictures is the light source (yellow point), a randomized terrain and the floor. I am implementing shadows on only the floor at the moment. In the light pass all the objects, but the light, get rendered with the light shader. At the draw pass, all objects get rendered with their own shaders.
The artifact that happens is that I see (1) no shadow and (2) exactly half of my plane is missing.
Geometry locations are (in form (x, y, z) with y the up vector):
 Light located at (0, 7.5, 0)
 Floor located in a rectangle from (400, 10, 400) to (400, 10, 400)
 Terrain located between (0, 0, 0) to (48, 0, 48)
 The near plane is located at 0.1
 The far plane is located at 1000
The relevant code, most should be self explanatory:
Initialiazing OpenGL:
@Override
protected void init() {
super.init();
//shadow FBO and texture
depthFBO = new FrameBufferObject().create().bind();
depthTexture = new Texture2D().create().bind()
.storage2D(11, GL_DEPTH_COMPONENT32F, 4096, 4096) //11 is log2(4096)
.minFilter(GL_LINEAR)
.magFilter(GL_LINEAR)
.compareMode(GL_COMPARE_REF_TO_TEXTURE)
.compareFunc(GL_LEQUAL);
depthFBO.texture(GL_DEPTH_ATTACHMENT, depthTexture, 0)
.unbind();
depthTexture.unbind();
//drawable buffer
buffer = new DynamicDrawArrayBuffer().create().bind().fillData(Drawable.putAllData(drawables));
vertexArray = new VertexArrayObject().create().bind();
vertexArray.setAttribute(buffer, VS_POSITION, 3, GL_FLOAT, false, 0, 0);
vertexArray.enableAttributes(VS_POSITION);
//set model matrix
modelMatrix.identity().translate(0f, 0f, 0f);
Uniforms.setUniformMatrix4(UNIFORM_MODEL_MATRIX, false, modelMatrix.writeToFloatBuffer(modelMatrixBuffer));
//set light MVP
lightMVPMatrix.identity()
.frustum(1f, 1f, 1f, 1f, nearPlane, farPlane)
.lookAt(new Vector3f(0f, 7.5f, 0f), Vector3f.O, Vector3f.Y)
.multiply(modelMatrix);
Uniforms.setUniformMatrix4(UNIFORM_LIGHT_MVP_MATRIX, false, lightMVPMatrix.writeToFloatBuffer(lightMVPMatrixBuffer));
//set shadow matrix for the light
shadowMatrix.identity()
.multiply(Matrix4f.SCALE_BIAS)
.multiply(lightMVPMatrix);
Uniforms.setUniformMatrix4(UNIFORM_SHADOW_MATRIX, false, shadowMatrix.writeToFloatBuffer(shadowMatrixBuffer));
//general settings
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPatchParameteri(GL_PATCH_VERTICES, 16);
}
Rendering:
@Override
protected void render(final double msDelta) {
super.render(msDelta);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
//Light pass
depthFBO.bind();
glViewport(0, 0, 4096, 4096);
lightProgram.use();
glDrawBuffer(GL_NONE);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepthf(1f);
glClear(GL_COLOR_BUFFER_BIT  GL_DEPTH_BUFFER_BIT);
Drawable.drawAllLightPass(drawables, lightProgram);
depthFBO.unbind();
//Draw pass
glViewport(0, 0, screenWidth, screenHeight);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClearDepthf(1f);
glClear(GL_COLOR_BUFFER_BIT  GL_DEPTH_BUFFER_BIT);
glActiveTexture(GL_TEXTURE0);
depthTexture.bind();
glDrawBuffer(GL_BACK);
Drawable.drawAll(drawables);
depthTexture.unbind();
}
Then the light.vs.glsl
vertex shader:
#version 440 core
layout(location = 4) uniform mat4 light_mvp;
layout(location = 0) in vec4 position;
void main(void) {
gl_Position = light_mvp * position;
}
The light.fs.glsl
fragment shader:
#version 440 core
layout(location = 0) out float depth;
void main(void) {
depth = gl_FragCoord.z;
}
The floor.vs.glsl
vertex shader:
#version 440 core
layout(location = 0) in vec4 position;
layout(location = 0) uniform mat4 model_matrix;
layout(location = 1) uniform mat4 view_matrix;
layout(location = 2) uniform mat4 proj_matrix;
layout(location = 3) uniform mat4 shadow_matrix;
out VS_OUT {
vec3 N;
vec3 L;
vec3 V;
vec4 shadow_coord;
} vs_out;
uniform vec4 light_pos = vec4(0.0, 7.5, 0.0, 1.0);
void main(void) {
vec4 local_light_pos = view_matrix * light_pos;
vec4 p = view_matrix * model_matrix * position;
//normal
vs_out.N = vec3(0.0, 1.0, 0.0);
//light vector
vs_out.L = local_light_pos.xyz  p.xyz;
//view vector
vs_out.V = p.xyz;
//light space coordinates
vs_out.shadow_coord = shadow_matrix * position;
gl_Position = proj_matrix * p;
}
The floor.fs.glsl
fragment shader:
#version 440 core
out vec4 color;
in VS_OUT {
vec3 N;
vec3 L;
vec3 V;
vec4 shadow_coord;
} fs_in;
layout(binding = 0) uniform sampler2DShadow shadow_tex;
uniform vec3 light_ambient_albedo = vec3(1.0);
uniform vec3 light_diffuse_albedo = vec3(1.0);
uniform vec3 light_specular_albedo = vec3(1.0);
uniform vec3 ambient_albedo = vec3(0.1, 0.1, 0.2);
uniform vec3 diffuse_albedo = vec3(0.4, 0.4, 0.8);
uniform vec3 specular_albedo = vec3(0.0, 0.0, 0.0);
uniform float specular_power = 128.0;
void main(void) {
//normalize
vec3 N = normalize(fs_in.N);
vec3 L = normalize(fs_in.L);
vec3 V = normalize(fs_in.V);
//calculate R
vec3 R = reflect(L, N);
//calcualte ambient
vec3 ambient = ambient_albedo * light_ambient_albedo;
//calculate diffuse
vec3 diffuse = max(dot(N, L), 0.0) * diffuse_albedo * light_diffuse_albedo;
//calcualte spcular
vec3 specular = pow(max(dot(R, V), 0.0), specular_power) * specular_albedo * light_specular_albedo;
//write color
//color = vec4(ambient + diffuse + specular, 0.5);
color = mix(textureProj(shadow_tex, fs_in.shadow_coord), 1.0, 0.5) * vec4(ambient + diffuse + specular, 0.5);
}
The strange things I have discovered so far:

If in the
init()
method, I change.frustum(1f, 1f, 1f, 1f, nearPlane, farPlane)
to.frustum(1f, 1f, 1f, 1f, nearPlane, farPlane)
, then the opposite of the floor is considered to be in the shadow and vica versa. 
I should note that I have used OpenGL SuperBible: Sixth Edition as learning resource, if anyone is concerned, especially the
shadowmapping
example. 
I understand most of what I am doing, however the shadow mapping part is still very new to me, I understand that I need to use a
frustum
as projection matrix to simulate a directional light, and that the view matrix is there to put every point in camera coordinates. However I do not understand why in.lookAt(new Vector3f(0f, 7.5f, 0f), Vector3f.O, Vector3f.Y)
theVector3f.O
is there as second argument, formally for a lookAt matrix it is there to denote the at point, but how does that coincide with mylightMVPMatrix
? 
The camera projection is a first person view, and I am rotating my camera via that, maybe it is relevant.
I have really done my utmost best to clearly explain what is going on, but I am pretty much at a loss here, and do not know anymore what else could be wrong, obviously something is going wrong as I expecting that the terrain will cast a shadow on the floor.