   View space shadow mapping for point lights using cubemap.
  For each shadow casting light, I calculate the view and projection matrix.I use this to render the depth for each of my lights.I then use each of these depth maps to compute a single shadow map, which is in view space.This is working fine for my directional and spot lights, however I'm in a bit over my head for point lights.For the point lights, I store depth in a cube map.These are my view matrixes for the point light:View[0] = Matrix.LookAtRH(Position, Position + Vector3.UnitX, Vector3.UnitY);View[1] = Matrix.LookAtRH(Position, Position - Vector3.UnitX, Vector3.UnitY);View[2] = Matrix.LookAtRH(Position, Position + Vector3.UnitY, Vector3.UnitZ);View[3] = Matrix.LookAtRH(Position, Position - Vector3.UnitY, -Vector3.UnitZ);View[4] = Matrix.LookAtRH(Position, Position - Vector3.UnitZ, Vector3.UnitY);View[5] = Matrix.LookAtRH(Position, Position + Vector3.UnitZ, Vector3.UnitY);You may notice that the Z values are inverted, this is necessary since I'm using a RH system... this should be correct.This is the actual shader rendering the depth values to my cubemap:float4x4 worldView[6];float4x4 projection;struct VS_IN{float4 pos : POSITION0;};struct GS_IN{float4 pos : POSITION0;};struct PS_IN{uint RTIndex : SV_RenderTargetArrayIndex;float4 pos : SV_POSITION;float depth : TEXCOORD0;};GS_IN VS( VS_IN input ){GS_IN output = (GS_IN)0;output.pos = input.pos;return output;}[maxvertexcount(18)]void GS( triangle GS_IN input[3], inout TriangleStream<PS_IN> triStream ){//for each side of the cubemapfor(int d = 0; d < 6; d++){PS_IN output = (PS_IN)0;output.RTIndex = d;//for each vertex in the trianglefor(int v = 0; v < 3; v++){output.pos = mul(input[v].pos, worldView[d]);output.pos = mul(output.pos, projection);output.depth = output.pos.z;triStream.Append(output);}triStream.RestartStrip();}}float4 PS( PS_IN input ) : SV_Target{return float4(input.depth, 0, 0, 1);}technique10 omniDepth{pass P0{SetVertexShader( CompileShader( vs_4_0, VS() ) );SetGeometryShader( CompileShader( gs_4_0, GS() ) );SetPixelShader( CompileShader( ps_4_0, PS() ) );}}I'm using the geometry shader to render the whole cubemap with a single draw call.The cubemap looks correct, so there shouldn't be any problem here.My main problem is that I do not know how to correctly render my view space shadow map using this cubemap containing the depth values.Currently, my shader generating the shadow map from a light's depth map looks like this:float4x4 worldViewProjection;float4x4 lightViewProjection;float4x4 matTexture;texture2D shadowDepth;float lightFarPlane;sampler shadowSampler = sampler_state{Filter = MIN_MAG_MIP_LINEAR;    AddressU = CLAMP;    AddressV = CLAMP;};struct VS_IN{float4 pos : POSITION0;};struct PS_IN{float4 pos : SV_POSITION;float4 vTexCoord : TEXCOORD0;float Depth : TEXCOORD1;};PS_IN VS( VS_IN input ){PS_IN output = (PS_IN)0;output.pos = mul(input.pos, worldViewProjection);output.vTexCoord = mul(input.pos, matTexture);output.Depth = mul(input.pos, lightViewProjection).z;return output;}float4 PS( PS_IN input ) : SV_Target{// Generate the 9 texture co-ordinates for a 3x3 PCF kernelfloat4 vTexCoords[9];// Texel sizefloat fTexelSize = 1.0f / 1024.0f;// Generate the tecture co-ordinates for the specified depth-map size// 4 3 5// 1 0 2// 7 6 8vTexCoords[0] = input.vTexCoord;vTexCoords[1] = input.vTexCoord + float4( -fTexelSize, 0.0f, 0.0f, 0.0f );vTexCoords[2] = input.vTexCoord + float4(  fTexelSize, 0.0f, 0.0f, 0.0f );vTexCoords[3] = input.vTexCoord + float4( 0.0f, -fTexelSize, 0.0f, 0.0f );vTexCoords[6] = input.vTexCoord + float4( 0.0f,  fTexelSize, 0.0f, 0.0f );vTexCoords[4] = input.vTexCoord + float4( -fTexelSize, -fTexelSize, 0.0f, 0.0f );vTexCoords[5] = input.vTexCoord + float4(  fTexelSize, -fTexelSize, 0.0f, 0.0f );vTexCoords[7] = input.vTexCoord + float4( -fTexelSize,  fTexelSize, 0.0f, 0.0f );vTexCoords[8] = input.vTexCoord + float4(  fTexelSize,  fTexelSize, 0.0f, 0.0f );// Sample each of them checking whether the pixel under test is shadowed or notfloat fShadowTerms[9];float fShadowTerm = 0.0f;for( int i = 0; i < 9; i++ ){float A = shadowDepth.Sample( shadowSampler, vTexCoords.xy / vTexCoords.w ).r;float B = (input.Depth - (1.0f / lightFarPlane));// Texel is shadowedfShadowTerms = A < B ? 0.0f : 1.0f;fShadowTerm+= fShadowTerms;}// Get the averagefShadowTerm /= 9.0f;return float4(fShadowTerm, 0, 0, 1);}technique10 test{pass P0{SetVertexShader( CompileShader( vs_4_0, VS() ) );SetGeometryShader( 0 );SetPixelShader( CompileShader( ps_4_0, PS() ) );}}This is a similar implementation as seen here on gamedev at: http://www.gamedev.net/reference/articles/article2193.aspUnfortunately I have no idea how to modify this to work with a cubemap...I figured I should just get it to work first, so right now, I'm doing a draw call for every side of the cube.Basically I call the above shader code, once for each view matrix of the light, and changed thetexture2d shadowDepth to  textureCube shadowDepthCubeI then tried to sample like this (I'm skipping the pcf for now):shadowDepthCube.Sample( shadowSampler, input.vTexCoord.xyz / input.vTexCoord.w ).r;The results for this are completely wrong, so I'm hoping that I'm sampling the cubemap wrong...Here's the full code:float4x4 worldViewProjection;float4x4 lightViewProjection;float4x4 matTexture;TextureCube shadowDepthCube;float lightFarPlane;sampler shadowSampler = sampler_state{Filter = MIN_MAG_MIP_LINEAR;    AddressU = CLAMP;    AddressV = CLAMP;};struct VS_IN{float4 pos : POSITION0;};struct PS_IN{float4 pos : SV_POSITION;float4 vTexCoord : TEXCOORD0;float Depth : TEXCOORD1;};PS_IN VS( VS_IN input ){PS_IN output = (PS_IN)0;output.pos = mul(input.pos, worldViewProjection);output.vTexCoord = mul(input.pos, matTexture);output.Depth = mul(input.pos, lightViewProjection).z;return output;}float4 PS( PS_IN input ) : SV_Target{// Sample each of them checking whether the pixel under test is shadowed or notfloat A = shadowDepthCube.Sample( shadowSampler, input.vTexCoord.xyz / input.vTexCoord.w ).r;float B = (input.Depth - (1.0f / lightFarPlane));// Texel is shadowedfloat shadow = A < B ? 0.0f : 1.0f;return float4(shadow, 0, 0, 1);}technique10 test{pass P0{SetVertexShader( CompileShader( vs_4_0, VS() ) );SetGeometryShader( 0 );SetPixelShader( CompileShader( ps_4_0, PS() ) );}}It's also possible that the culprit is the matTexture.I have to admit I don't fully understand how it maps from projection to texture space.The article suggests setting it like this:0.5f,0.0f,0.0f, 0.0f,0.0f,-0.5f,    0.0f, 0.0f,0.0f,0.0f,1.0f, 0.0f,fTexOffs, fTexOffs, 0.0f, 1.0fI tried changing it to this:0.5f,0.0f,0.0f,0.0f,0.0f,-0.5f,    0.0f,0.0f,0.0f,0.0f,1.0f,0.0f,fTexOffs, fTexOffs, fTexOffs, 1.0fThe shadow map is still completely messed up though.It basically makes everything shadowed that is to the X (right) side of the light.This leaves me with 2 questions:1) How do I sample the cubemap correctly? I'm pretty sure I'm doing it wrong.2) How would I render my shadow map in a single draw call?   
  1) Sampling a cube map is pretty easy. Basically you just pass a normalized direction vector, and it will give you the texel that corresponds to that direction. So in your case since you aligned your cube depth map to the major world-space axes, you can just get the direction from your light to your pixel in world-space. You don't need to muck around with your light's view or projection matrices at all. This should also answer your second question.And now a few things about that sample you're using as a reference...-a screen-space blur can be a pretty poor way to filter your shadows. It can destroy shadow detail in the distance (since the penumbra size is equal everywhere on-screen), and unless you take scene depth into account you'll have "light bleeding" around areas of overlapping geometry.-that sample does things pretty inefficiently. After the depth map is rendered, the shadow occlusion value is calculated by once again re-rendering the scene geometry. Fine for one mesh, but for an actual scene this is a waste. Instead if you have a depth buffer for your scene that you can sample, you can just reconstruct position from that and then do the shadow map calculations using either a full-screen quad or with geometry representing the light's bounding volume (just like in deferred rendering).;  After reading your post, how to sample from the cubemap is perfectly obvious, thank you :)As you may have imagined, I was thinking about this all wrong, and didn't consider that the cube was aligned to the world axes, and that this would make things so much easier.As for the reference I am using, I was searching for a method to implement shadows, that would be identical regardless of whether I'm using forward or deferred rendering, since I'm considering to do something related to deferred rendering for my bachelor thesis.I knew from the start that a screen space blur would be a bad idea, since I've read about light bleeding before, so I decided to use this as a reference and just skip the blur part.I'm going to investigate soft-edged shadows after everything is working as it should.If you have any suggestions, I'd be more then happy to hear about them though :)Now that you mention it, having to render everything twice to just to get the shadow map has been bugging me for some time.I'm very happy to read about your suggestion to improve performance, especially since it's quite similar to what you do in deferred rendering.I wasn't aware that you could bind the depth buffer as a shader resource in dx10, this is quite nice :)Does this also mean, that in deferred rendering, I do not need to keep the scene depth stored in the G-Buffer anymore? I can just read it directly from the depth buffer?Thank you,Hyu   ;Quote:Original post by HyunkelDoes this also mean, that in deferred rendering, I do not need to keep the scene depth stored in the G-Buffer anymore? I can just read it directly from the depth buffer?Yeah, you can do this. However you can't bind a depth-stencil buffer as both a shader resource view and a depth-stencil view at the same time, which means if you want to sample from it you can't use it for depth or stencil culling of light volumes. ;  I guess that would have been too easy :)Thanks again!   ;  I'm nearly there, but I have quite a bit of trouble figuring something out.Here's how I render the shadow map for point lights now:float4x4 world;float4x4 viewProjection;float3 lightPosition;TextureCube shadowDepthCube;float lightFarPlane;sampler shadowSampler = sampler_state{Filter = MIN_MAG_MIP_LINEAR;    AddressU = CLAMP;    AddressV = CLAMP;};struct VS_IN{float4 pos : POSITION0;};struct PS_IN{float4 pos : SV_POSITION;float4 wPos : TEXCOORD0;};PS_IN VS( VS_IN input ){PS_IN output = (PS_IN)0;output.wPos = mul(input.pos, world);output.pos = mul(output.wPos, viewProjection);return output;}float4 PS( PS_IN input ) : SV_Target{//Distance between light and surfacefloat3 lightToSurface = input.wPos.xyz - lightPosition;//View Space Depthfloat vDepth = length(lightToSurface);//Cubemap Depthfloat cDepth = shadowDepthCube.Sample( shadowSampler, normalize(lightToSurface) ).r;float A = cDepth;float B = (vDepth - 1.0f); //account for floating point imprecision// Texel is shadowedfloat shadow = A < B ? 0.0f : 1.0f;return float4(shadow, 0, 0, 1);}technique10 test{pass P0{SetVertexShader( CompileShader( vs_4_0, VS() ) );SetGeometryShader( 0 );SetPixelShader( CompileShader( ps_4_0, PS() ) );}}Now... this isn't working correctly.I believe the main issue here is the way I store depth in my cubemap:void GS( triangle GS_IN input[3], inout TriangleStream<PS_IN> triStream ){//for each side of the cubemapfor(int d = 0; d < 6; d++){PS_IN output = (PS_IN)0;output.RTIndex = d;//for each vertex in the trianglefor(int v = 0; v < 3; v++){float4 worldPos = mul(input[v].pos, world[d]);float4 viewPos = mul(worldPos, view[d]);output.pos = mul(viewPos, projection);output.depth = output.pos.z;triStream.Append(output);}triStream.RestartStrip();}}A pixel shader then writes output.depth to my render target.So on the one side, I have my cubemap, which has the depth (as seen by the light) stored in the projection space of the light.On the other side, I have my lightToSurface vector, which has the other depth (for the pixels seen by the camera), but in world space.I can't figure out how to compare both depth values... I somehow need to get them into the same space.How can I do that?Thanks,Hyu;  Just store the distance from the light to the pixel in world-space when you're generating your depth map. It's simple, cheap, and it's a linear metric which is desirable in terms of precision.   ;  Alright, I got it working thanks to your help.One thing that threw me off was that for the cubemap lookup vector, I had to negate the Z axis, supposedly because I'm using a RH coordinate system.I have one more problem, which I suppose could be described as some sort of Z fighting.Right now I calculate shadows like this:float4 PS( PS_IN input ) : SV_Target{float3 lightToSurface = input.wPos.xyz - lightPosition;//View Space Depthfloat vDepth = length(lightToSurface);vDepth -= 0.6f; //floating point imprecision//Negate Z axis for cubemap lookupfloat3 RHlookup = float3(lightToSurface.x, lightToSurface.y, -lightToSurface.z);//Cubemap Depthfloat cDepth = shadowDepthCube.Sample( shadowSampler, normalize(RHlookup) ).r;// Texel is shadowedfloat shadow = cDepth < vDepth ? 0.0f : 1.0f;return float4(shadow, 0, 0, 1);}I understand that some kind of Z fighting does occur with this, due to floating point imprecision.Ideally I'd want to check if cDepth == vDepth, but that obviously isn't possible.This is why I do the vDepth -= 0.6f; trick (found 0.6 after some testing), which gets rid of the standard problems associated with doing this.I have to admit 0.6f sounds quite extreme, but it's the only way to get rid of the typical sawtooth problemFor some reason I still have quite a bit of artifacts though, which seem related to depth comparison, and I don't know how to get rid of them.I guess a video describes this best:">Is this caused by an insufficient cubemap texture resolution?I'm already using 1024x1024 for each face of the cubemap, which as I understand is quite high for shadow mapping.Any suggestions on how to improve this?Thanks,Hyu;  *bump*I tried a few things to get rid of the flickering, but I ran out of ideas.The flickering issue is best described with the youtube video in my last post.Any suggestions on how to get rid of it?Thanks,Hyu   ;  When you're outputting depth the shadow map, try normalizing your depth value by dividing the distance from light to pixel by the the maximum range of your light. Then do the same to the distance you calculate in your main shader before comparing to shadow map value.   