omni shadowmaps

Started by
5 comments, last by PaulHolverda 15 years, 9 months ago
i'm having major problems with my omni shadowing approach, i just don't seemed to grasp the logic behind it. I'm treating my omnis as 6 spotlights, all pointing in a 90 degrees direction, that works fine, but spots are like perfect cones, i need to find some way to let them work on omni frustum. I can submit the 5 plane equations to the pixel shader to find if a fragment is lit or not, but that seems to be an overkill in my eyes, help is more than weclome here is the code that renders a shadowmap from a given spot light: uniform sampler2D tex0; //diffusetex uniform sampler2D tex1; //normaltex uniform sampler2D tex2; //depth texture uniform sampler2DShadow tex3; //shadow tex uniform vec3 lightPos; //light pos uniform vec3 lightColor; //light color uniform float lightRadius; //raidus uniform mat4 invMat; //inv projmv mat uniform vec3 lightDirection; //raidus uniform float spotCutOff; //innerangle//as seen in editor uniform float spotFadeOff ; //outer angle uniform mat4 texMat; varying vec3 camPos; //camera position varying vec2 texCoord; varying vec4 dir; uniform float lightScale; void main(void) { float shadowColor = 1.0; vec4 base = texture2D(tex0, texCoord); vec3 bump = normalize(texture2D(tex1, texCoord).xyz* 2.0 - 1.0); float depth = texture2D(tex2, texCoord).r; vec4 worldPos = invMat * vec4( (texCoord*2.0)-1.0, depth * 2.0 - 1.0, 1.0 ); vec4 projDepth = texMat * worldPos; shadowColor = shadow2D(tex3, projDepth.xyz/projDepth.w).r; worldPos.xyz /=worldPos.w; vec3 lDir =normalize(lightPos - worldPos.xyz); float cos_cur_angle = dot(-lDir,lightDirection); vec4 final_color = vec4(0.0, 0.0, 0.0, 0.0); float spot = 0.0; float minAngle = spotFadeOff - spotCutOff; spot = clamp((cos_cur_angle - spotCutOff) / minAngle, 0.0, 1.0); float diff = max(0.0, dot(lDir, bump)); if(diff > 0.0) { if(cos_cur_angle > spotCutOff) final_color += base * diff * vec4(lightColor, 1.0) * spot; } gl_FragColor = final_color *lightScale * shadowColor ; }
Advertisement
use a cubemap (cubemap shadowmaps arent supported on most hardware) so u will have to emulate a depth map with a standard colormap, this way the texture lookup is only done in one of the sides,

though u will have to render most shadowcasters to more than one side though
This is the Shader sofar but i can't see what i'm doing wrong, any help is appreciated, somehow i think it has todo with this line
//shadowColor = shadowCube(tex3, cubecoord).x;


Regard

Paul

float shadowColor = 1.0;	vec4 base = texture2D(tex0,  texCoord);	vec3 bump = normalize(texture2D(tex1,   texCoord).xyz* 2.0 - 1.0);	float depth  = texture2D(tex2, texCoord).r;	vec4 worldPos = invMat * vec4( (texCoord*2.0)-1.0, depth * 2.0 - 1.0, 1.0 );	worldPos.xyz /=worldPos.w;	vec3 lDir =(lightPos - worldPos.xyz);			float distance = length(lDir);	float att=max(0.0, 1.0 - distance/lightRadius)*lightScale;	vec3 lightdir = normalize(-lDir);		vec4 cubecoord = vec4( lightdir, max(max(abs(lightdir.x),abs(lightdir.y)),abs(lightdir.z)) );	shadowColor = shadowCube(tex3, cubecoord).x;		//is this correct	float shadow = (distance < shadowColor)? 1.0 : 0.0;		lDir    = normalize(lDir);		float cos_cur_angle = dot(-lDir,lightDirection);	float diff = max(0.0, dot(lDir, bump));	vec4 final_color = vec4(0.0, 0.0, 0.0, 0.0);	if(diff > 0.0)	{		final_color += base * diff * att *  vec4(lightColor, 1.0)*lightScale;	}		vec4 color = final_color*shadow;	gl_FragColor =color;
Quote:Original post by zedz
use a cubemap (cubemap shadowmaps arent supported on most hardware) so u will have to emulate a depth map with a standard colormap, this way the texture lookup is only done in one of the sides,

though u will have to render most shadowcasters to more than one side though


Actually doesn't DX10.1 hardware have support for this? And if so, I am assuming this is coming sooner or later.
I'm having a geforce 8600, so depth cube maps are supported, from what i have read, and i'm already rendering to a cubemap, i just don't get it how to figure out when a fragment is in shadow and when not. I thought i would just comparing the distance of the fragment with the light, and the value stored in the cubemap

Paul
IIRC humus has a demo that does omni point shadow maps.
finally got it working, what i do now, is first render the squared distances into a cubemap, then i use that cubemap later on to compare the distances...seems so easy if you got it working.

here are some screenshots as well as the shader code

my blog



regards,

This topic is closed to new replies.

Advertisement