# Help with 3D camera please

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

## Recommended Posts

Hi guys,

I have created a simple 3D perspective camera for my project. Which is rendering a simple triangle correctly as anticipated.

I am wondering how to go about setting the 'look at' position.

This is my main code:

// CAMERA
XMMATRIX viewMatrix = XMMatrixIdentity();
XMMATRIX projMatrix = XMMatrixPerspectiveFovLH(60.0f * 0.0174533f, float((float)nWidth) / ((float)nHeight), 1.0f, 1000.0f);
viewMatrix = XMMatrixTranspose(viewMatrix);
projMatrix = XMMatrixTranspose(projMatrix);

// position the camera
XMMATRIX rotationMatrix = XMMatrixRotationZ(0.0f);
XMMATRIX translationMatrix = XMMatrixTranslation(0.0f, 0.0f, 0.0f);
XMMATRIX worldMat = rotationMatrix*translationMatrix;
worldMat = XMMatrixTranspose(worldMat);

d3dContext->UpdateSubresource(worldCB, 0, 0, &worldMat, 0, 0);
d3dContext->UpdateSubresource(viewCB, 0, 0, &viewMatrix, 0, 0);
d3dContext->UpdateSubresource(projCB, 0, 0, &projMatrix, 0, 0);

d3dContext->VSSetConstantBuffers(0, 1, &worldCB);
d3dContext->VSSetConstantBuffers(1, 1, &viewCB);
d3dContext->VSSetConstantBuffers(2, 1, &projCB);

This is the vertex part of my shader:

struct VS_Input
{
float4 pos  : POSITION;
};

struct VS_Output
{
float4 pos  : SV_POSITION;
};

{
VS_Output OUT;
matrix mvp = mul(projectionMatrix, mul(viewMatrix, worldMatrix));
OUT.pos = mul(mvp, IN.pos);
return OUT;
}

A nudge in the right direction would be greatly appreciated.

##### Share on other sites
Again one of those things, where when you take a step back and think the answer reveals itself.

I needed to add this to the mix:

XMVECTOR eyePosition = XMVectorSet(0, 0, -20, 1);
XMVECTOR focusPoint = XMVectorSet(0, 0, 0, 1);
XMVECTOR upDirection = XMVectorSet(0, 1, 0, 0);
viewMatrix = XMMatrixLookAtLH(eyePosition, focusPoint, upDirection);
viewMatrix = XMMatrixTranspose(viewMatrix);


Although, it seems something still isn't quite right here, as the camera movement isn't what I'd expect. I'll test a few thing out and possibly enquire further Edited by DarkRonin

##### Share on other sites
I found that part of the problem was that I had two of the constant buffers around the wrong way, so they were receiving the wrong matrix data.

After correcting this, I am now not seeing anything rendered to the screen. This is the code that I have at the moment, after a lot of re-working.

cbuffer PerObject : register(b0)
{
matrix worldMatrix;
}

cbuffer PerFrame : register(b1)
{
matrix viewMatrix;
}

cbuffer PerApplication : register(b2)
{
matrix projectionMatrix;
}

struct VS_Input
{
float4 pos  : POSITION;
};

struct VS_Output
{
float4 pos  : SV_POSITION;
};

{
VS_Output OUT;
matrix mvp = mul(projectionMatrix, mul(viewMatrix, worldMatrix));
OUT.pos = mul(mvp, IN.pos);

return OUT;
}


And the main project side of things.

		// Camera
XMMATRIX projMatrix = XMMatrixPerspectiveFovLH(60.0f * 0.0174533f, float((float)nWidth) / ((float)nHeight), 1.0f, 1000.0f);
projMatrix = XMMatrixTranspose(projMatrix);

// Position the camera
XMVECTOR eyePosition = XMVectorSet(0.0f, 0.0f, -10.0f, 0.0f);
XMVECTOR focusPoint = XMVectorSet(0.0f, 0.0f, 0.0f, 0.0f);
XMVECTOR upDirection = XMVectorSet(0.0f, 1.0f, 0.0f, 0.0f);
XMMATRIX viewMatrix = XMMatrixLookAtLH(eyePosition, focusPoint, upDirection);
viewMatrix = XMMatrixTranspose(viewMatrix);

// Position the object at 0,0,0 for the moment
XMMATRIX translationMatrix = XMMatrixTranslation(0.0f, 0.0f, 0.0f);
XMMATRIX worldMat = translationMatrix;
worldMat = XMMatrixTranspose(worldMat);

// Update and set the contant buffers
d3dContext->UpdateSubresource(worldCB, 0, 0, &worldMat, 0, 0);
d3dContext->UpdateSubresource(viewCB, 0, 0, &viewMatrix, 0, 0);
d3dContext->UpdateSubresource(projCB, 0, 0, &projMatrix, 0, 0);

d3dContext->VSSetConstantBuffers(0, 1, &worldCB);
d3dContext->VSSetConstantBuffers(1, 1, &viewCB);
d3dContext->VSSetConstantBuffers(2, 1, &projCB);


I know that I must be reasonably close. But, if someone could shed an eye over this, that would be awesome

##### Share on other sites

Try setting projMatrix with a znear lesser than 1.0f, maybe 0.1f or something, and maybe your camera is pointing in the wrong direction for stuff to be seen?

Note: It would be better to keep all matrices in one cbuffer, so you potentially get less UpdateSubresource() calls overall - but not entirely sure.. :)

Edited by vinterberg

##### Share on other sites
Hi there.

Tried both of your suggestions. Positioned the camera at both -20 and +20, and changed the znear value. But the result is still the same unfortunately.

##### Share on other sites

was the triangle always in world space, was the camera previously at origin? I can't see where you create the triangle, so i'm not sure where you *should* find it. what does the view transform look like immediately before being sent to the shader?

EDIT: looking at the original code I'm not sure how you got anything displayed! Both the view and the world transforms were identity matrices. ie the camera and triangle were in the same place, unless the tri verts put it somewhere else (since they would be in world space at that time)

Edited by Burnt_Fyr

##### Share on other sites
Hi Bunrt_Fyr,

Yeah, I am pretty new to martices. So, I am confident that the problem lies in there somewhere.

Any advice on how it should look would be awesome. I am still trying to get my head around what is happening here. Even though I have been reading up on this since the OP - hehe.

Thanks again

##### Share on other sites
From the above code, this is what should be happening (in my understanding).

Triangle - 0,0,0
Camera - 0,0,-10
Looking at - 0,0,0

I just can't seem to understand what is going wrong here.

I have tried the camera at z=10 in case of a culling issue. But to no avail. The triangle is definitely in a RHW winding order.

##### Share on other sites
Turns out the other half of the problem was in the shader.

I have changed the shader to this and the whole scene seems to be working correctly now

VS_Output VShader(VS_Input IN)
{
VS_Output OUT = IN;

OUT.pos = mul(IN.pos, worldMatrix);
OUT.pos = mul(OUT.pos, viewMatrix);
OUT.pos = mul(OUT.pos, projectionMatrix);

return OUT;
}


##### Share on other sites

Turns out the other half of the problem was in the shader.

I have changed the shader to this and the whole scene seems to be working correctly now

VS_Output VShader(VS_Input IN)
{
VS_Output OUT = IN;

OUT.pos = mul(IN.pos, worldMatrix); // transform from model to world space
OUT.pos = mul(OUT.pos, viewMatrix); // transform from world to camera space
OUT.pos = mul(OUT.pos, projectionMatrix); // transform from camera to projection space

return OUT;
}


Sorry i kind of afk'd on the convo here, but I see you solved it. Working your critical thinking skills will payback 10x the effort you put into them. I find myself answering so many more questions than i have to ask now. When I run into an issue, I have the experience, as well as the critical thinking to pinpoint the problem in a fraction of the time that i would have spent even a year ago, so good on you for solving your own problem.

Looking back at the original shader

 matrix mvp = mul(projectionMatrix, mul(viewMatrix, worldMatrix));


should probably have been

 matrix mvp = mul(mul(worldMatrix, viewMatrix), projectionMatrix);


so that the matrices are being concatenated in the right order. An even better idea would be to concatenate those transforms per object on the CPU, and then upload the fully formed model->projection transform(via update subresource) to the shader as a single matrix, so you are not performing all of those muls in the first place.

1. 1
2. 2
3. 3
Rutin
15
4. 4
5. 5

• 9
• 10
• 9
• 9
• 11
• ### Forum Statistics

• Total Topics
633691
• Total Posts
3013348
×