Deffered shadows!


Im trying to do new shadow rendering technique. Idea is to render first pass in float pbuffer and store xyz coord of each screen pixel. After that, render shadow maps from all light sources and each light have it’s own pbuffer. Finally, render quad over whole screen and do following:

  • finalcolor = 0
  • fetch pixel xyz from float pbuffer
  • for all shadowmaps, project pixel using light matrix and fetch shadowmap. If pixel is lit add light color to final color

But, I have problem… It desn’t wan’t to work. Im stuck with matrices (I suppose). So, here is shader code. Can someone help me?

float pbuffer filler:
vertex shader
varying vec4 col;

void main()
	gl_Position = ftransform();
	// To remove viewer matrix from here, 
	// I put ModelView and Projection matrix 
	// *IN* Projection Matrix, so ModelView matrix
	// are free to use as usuall...
	col = gl_ModelViewMatrix * gl_Vertex;

fragment shader:
varying vec4 col;

void main()
	gl_FragColor = col;

After this pass float pbuffer (RGBA32f) are filled with x-y-z-1 if pixel is rendered or with 0-0-0-0 if not. Testing alpha channel I know should perform shadow calculation or not.

And complex shadow mapping shader. Assume:

  • float pbuffer are bind to unit 0
  • spot texture (light shape) are bind to unit 1
  • shadow maps are bind to units 2, 3, 4, 5
  • light matrices are binded to uniforms lightMVP0-3
void main (void)
	gl_Position = ftransform();
	gl_TexCoord[0] = gl_MultiTexCoord0;

uniform sampler2DRect world;
uniform sampler2D spot;

uniform sampler2D shadowmap0;
uniform sampler2D shadowmap1;
uniform sampler2D shadowmap2;
uniform sampler2D shadowmap3;

uniform mat4 lightMVP0;
uniform mat4 lightMVP1;
uniform mat4 lightMVP2;
uniform mat4 lightMVP3;

vec4 AddLight(sampler2D map, mat4 MVP, vec4 lightcol, vec4 wpos)
	vec4 proj = MVP * wpos;	// transform into light space
	vec3 projectiveBiased = ( / proj.w);
	projectiveBiased = (projectiveBiased + 1.0) * 0.5;
	vec4 shadowValue = texture2D(map, projectiveBiased.xy);
	vec4 lightValue = texture2D(spot, projectiveBiased.xy);
	if(shadowValue.z >= projectiveBiased.z)	
		return lightcol * lightValue;
	else return vec4(0,0,1,0);

void main (void)
	vec4 finalcolor = vec4(0,0,0,0);
	vec4 pos = texture2DRect(world, gl_TexCoord[0].xy);
	if (pos.a != 0.0)
		finalcolor += AddLight(shadowmap0, lightMVP0, gl_LightSource[0].diffuse,  pos);
		finalcolor += AddLight(shadowmap1, lightMVP1, gl_LightSource[1].diffuse,  pos);
		finalcolor += AddLight(shadowmap2, lightMVP2, gl_LightSource[2].diffuse,  pos);
		finalcolor += AddLight(shadowmap3, lightMVP3, gl_LightSource[3].diffuse,  pos);
	else finalcolor = vec4(0,0,0,0);
	gl_FragColor = finalcolor;

This shader can be optimized more for NV40 hw and add support for soft shadows and rendering up to 14 shadows in single pass.


[edit: added comment in float pbuffer filler]

Anyway… I fix it… here is a screenshot:
4 light sources with soft shadows in single pass

After cleaning code I’ll post demo with sources.


This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.