Jump to content


D3D10 Shadow Mapping


123 replies to this topic

#1 XVincentX

    Valued Member

  • Members
  • PipPipPip
  • 115 posts

Posted 05 February 2009 - 11:41 AM

I'm trying to make a little shadow map example with a point light: so i had to use a cubemap via Geometry Shader.
So i made a ViewMatrix array

[source lang="cpp"]
D3DXMatrixLookAtLH(&cNeverChange.view[0],&D3DXVECTOR3(3.0f,10.0f,-35.0f),&D3DXVECTOR3(1,0,0),&D3DXVECTOR3(0,1,0));
D3DXMatrixLookAtLH(&cNeverChange.view[1],&D3DXVECTOR3(3.0f,10.0f,-35.0f),&D3DXVECTOR3(-1,0,0),&D3DXVECTOR3(0,1,0));
D3DXMatrixLookAtLH(&cNeverChange.view[2],&D3DXVECTOR3(3.0f,10.0f,-35.0f),&D3DXVECTOR3(0,1,0),&D3DXVECTOR3(0,0,1));
D3DXMatrixLookAtLH(&cNeverChange.view[3],&D3DXVECTOR3(3.0f,10.0f,-35.0f),&D3DXVECTOR3(0,-1,0),&D3DXVECTOR3(0,0,1));
D3DXMatrixLookAtLH(&cNeverChange.view[4],&D3DXVECTOR3(3.0f,10.0f,-35.0f),&D3DXVECTOR3(0,0,1),&D3DXVECTOR3(0,1,0));
D3DXMatrixLookAtLH(&cNeverChange.view[5],&D3DXVECTOR3(3.0f,10.0f,-35.0f),&D3DXVECTOR3(0,0,-1),&D3DXVECTOR3(0,1,0));


[/source]

and set it in the geometry shader using a render target view array.
Now all it's finished, but the cubemap does not really convince me.
It's normal that all the face looks at the same point?
Here is a screenshot. (I'm using DXGI_FORMAT_R32_FLOAT)

http://img4.imagesha...98524769vp9.jpg
http://img17.imagesh...42060593bo7.jpg
http://img516.images...70371578ov5.jpg

and so on...

#2 rouncer

    Senior Member

  • Members
  • PipPipPipPip
  • 2258 posts

Posted 05 February 2009 - 02:44 PM

Ive only ever handled spot lights and direction lights, doing point lights is advanced, i bet using the cube texture is a complete biatch, anyway good luck.
(btw, i think they are supposed to take shots different directions. ;))

#3 XVincentX

    Valued Member

  • Members
  • PipPipPip
  • 115 posts

Posted 05 February 2009 - 03:29 PM

I think the same thing...

#4 Reedbeta

    DevMaster Staff

  • Administrators
  • 4782 posts
  • LocationBellevue, WA

Posted 05 February 2009 - 05:29 PM

The problem is the third parameter to D3DXMatrixLookAtLH is the point to look at, not the direction to look. Just add each of those values to the camera location and you'll get something closer to what it's supposed to be. (You still may need to tweak the up vectors to get all the faces rotated the right way.)

BTW, the tag for posting code is [code] rather than [source].
reedbeta.com - developer blog, OpenGL demos, and other projects

#5 XVincentX

    Valued Member

  • Members
  • PipPipPip
  • 115 posts

Posted 05 February 2009 - 06:25 PM

Oh you're right!
But...should not i have to do A - B instead A + B in order to get direction?

#6 Reedbeta

    DevMaster Staff

  • Administrators
  • 4782 posts
  • LocationBellevue, WA

Posted 05 February 2009 - 07:12 PM

You already have the directions, and it wants the point to look at. So you need to add the camera location to the directions.
reedbeta.com - developer blog, OpenGL demos, and other projects

#7 XVincentX

    Valued Member

  • Members
  • PipPipPip
  • 115 posts

Posted 05 February 2009 - 09:40 PM

Ok now my texture has got 6 different faces and looks like ok.
But i'm not yet convinced about the shadow.

To help you help me, i decided to mark shadowed pixel in red, in this image.
http://img4.imagesha...673/img1xe5.jpg

I'm not sure about results...there is a shadow only on the lamp itself?
Here is my shader code.

PS_INPUT vs_position (VS_INPUT In)
{
	PS_INPUT Out = (PS_INPUT)0;

	Out.Pos = mul(mul(mul(In.Pos,WorldMatrix),ViewMatrix),ProjMatrix);
	Out.WPos = mul(In.Pos,WorldMatrix);
	Out.Nor = mul(In.Nor,WorldMatrix);
	Out.Tex = In.Tex;
	
	Out.Dist = distance(Out.WPos,LightInfo.xyz);
	Out.LPos = Out.WPos - LightInfo.xyz;

	return Out;	
}

float4 ps_light (PS_INPUT In)	:	SV_TARGET
{	
	float4 BaseColor = (Lamp == true) ? float4(0.25f, 0.21f, 0.20f, 1) : Text.Sample(SamplText,In.Tex);
	float3 vLight = normalize(LightInfo.xyz-In.WPos);
	float NdotL = dot(In.Nor,vLight);
	float Att = Attenuation(distance(LightInfo.xyz,In.WPos),0.003,0.003,0.003);
	float4 Light1 = (saturate(NdotL)) * Att;
	
	float shadow = Cubemap.Sample(SamplText,normalize(In.LPos));
	
	if (shadow > In.Dist)
		return float4(1,0,0,1);
	else
	{
		return BaseColor * Light1;
	}
}

Thank you again.

#8 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 574 posts

Posted 05 February 2009 - 09:59 PM

It would be much easier, btw to, simply build yourself some simple matrices directly.

As you probably know a matrix is defined in rows as

<side vector>
<up vector>
<forward vector>
<position vector>

So for the simple case of look forward you'd set up a matrix as follows

1 0 0 0
0 1 0 0
0 0 1 0
3 10 -35 1

Now to convert that to a view matrix all you need to do is take the inverse of the matrix. Basically by transforming any position by the inverse of that matrix you are moving into the view space as defined. Work through the maths. It makes good sense :)

It'll be much easier, imo, to conceptualise your matrices if defined this way.

#9 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 574 posts

Posted 05 February 2009 - 10:19 PM

The implication is, btw, that the value returned by "shadow" is NOT greater than the interpolated distance value. I'd look at the float values you are writing into the shadow depth buffer. Have you tried debugging the shader with pix to see what happens?

#10 XVincentX

    Valued Member

  • Members
  • PipPipPip
  • 115 posts

Posted 05 February 2009 - 10:27 PM

I've not understood your theory...
What's the problem? Why should i use your "solution"?

#11 XVincentX

    Valued Member

  • Members
  • PipPipPip
  • 115 posts

Posted 05 February 2009 - 10:41 PM

Goz said:

The implication is, btw, that the value returned by "shadow" is NOT greater than the interpolated distance value. I'd look at the float values you are writing into the shadow depth buffer. Have you tried debugging the shader with pix to see what happens?

Oh, this is what i was looking for.
The shadow depth buffer it's simply filled in this way
float4 ps_depth (VGS_OUTPUT In)	:	SV_TARGET
{	
	return In.P2D.z/In.P2D.w;
}

Changin the formula in this way

float4 ps_depth (VGS_OUTPUT In)	:	SV_TARGET
{	
	return distance(In.WPos,LightInfo);
	//return In.P2D.z/In.P2D.w;
}


The shadowed zone grows.
http://img3.imagesha...951/img1wo7.jpg

#12 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 574 posts

Posted 05 February 2009 - 11:20 PM

OK ... and if you change the line

if (shadow > In.Dist )

to

if (shadow < In.Dist)

what happens?

You are testing to see if the current pixel position "In.Dist" is further away than shadow afterall.

#13 XVincentX

    Valued Member

  • Members
  • PipPipPip
  • 115 posts

Posted 05 February 2009 - 11:26 PM

I just see the complete opposite. All red except for the "shadowed" zone.

#14 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 574 posts

Posted 06 February 2009 - 11:04 AM

Hmmm ... the distances used ought to be positive values (a negative distance is non sensical). The implication would be, therefore, that if the current pixel distance is further than the shadow buffer distance then its shadowed.

Still. Run it under pix take a grab and debug it. Pix is an amazing piece of tech for doing this sort of thing :)

#15 XVincentX

    Valued Member

  • Members
  • PipPipPip
  • 115 posts

Posted 06 February 2009 - 11:37 AM

I'm sorry but my english is not so good so i'm not able to understand fully your sentences.
Please do not punish me if i will ask you every time same things.

In this afteroon i will try your suggestions with PIX, but i've not understood if, in your opinion, the shadow is wrong.

#16 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 574 posts

Posted 06 February 2009 - 12:02 PM

It looks fine to me, but I may be missing something.

Debugging with Pix would be great for validating the data coming from.

#17 XVincentX

    Valued Member

  • Members
  • PipPipPip
  • 115 posts

Posted 10 February 2009 - 11:09 PM

Hello again. Now all it's going better and now i would add a second shadow with a spotlight.
I had no problem to make spotlight work and, making the shadow, i simply used the same technique updescribed but with only 1 texture.
To make sure i made the right work, i run a PIX simulation and tried to look at Render Target result: completely white.

The big problem that also the cubemap render target (that works perfectly) at the end of all draw calls it's white. So i do not know how to verify my work (that looks like wrong, since my shadow is not drawn correctly)

Suggestions?

#18 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 574 posts

Posted 11 February 2009 - 09:21 AM

Can you not run the shadow map pixel shader through PIX and see what the values being written to the shadow map look like? Do they look sensible?

#19 XVincentX

    Valued Member

  • Members
  • PipPipPip
  • 115 posts

Posted 11 February 2009 - 03:22 PM

Yes, i checked it completely.
I see both rendertarget completely white, but it's impossibile becouse

A) The first cubemap target works infact the shadow it's displayed correctly.
B) The second (Spotlight, so a single render target) also it's filled becouse a shadow it's displayed (wrong, but it's displayed).

To help you help me, i uploaded a complete PIX simulation, you can download it ah ftp://xvincentx.netsons.org/poppi.rar
It's about 3 mega.

Have a look at EID 736 (it's the cubemap filling) of frame 1, and in each frame look at first render target binding and drawing.

Thank you again

#20 Goz

    Senior Member

  • Members
  • PipPipPipPip
  • 574 posts

Posted 11 February 2009 - 05:30 PM

That link doesn't work.

There is one slight other issue in that I accidentally destroyed my Vista laptop so I don't know if I can do a DX10 simulation under DX9. But if you get the link working i'll give it a try :)





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users