Sign in to follow this  
lonewolff

Help with 3D camera please

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 VShader(VS_Input IN)
{
     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.

 

Thanks in advance smile.png

Share this post


Link to post
Share on other sites
Again one of those things, where when you take a step back and think the answer reveals itself. rolleyes.gif
 
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);

[edit]
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 smile.png Edited by DarkRonin

Share this post


Link to post
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 VShader(VS_Input IN)
{
	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 smile.png

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 smile.png

Share this post


Link to post
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. sad.png

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 this post


Link to post
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 smile.png

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 this post


Link to post
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 smile.png
 

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.

Share this post


Link to post
Share on other sites

Thanks heaps.

 

I am starting to find that these days I tend to answer my own question before others even reply (as you'll see from quite a few of my recent topics). That has got to be a good thing :)

 

I always make sure to come back and answer my own topics regardless for two reasons. It helps other people (hopefully) and I often find myself shelving projects for years at a time, in which I tend to make the same mistakes again when I start over. I have found some of my ancient posts coming back to instantly help me recently. So, it is an immediate reference for me also.

 

When I first come back to DX11, I think 'what the hell is going on', but then after a few days of getting my head around the essential concepts it becomes quite easy again.

 

I must be getting old - LOL :)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this