How to implement a Camera???

Started by
17 comments, last by EEPROM 22 years, 8 months ago
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."
"Simple is beautiful"
Advertisement
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
------------------General Equation, this is Private Function reporting for duty, sir!a2k
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
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)===-
Gaiomard Dragon-===(UDIC)===-
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.
"Simple is beautiful"
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
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.
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 .
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?
"Simple is beautiful"

This topic is closed to new replies.

Advertisement