# light as camera? for shadow maps

This topic is 4995 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

how to create a view matrix from the light-view? I have position and a direction vector but no up vector, I have tried many different things I have found about cameras and stuff like that but nothing that works.

##### Share on other sites
ha, i never thought of that. im planning on doing shadow mapping myself.
make the up vector 0,1,0
you got the front vector and cross it to get the right, have you tried that?
tell me if you have tried that yet.
anyway, ive got a question myself
can you orthogonally project to make the light a directional light?
would that work?

if you cant work it out look at the latest directx sdk, theres a shadow mapping
demo in it.

also, do you know if you can make soft shadow maps, cause thats what i really
would like.

my games bump mapped and if the shadows are soft the game will kick command and
conquer generals butt.

http://www.geocities.com/magnus_wootton/Building.jpg

##### Share on other sites
Since it doesn't really matter, just use some arbitrary vector for the up vector, like [0,1,0]. If the light's direction is nearly parallel to that vector (i.e. abs(L dot Up) > .707), then pick another vector that is perpendicular to it, like [1,0,0]. One of the two will work.

##### Share on other sites
Supposing that up is the vector (0, 1, 0) and target and eye are classic look at parameters:

    vector3 z(target-eye); //Get the z vector    z.Normalize();        vector3 x(up*z);   //crossing z and (0, 1, 0) to get x vector    x.Normalize();        vector3 y(z*x);  //crossing z and x and you get you correct up vector

That should be what you need.

##### Share on other sites
When I need an up vector for a light source that doesn't naturally have one I use this function to get some perpendicular vector (HLSL code):

float3 GetPerpendicular(float3 vec){	float3 absvec=abs(vec);		float3 result;		if (absvec.x<absvec.y)	{		if (absvec.x<absvec.z)		{	//x is smallest			result.x=0.0f;			result.y=vec.z;			result.z=-vec.y;		} else		{	//z is smallest			result.z=0.0f;			result.x=vec.y;			result.y=-vec.x;		}	}	else	{		if (absvec.y<absvec.z)		{	//y is smallest			result.y=0.0f;			result.x=vec.z;			result.z=-vec.x;		} else		{	//z is smallest			result.z=0.0f;			result.x=vec.y;			result.y=-vec.x;		}	}		return result;}

Just normalize and you are done.

##### Share on other sites
Quote:
 Original post by cignox1Supposing that up is the vector (0, 1, 0) and target and eye are classic look at parameters: vector3 z(target-eye); //Get the z vector z.Normalize(); vector3 x(up*z); //crossing z and (0, 1, 0) to get x vector x.Normalize(); vector3 y(z*x); //crossing z and x and you get you correct up vectorThat should be what you need.

I have tried that several times, but without any success.. at the moment I use the light as camera and render from it's view just so that I can make sure it is "looking" at the correct stuff, but it isn't I have made a small function that draws a line from the lights position and to it's "lookat" point and that works ok..

muhkuh: I'll try that one, maybe it works :)

##### Share on other sites
I don't know if you found a solution of your problem, but if not, then what do you need exactly? Perhaps I misunderstood you question: if you need the 'up' vector of your camera, then the code posted should work (it works for me). If you need the view-at matrix in order to be able to move and rotate it and to make it look at a specific point, you have to build the view-at matrix as always, and then invert it.
That is, if you want to make your light look at the (x y z) point, you have to build the lok-at matrix with the position of your light as the parameter 'eye', the point you want to look at as the at parameter and the (0,1,0) vector as the up (if you function does not calculate the actual up vector itself, you will need to do it) and then invert the resulting matrix.
Then you transform your light with this matrix.

##### Share on other sites
I would like to create a view matrix using only the eye and lookat target, by creating my own right and up vectors..

if I don't remember wrong the matrix looks something like this

m.identity();
m[0,0] = right.x; m[1,0] = up.x; m[2,0] = lookatdir.x;
m[0,1] = right.y; m[1,1] = up.y; m[2,1] = lookatdir.y;
m[0,2] = right.z; m[1,2] = up.z; m[2,2] = lookatdir.z;

then I multiply that matrix with a translation matrix like this

t.identity();
t.translate( -x, -y, -z );

result.identity();
result = m * t;

and then the result is the final modelview matrix. or have I missed something?

EDIT: the problem is when I have the light/camera at 0,30,0 lookat dir 0,-1,0 then the up can't be 0,1,0 and I can't get a working one either

##### Share on other sites
Ok, that's how I set up my look-at matrix. I use a left-handed coordinate system (that is x positive right, y positive up and z positive far from the screen) with a ROWxCOL matrix system, and you may need to modify it to fit yours systems:
void matrix::LookAt(vector3 &eye, vector3 &target, vector3 &up){    if(eye == target)     {        Identity();        return; //eye and target are the same    }        vector3 z(target-eye);    z.Normalize();        vector3 x(up*z);       x.Normalize();        vector3 y(z*x);        mat[0][0] = x.x;    mat[0][1] = x.y;    mat[0][2] = x.z;    mat[0][3] = -(x^eye);      mat[1][0] = y.x;    mat[1][1] = y.y;    mat[1][2] = y.z;    mat[1][3] = -(y^eye);     mat[2][0] = z.x;    mat[2][1] = z.y;    mat[2][2] = z.z;    mat[2][3] = -(z^eye);      mat[3][0] = 0;    mat[3][1] = 0;    mat[3][2] = 0;      mat[3][3] = 1;  }

You don't need to specify right vector and the up vector is always (0,1,0) (except if you want your camera to be reversed, but for a light it is not tha case). This function (that is pretty the same to the one in the DXSDK) takes your parameters and builds the three vectors it needs in order to set a local coordinate system realted to the camera (light in your case).
The following section of the function builds these three vectors
    vector3 z(target-eye);    z.Normalize();        vector3 x(up*z);       x.Normalize();        vector3 y(z*x);

When applied to a vector, the matrix transforms the original point in the new coordinate system (hope to be right, I'm new to this).
What you need to know are only position and the look-at point of your light.
For the use with an up and z vectors that coincide (or are too much paralel), you can try to add a check and use (1, 0, 0) instead, as JhonBolton said.

##### Share on other sites
what is the ^ for? mat[0][3] = -(x^eye); is that the dotproduct between x and eye?

EDIT: what is the difference between the right and lefthanded view matrices and ROWxCOL based vs. COLxROW based?

1. 1
Rutin
43
2. 2
3. 3
4. 4
5. 5

• 9
• 27
• 20
• 9
• 20
• ### Forum Statistics

• Total Topics
633398
• Total Posts
3011659
• ### Who's Online (See full list)

There are no registered users currently online

×