We are about to switch to a new forum software. Until then we have removed the registration on this forum.
I'm trying to implement first person movement in a 3D environment using Processing however I'm having trouble understanding the projection system. I previously learnt how to do this using the Nehe OpenGL tutorials for C which uses the following projection system: -
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
When objects are drawn with this perspective objects that are positioned behind the viewer do not appear. This does not appear to be the case in Processing using the default 3D perspective. For example: -
void draw() {
background(0);
translate(width/2,height/2,position);
fill(255);
rectMode(CENTER);
rect(0,0,800,600);
}
When the rectangle is translated to position 0 on the z-axis, the object fills the screen as expected, however the object does not disappear until ~460 pixels translated into the foreground which doesn't make sense to me.
Can anyone provide any insight as to what's going on with the projection system and how I might replicate the prior perspective model.
Thanks,
Answers
perspective reference page says:
"The default values are: perspective(PI/3.0, width/height, cameraZ/10.0, cameraZ10.0) where cameraZ is ((height/2.0) / tan(PI60.0/360.0));"
so camera position depends on screen height and for a screen of height 480, cameraZ is about 140
i find camera() much easier to get along with.
I originally tried changing the perspective setting, which has a FOV of 60 degrees rather than 45 but that doesn't explain the z-clipping when an object is supposed to be behind the camera. Note:I should of mentioned my screen size for the above is 800 by 600 pixels so zNear-Far is ~51-5100
Can't say I really understand perspective translations, the format I used previously just worked as expected.
Not sure where you get 140 for cameraZ:
If fov=1.04 radians, height = 480, then cameraZ = 415 with a clipping range of 41-4156.
um, forum has chomped my quote from the reference page. i think i may've mucked up the tan() calculation (thinking it was a standard radians to degrees thing)
also, there was a bug in 1.5.1 where things behind the camera were still being drawn, badly and slowly. was only in p3d though and using opengl would fix it. not sure what the status of that is in 2.0.x though
can you post an entire sketch that shows the problem as succinctly as possible rather than just snippets. i can try and help but the more code i have to make up takes me longer and is less likely to reflect yours.
No problem and thanks for the assistance.
This displays the rectangle right in front of the camera filling the entire screen, moving the shape into the background allows us to see the rectangle's dimensions. However moving the shape into the foreground doesn't make it disappear until ~400 pixels in.
I'm trying to create a 3D version of a simple 2D game by treating the player's character as the camera position. However I can't get objects to appear behind the camera when their suppose to.
that's odd. using p3d it disappears between 510 and 515, which matches your value for zCamera above (519.6 i make it)
with opengl it disappears between 465 and 470. which is 519 - 51.9 (ish)
so i'm guessing that the perspective call is setting the camera z to zCamera (clue is in the name, i guess) and p3d doesn't respect the front clipping plane, whereas opengl does.
if you add printCamera() to the bottom it prints this:
is that final column the camera position? the translate in line 16 explains the -400 and the -300. so the -519 is the camera z position, defined by the call to perspective.
you can change the position with camera();
alternatively, do your own z-clipping 8)
So basically Processing is going to be uncooperative? :)
I ran using the different renderers with the above z plane the shape disappears at +468 P3D and +468 OpenGL. I actually tried pushing the object into the background and it disappears at -4680.
It looks like something is screwing up the z plane put I don't know what.
Note: I'm using Processing 2.2.1.
I'm not familiar with the camera function if I wanted to instigate the same movement effect as above how would I write that?
camera() I believe is modelled on gluLookAt which I really couldn't get to grips with.
no, i don't think there's a problem. it's just that the camera isn't where you think it is.
at what z value would you expect things to disappear?
(the above was using processing 1.5.1 btw)
those near and far measurements, btw, aren't absolutes, they are distances from the camera position. so a camera at -520 has a znear of 52. it won't see anything nearer to it than 52 pixels, ie anything with a z of -468 or lower, exactly what you are seeing.
I'm assuming that the camera is positioned at (width/2, height/2, 0) (or the middle of the screen) and the origin point (0,0,0) is located in the top-left hand corner.
To be honest I've not really sure where the object should disappear given the clipping plane. I'd of assumed it should of disappeared at the z=-51.9 rather than z=468 and so not be viewable in the first place.
The only thing which seems to make sense so far is that the clipping range (of 5180 pixels) does actually exist even if its not from the z coordinates I'm expecting.
no, it's setting the camera z position so that things that are draw on the z=0 plane appear the right size for the monitor (ie a 800x600 rectangle at z=0 fills a 800x600 window exactly). it's using the fov to calculate this and moving the camera backwards - the tan() in the calculations is doing this, opposite / adjacent using half the height as opposite, standard trig stuff.
the near and far are, as i said, distances from the camera. things nearer than the near won't appear. things further away than the far won't appear. (they MUST be distances because you might not be looking down the z axis in which case absolute z values would make no sense)
um, am trying to find a decent picture but can't. something like the 6th one here, but with annotations: http://www.glprogramming.com/red/images/Image48.gif
(would be interesting to write something that showed how all this stuff hangs together might do that tonight)
Thanks koogs! I'm getting there. Thanks for hanging in.
I've read some more on how perspective is done in native OpenGL, from what I understand the eye position [1] is at 0,0,0 rather than in front of the origin point as with Processing. I just need to take into account that the camera is at a different position than the origin.
Incidentally this diagram [2] on glPerspective was also useful.
[1] http://www.opengl.org/archives/resources/faq/technical/viewing.htm
[2] http://www.felixgers.de/teaching/jogl/perspectiveProjection.html
thinking about the 'camera is at 0, 0, 0' thing and i think you might be right. but moving the camera back or moving the whole world forwards is effectively the same thing.
anyway, i wrote this showing my view of things. it uses peasycam (which is very useful) but nothing else. oh, it's 1.5.1. change the fov, w and h as required.
Neat, that's a really nifty program to help visualise the camera model.
Thanks to your help I finally understood how the camera works! Processing doesn't make rendering first person movement easy; for example with the placement of the origin point at the top left hand corner in order to rotate objects around the camera you need to first translate it to where the camera is located, rotate it, then put it back:
Only then can you translate it to its destination. In native OpenGL the camera starts at the origin point so you just need to rotate the object before deploying.
Also the scale of objects appears to be locked into the screen resolution. Native OpenGL uses an arbitrary scale independent of the screen resolution, but Processing defines shapes by the length in pixels. This takes some getting use to.