Cube-Map Shadow Mapping

I’m slowly making progress with my game engine, but I can’t seem to get omni-directional shadow maps to work.

The shading for each point light is done in two passes:
It renders the depth component 6 times in each direction (for the cube that is). One framebuffer is used to draw to a cube map. Then it passes the scene again with the light’s calculation, sampling the cube-map texture.

Here’s what I understand & have so far,

To initialize the OpenGL cubemap, there’s 6 enums for 6 textures with one binding:

GL13.GL_TEXTURE_CUBE_MAP
GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X​
GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_X​
GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_Y​
GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y​
GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_Z​
GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z​

And the per-cubemap-face constants:

private final static int[] GL_CUBEMAP_ENUM = {
	GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X,
	GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
	GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
	GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
	GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
	GL13.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
};

private final static Vector3f[] DIRECTIONS = new Vector3f[] {
	new Vector3f( 1.0f, 0.0f, 0.0f),
	new Vector3f(-1.0f, 0.0f, 0.0f),
	new Vector3f( 0.0f, 1.0f, 0.0f),
	new Vector3f( 0.0f,-1.0f, 0.0f),
	new Vector3f( 0.0f, 0.0f, 1.0f),
	new Vector3f( 0.0f, 0.0f,-1.0f),
};

private final static Vector3f[] DIRECTIONS_UP = new Vector3f[]{
	new Vector3f(0.0f,-1.0f, 0.0f),
	new Vector3f(0.0f,-1.0f, 0.0f),
	new Vector3f(0.0f, 0.0f,-1.0f),
	new Vector3f(0.0f, 0.0f, 1.0f),
	new Vector3f(0.0f,-1.0f, 0.0f),
	new Vector3f(0.0f,-1.0f, 0.0f),
};

And were I loop through the cubemap to initialize it:

depthCubeMap = new Texture(GL13.GL_TEXTURE_CUBE_MAP, WorldLightBatchObject.SHADOW_MAP_TMUNIT, GL11.GL_NEAREST, GL11.GL_REPEAT);
depthCubeMap.bind();
for(int i = 0; i < 6; i++){
	GL13.glActiveTexture(GL13.GL_TEXTURE0 + WorldLightBatchObject.SHADOW_MAP_TMUNIT);
	GL11.glTexImage2D(GL13.GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL14.GL_DEPTH_COMPONENT24, (int) (WorldGameContext.SHADOW_MAP_MUL * 1024), (int) (WorldGameContext.SHADOW_MAP_MUL * 1024), 0, GL11.GL_DEPTH_COMPONENT, GL11.GL_FLOAT, (ByteBuffer) null);
}

Initializing the framebuffer & the perspecive matrix

depthFrame = new Frame(GL30.GL_FRAMEBUFFER);
depthFrame.bind();

depthProjection = Projection.createPerspective(90f, 1.f, 0.01f, 100f);

And to render to the depth-map:

GL11.glPushAttrib(GL11.GL_VIEWPORT_BIT | GL11.GL_ENABLE_BIT);
GL11.glViewport(0, 0, (int) (WorldGameContext.SHADOW_MAP_MUL * 1024), (int) (WorldGameContext.SHADOW_MAP_MUL * 1024));
	for(int i = 0; i < 6; i++){
		GL11.glColorMask(false, false, false, false);
		GL11.glEnable(GL11.GL_DEPTH_TEST);
		
		GL11.glClearColor(Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE);
		depthFrame.bind();
		GL30.glFramebufferTexture2D(GL30.GL_FRAMEBUFFER, GL30.GL_DEPTH_ATTACHMENT, GL_CUBEMAP_ENUM[i], depthCubeMap.getID(), 0);
		GL11.glDrawBuffer(GL11.GL_NONE);
		GL11.glReadBuffer(GL11.GL_NONE);
		GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
		
		Matrix4f depthTransform = getLightMatrix(i);
		depthProgram.use();
		depthProgram.setUniformM4("u_tLight", false, depthTransform);
		depthProgram.setUniformf("u_lPosition", position.x, position.y, position.z);
		rootObject.render(null, depthProgram);
		GL11.glColorMask(true, true, true, true);
	}
GL11.glPopAttrib();
GL11.glClearDepth(1.0d);

And to find the light projection/view matrix per-face, (I’m certain this one’s right, worked with the spotlight…)

private Matrix4f getLightMatrix(int index){
	Vector3f direction = DIRECTIONS[index];		
	Vector3f up        = DIRECTIONS_UP[index];
	
	Matrix4f out = ViewTransformComponent.lookat(position, direction, up);
	out.mul(depthProjection);
	return out;
}

Here’s what I use in the light pass, to multiply with the light fragment
v_position is in world space (object matrix * vertex) and l_position is traditionally in world space

uniform samplerCube u_sDepthMap;

float shadowVisibility(vec3 l_position, vec3 v_position){
	vec3 l_direction = l_position - v_position;
	
	float depth  = length(l_direction);
	float sample = textureCube(u_sDepthMap, normalize(l_direction)).z;
	
	if(sample <= depth + 0.00005) return 1;
	else                          return 0;
};

And the fragment shader for the ‘depth’ pass, same world space calculation as before just with the light’s matrix.

#include "./asset/shader/global.fsh"

varying vec3 v_lPosition_ws;
varying vec3 v_vPosition_ws;

vec4 calcPixel()
{
	return vec4(length(v_vPosition_ws - v_lPosition_ws));
}

Vertex shader for the ‘depth’ pass

#include "./asset/shader/global.vsh"

uniform mat4 u_tLight;
uniform vec3 u_lPosition;

varying vec3 v_lPosition_ws;
varying vec3 v_vPosition_ws;

void main(void)
{
	v_lPosition_ws = u_lPosition;
	v_vPosition_ws = vec3(u_tObject * gl_Vertex);
	gl_Position = u_tLight * vec4(v_vPosition_ws, gl_Vertex.w);
}

Stack overflow doesn’t know what’s up, but here’s the output:

As you can see in the small circle is an error I noticed happening. But in the large circle the shadows not projecting. More code will be provided on request. Thanks in advance!