Archived

This topic is now archived and is closed to further replies.

EEPROM

How to implement a Camera???

Recommended Posts

Hi everybody. I would like to know how to implement a Camera into a 3D engine, so that you can look around instead of looking into a fixed direction. I was thinking that I should use 2 points for the camera. One vertex for the actual position of the camera, and one vector for the spot direction. Is that right? And how to I actually render the world from the camera''s perspective? Should I rotate the whole world in funtion of the cameras position/spot direction? "Simple is beautiful"

Share this post


Link to post
Share on other sites
you can either use direct3d or opengl for that. whichever one you choose has camera features.

a2k

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
AFAIK, OpenGL does NOT have camera features. Granted, with gluLookAt() you can make a simple camera system, but OpenGL itself does not support any such feature. IMO, if your using OGL, just roll your own camera system to build a camera matrix from scratch, then load the matrix on to the matrix stack and multiply.

Share this post


Link to post
Share on other sites
I don''t want to seem rude, but I give a shit for all this pre-coded 3D API''s. (OpenGL/Glide/Direct3D/etc.)

What I''m doing is to build a 3D engine in DirectDraw for me to learn how a 3D engine works. I want to know how things are calculated etc. And now I''m asking how I could implement a camera. What I want are some formulas, tutorials, etc...

Please, don''t mention any 3D API''s because using them is for people who allready know how a 3D engine works, or for those who just want to code a 3D engine without any deep knowledge. I plan to use them later to get beautiful graphics on high-resolution.

"Simple is beautiful"

Share this post


Link to post
Share on other sites
okay, gotcha. um, you need to perform what''s called a world to viewer coordinate transformation with a special matrix.

Here''s a link to info as to how this is performed:

http://www.siggraph.org/education/materials/HyperGraph/viewing/view3d/3dview1.htm

a2k

Share this post


Link to post
Share on other sites
OK, thanks. That was exaclty what I am looking for. If you have some other URL''s about this topic I would apreciate it.

I like it to read 2 or 3 diferent tutorials about the same topic, because each author has a diferent point-of-view. So, reading 3 diferent opinions is the best way to make your own conclusions

"Simple is beautiful"

Share this post


Link to post
Share on other sites
Another URL?

Sure, look in the DirectX documentation : )

But hey, feel free to bitch about mentioning an API and not look at it.

G''luck,
-Alamar

Share this post


Link to post
Share on other sites
OK, I''ve found 2 tutorials about camera calculations. One of them provided by a2k .

Both tutorials use a 3x3 Camera Matrix in the clculations. And this is my new question now. What is inside this 3x3 camera matrix?

I really don''t know what to put in there. I have the cameras position inside a vertex:
[X]
[Y]
[Z]

and I''m sure that I must put the cameras direction vector into this 3x3 Camera Matrix, but how???

[Vx,0,0]
[0,Vy,0]
[0,0,Vz]
?

Any idae?

Share this post


Link to post
Share on other sites
3x3 Matrix? Hmmmm, interesting. It would be a little bit easier if you used 4x4 Matrices and worked in Homogeneous space rather than Euclidean space. Then the matrices would be:

Translation:
[1 0 0 X]
[0 1 0 Y]
[0 0 1 Z]
[0 0 0 1]

Rotation around X:
[ 1 0 0 0]
[ 0 cosT -sinT 0]
[ 0 sinT cosT 0]
[ 0 0 0 1]

Rotation around Y:
[cosT 0 sinT 0]
[ 0 1 0 0]
[-sinT 0 cosT 0]
[0 0 0 1]

Rotation around Z:
[cosT -sinT 0 0]
[sinT cosT 0 0]
[ 0 0 1 0]
[ 0 0 0 1]

Remember to rotate before you translate and then invert.

M = Inverse(T * Rz * Ry * Rx)

But if your writing yourself a renderer get yourself the bible. Computer Graphics: Principles and Practice.

Share this post


Link to post
Share on other sites
If you got access to your local bookstore, flip open Game Programming Gems. They have the matrix in there, and a description of where the aspect ratio and field of view go into that matrix.

your aim is to find a way to express a camera with a matrix transformation that accepts:

camera position vector
camera target vector
camera "up" vector
field of view
and aspect ratio

the W->V matrix can readily take these values in (i think)

a2k

Edited by - a2k on August 8, 2001 1:34:12 PM

Share this post


Link to post
Share on other sites
I''m starting to think that I should stop coding this engine and start learning some heavy math about Matrices, 3D perspectives, etc...

It''s cool to see when the engine works. Actually it displays solid 3D Studio Max objects without texture, from a fixed perspective point. But I think that it makes no sense to implement all this math stuff without understanding why a 3x3 or 4x4 matrix multiplied by a sort of vectors gives me the new perspective vertex. Many people out there just want to see there engine working, but I want to know WHY DOES IT WORK. What kind of 3D coder will I be if I''m unable to understand what I''m coding? What kind of 3D coder will I be if I can''t code a 3D engine without those 3D Render API''s?

3D coding is very hard when you don''t have the math base. At this point, 3D coding is MUCH harder for me than raw Win32 Assembly programming. Maybe it''s not on time for me to code 3D engines.

"My dream was to be a Demo coder."

Share this post


Link to post
Share on other sites
it was a good attempt, but i would recommend the way to do that is to understand how the transformation works, as well as the rest of the pipeline, and THEN use the APIs. see, you don''t really have to code the engine, i''m sure you''d be more thrilled coding particle systems and reflection algorithms than the lower level stuff, though it is good to understand.

why reinvent the wheel?

a2k

Share this post


Link to post
Share on other sites
DISCLAIMER: I have no idea if this is what matrices do, but this is the general projection method in easy-to-understand language. And if anything is inaccurate, someone please correct me!!


We'll start with an assumption:

- The size of an object is inversely proportional to the distance of the viewer from that object.

Translated to an equation, that means (if z is depth):

x_on_screen = x / z;
y_on_screen = y / z;

Except there's one problem with that. although it would work on a piece of graph paper, the screen's coordinates don't work like that. For one thing, on the screen, y increases top-to-bottom, while using cartesian coordinates, it's the reverse. And 0, 0 is the top left corner, while in cartesian coordinates, that's the center. So all we have to do is flip this vertically and add in half the screen's width and height to change this from cartesian coordinates to screen coordinates:

x_on_screen = x / z + half_screen_width
y_on_screen = -y / z + half_screen_height

One final check is to make sure that objects behind the camera cannot be seen:

if(z > 0)
{
x_on_screen = x / z + half_screen_width;
y_on_screen = -y / z + half_screen_height;
//Then do your drawing stuff
}

But all this only works in camera space - that is, where the camera is at 0, 0, 0 facing along the z axis pointing towards the positive side.

So you'll need to rotate your points relative to the camera, so that they're transformed from world space to camera space. Rotation in a plane is pretty straightforward. That's just a matter of using the sine and cosine functions (they're CIRCULAR functions, after all, aren't they?!)

x = cos(radians) * distance from origin (0, 0)
y = sin(radians) * distance from origin (0, 0)

So, for 3d rotations, you'll just need to rotate in three planes, XY, XZ, and YZ, aka rotation along the Z, Y, and X axes, respectively, OR roll, yaw, and pitch, also respectively.

Of course, the technique I just described treats the camera lens as a single point. That's fine for most purposes, but if you want a little more realism (less warping at screen edges), you should treat the the camera lens as a plane. So all you have to do is subtract the distance traveled from the focal point to the lens, and you're fine (just assume the focal point is 1 unit from the lens and the lens is the same size as the screen; it's just a proportion, so those numbers makes for easy calculations) That's just trig. But note that you have to transform x and y to cartesian coordinates for this calculation too.

x_on_screen = x / (z - tan(x - half_screen_width)) + half_screen_width;
y_on_screen = -y / (z - tan(y - half_screen_height)) + half_screen_height;


So that's the basic theory behind it all, assuming everything I just wrote is correct. Hope that helps.

But for explaining why matrix multiplication works, I have no idea.

Edited by - TerranFury on August 8, 2001 9:30:37 PM

Share this post


Link to post
Share on other sites
Hey man! At last someone who thinks the same way I do!

I believe that it''s the right track. I''ve tried to build my own software renderer but, as you know, it''s a LOT of work. Mine didn''t quite work, but it was a great experience, I''ve learned a lot, even without finishing it.

As for not using the APIs, the bad thing is that you won''t get hardware accelleration. The good thing is that you can optimize it for your specific needs (for example, DOOM''s engine didn''t need to support looking up/down, so ID made a lot of optimizations to take advantage of this).

Well, good luck

Gaiomard Dragon
-===(UDIC)===-

Share this post


Link to post
Share on other sites
TerranFury: Yes, all this is familiar to me. I could rotate the whole world around the origin(0,0,0) if I wish. But this is somewhat like a, hm, bruteforce camera . My idea was to use vectors, etc. Maybe I should use this Bruteforce Camera just to make this shit work. I will think about it.

Outworlder: Yes, API''s are fast and help us a lot. But I want to know how this 3D calculations are done. Why do you think have I learned to code in Assembly? Because I like to do things myself. I really will use those 3D API''s later, but not yet.

a2k: "why reinvent the wheel?"
Because I don''t want to be an API dependent 3D coder.

I have a question. How old are you guys? It seems that all of you code 3D stuff. Do you do that at work or just for fun? I''m 18 years old and I think it''s time to learn this damn 3D calculations before I grow old.

Share this post


Link to post
Share on other sites
EEPROM: I''m 21 and wishing I had learned more 3D math earlier.

But check this tutorial out on how to use the vector method. It should be helpful, even though it is for OpenGL.

http://www.wi.leidenuniv.nl/~dpalomo/camtut/camtut.html

Share this post


Link to post
Share on other sites
I noticed a mistake in my previosus post. Distortion correction is only necessary if you''re using a distance function, and not dividing by z. If you just divide by z, you ARE finding the distance from the plane. subtracting tan(...) is only necessary if you, instead of z, use sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2) + pow(z2 - z1, 2)). Using the distance function can be useful if you include rotation in that formula, so, in one shot, you transform from world space to screen coordinates.

Also, I''m not even sure that this would be slower than matrices.

Share this post


Link to post
Share on other sites
Yep, matrices are just another way of organizing sets of data. The actual math that ends up being performed is the same, it seems. See http://www.inversereality.org/tutorials/graphics%20programming/3dwmatrices.html .

Share this post


Link to post
Share on other sites
Cool... two more URL''s to read! I can''t have enough of them

Do you think that I should start coding 3D using some kind of API and learn the hard stuff later? Or should I continue learning 3D calculations and build my own Software 3D Engine?

Share this post


Link to post
Share on other sites