Single Pass Multi-Layer Depth Rendering

Hey, so I am currently trying to render multiple shadow maps in a single pass. I trying to render to a GL_TEXTURE_2D_ARRAY usign Cg geometry shaders. For the sake of testing I attached a color texture array to the FBO as well as the depth texture array. It seems like the rendering to the color texture array is working fine; however, the the depth components are not being stored. Here’s some code, maybe someone can see something I’m not seeing.

I create the buffers:


	glGenFramebuffersEXT(1, &shadowFBO);

// -- color texture
	glGenTextures( 1, &colorTex );
	glBindTexture( GL_TEXTURE_2D_ARRAY_EXT, colorTex );

	glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); 
	glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 
	glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); 
	glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); 
	glTexImage3D ( GL_TEXTURE_2D_ARRAY_EXT, 0, GL_RGBA16, 256, 256, 6, 0, GL_RGBA, GL_FLOAT, 0);

// -- depth texture
	glGenTextures(1, &depthTex);
	glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, depthTex);

	glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); 
	glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); 
	glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); 
	glTexParameteri( GL_TEXTURE_2D_ARRAY_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); 
	glTexImage3D( GL_TEXTURE_2D_ARRAY_EXT, 0, GL_DEPTH_COMPONENT16, 256, 256, 6, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
		
	glBindTexture(GL_TEXTURE_2D_ARRAY_EXT, 0);

// -- attach textures to FBO
	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadowFBO);

	glFramebufferTextureEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, colorTex, 0 );
	glFramebufferTextureEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, depthTex, 0 );

	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);


Render faces:


	glClearColor(0, 0, 0, 1);
	glClearDepth(1.0);
	glEnable(GL_DEPTH_TEST);
	glDepthFunc(GL_LEQUAL);
	glDepthMask(GL_TRUE);

	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadowFBO);

	glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
	glViewport(0, 0, 256, 256);

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	

	drawScene();

	glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

CgFX Shader:


/// = uniform parameters = 
float4x4 viewProjMat_array[];
float4x4 modelMat;

// - vertex -
struct vIN
{
	float4	position	: POSITION;
};

struct vOUT
{
	float4	wposition	: POSITION;
};

vOUT
cube_shadowmap_v(
		vIN _vInput,
		uniform float4x4 _mMat
		)
{
	vOUT vOutput = (vOUT)0;
	
	vOutput.wposition = mul(_mMat, _vInput.position);
	
	return vOutput;
}

// - geometry -

TRIANGLE
void 
cube_shadowmap_g(
		AttribArray<float4> _position	: POSITION
		)
{
	float4 pposition;

	for(int j=0; j<6; j++)
	{
	for(int i=0; i<_position.length; i++)
	{
		pposition = mul(viewProjMat_array[j], _position[i]);
		
		emitVertex(pposition	: POSITION, float4(pposition.z/10, 0,0,1) : COLOR, j : LAYER);
	}
	restartStrip();
	}
}

/// main technique
technique main
{
	pass p0
	{
		VertexProgram = compile gp4vp cube_shadowmap_v (
modelMat
);
		GeometryProgram = compile gp4gp cube_shadowmap_g();
	}	
}


I don’t show how I set the matrix parameters, or how I bind the shaders, because I think it’s irrelevant.

Any thoughts?

If I remember correctly in EXT version of the FBO extension all attachments must have the same internal format. Use ARB version to avoid this limitation (glGenFramebufferEXT -> glGenFramebuffer and so on…)

hmm, I am not sure that is the issue, although I tried it (changed all the relevant function calls and enumerators from EXT to ARB by removing the EXT suffix). I mean, the color buffer gets updated fine, the one that does not get updated is the depth buffer.

Depth testing is enabled, right? (glEnable(GL_DEPTH_TEST))

yea it is enabled, ok, it seems like the depth writes are working after all, but it seems like the problem is that the depths are not being normalized which always makes them greater than one, and thus never get written in the zbuffer. I came to this conclusion, because when I set the clear depth to 1 - glClearDepth(1) - and the depth function to less or equal - glDepthFunc(GL_LEQUAL) -, I get a white screen as I render the texture on a quad, but when I set the depth to 0 and the depth function to ‘always’ or ‘greater or equal’ I can see the silhouettes of different objects which are all white. Now, I am using a custom made projection matrix, that is, I wrote (more like, copied from the web) the code to create it, and I compared the resulting projection matrix to the gl matrix by getting the gl matrix with glGetFloatv, and they are identical. I wonder why I am not getting normalized coordinates.

wait, it looks like I might be getting correct values, I still test it further, but it seems like all values in the depth texture are either 1 or less. Sorry for wasting your time randall. I kind of got desperate.