I wanna have an object (e.g. a sphere) which is placed directly in front of the camera (let's say "5cm" in front). When the camera is moved, the object should always follow the movement of the camera.
In my rendering loop, I calculate the position of the camera in world space using the inverse of the view matrix:
glm::mat4 viewMatrixInverse = glm::inverse(camera->GetViewMatrix());
glm::vec3 cameraPositionWorldSpace = glm::vec3(viewMatrixInverse[3][0], viewMatrixInverse[3][1], viewMatrixInverse[3][2]);
This seems to work fine and as I move towards the world origin, the camera position approaches (0,0,0) as well. Now when I try to render a sphere at the camera position, this works perfectly fine and the camera is always positioned in the centre of the sphere.
The rendering part looks like this:
sphere->ResetModelMatrix();
sphere->TranslateModel(cameraPositionWorldSpace);
sphere->Render(GL_TRIANGLES);
Now, I don't want to "sit" inside the sphere, I'd rather have the sphere positioned a few units in front of the camera. I cannot seem to figure out how I have to translate the sphere correctly so that it is always aligned with the direction vector of the camera.
add an offset vector to the position in the direction the camera is looking:
sphere->TranslateModel(cameraPositionWorldSpace+camera->LookingDirection().normalized()*5);
Related
Often, we see the following picture when talking about ray tracing.
Here, I see the Z axis as the sort of direction if the camera pointed straight ahead, and the XY grid as the grid that the camera is seeing here. From the camera's point of view, we see the usual Cartesian grid me and my classmates are used to.
Recently I was examining code that simulates this. One thing that is not obvious from this picture to me is the requirement for the "right" and "down" vectors. Obviously we have look_at, which shows where the camera is looking. And campos is where the camera is located. But why do we need camright and camdown? What are we trying to construct?
Vect X (1, 0, 0);
Vect Y (0, 1, 0);
Vect Z (0, 0, 1);
Vect campos (3, 1.5, -4);
Vect look_at (0, 0, 0);
Vect diff_btw (
campos.getVectX() - look_at.getVectX(),
campos.getVectY() - look_at.getVectY(),
campos.getVectZ() - look_at.getVectZ()
);
Vect camdir = diff_btw.negative().normalize();
Vect camright = Y.crossProduct(camdir);
Vect camdown = camright.crossProduct(camdir);
Camera scene_cam (campos, camdir, camright, camdown);
I was searching about this question recently and found this post as well: Setting the up vector in the camera setup in a ray tracer
Here, the answerer says this: "My answer assumes that the XY plane is the "ground" in world space and that Z is the altitude. Imagine standing on the floor holding a camera. It's position has a positive Z component, and it's view vector is nearly parallel to the ground. (In my diagram, it's pointing slightly upwards.) The plane of the camera's film (the uv grid) is perpendicular to the view grid. A common approach is to transform everything until the film plane coincides with the XY plane and the camera points along the Z axis. That's equivalent, but not what I'm describing here."
I'm not entirely sure why "transformations" are necessary.. How is this point of view different from the picture at the top? Here they also say that they need an "up" vector and "right" vector to "construct an image plane". I'm not sure what an image plane is..
Could someone explain better the relationship between the physical representation and code representation?
How do you know that you always want the camera's "up" to be aligned with the vertical lines in the grid in your image?
Trying to explain it another way: The grid is not really there. That imaginary grid is the result of the calculations of camera's directional vectors and the resolution you are rendering in. The grid is not what decides the camera angle.
When you are holding a physical camera in your hand, like the camera in the cell phone, don't you ever rotate the camera little bit for effect? Or when filming, you may want to slowly rotate the camera? Have you not seen any movies where the camera is rotated?
In the same way, you may want to rotate the "camera" in your ray traced world. And rotating only the camera is much easier than rotating all your objects in the scene(may be millions!)
Check out the example of rotating the camera from the movie Ice Age here:
https://youtu.be/22qniGtZhZ8?t=61
The (up or down) and right vectors constructs the plane you project the scene onto. Since the scene is in 3D you need to project the scene onto a 2D scene in order to render a picture to display on your screen.
If you have the camera position and direction you still don't know whether you're holding the camera right-side up, upside down, or tilted to the left and right.
Using camera position, lookat, up (down) and right vectors we can uniquely define the 3D scene is projected into a 2D picture.
Concretely, if you look at the code and the picture. The 3D scene are the objects displayed. The image/projection plane is the grid infront of the camera. It's orientation is defined by the the camright and camdir vectors (because we are assuming the cameras line of sight is perpendicular to camdir, camdown is uniquely defined by the other two).
The placement of the grid is based on the camera's position and intrinsic properties (it's not being displayed here, but the camera will have a specific field of view).
For the sake of simplicity let's take OpenGL rendering system as an example. According to what I have learnt,
The camera in OpenGL is aligned with the world space's origin i.e (0,0,0). I also read that we don't move the camera so it will stay at it's original position of (0,0,0) in world coordinates. The camera faces in the negative z direction.
Thus the question is, if you don't move the camera then it will always stay at world space's origin of (0,0,0). If that's the case then there will be no difference between world and eye coordinates. Because for example, Object A position in world coordinates is (2,2,-5). In eye coordinates it will be the same (2-0, 2-0, -5-0) = (2,2,-5)
The camera is the eye. If you don't move your camera, it means that your View matrix is an identity matrix so any coordinate you multiply with it will remain the same.
Lets take your example, we have a point being rendered (2.0, 2.0, -5.0). This is the world space position of the point. It means the point lies at (2.0, 2.0, -5.0) regardless of where the camera is.
If the camera is at origin like you say, yes the eye(camera) space position is the same as the world space position.
For a simple example, lets say you want to move your camera 2 units in the positive z-axis. Now your camera is at (0, 0, 2) and when you look from your camera(or eye), the point will be 2 units farther away in z axis from the origin, since you moved your camera back, so the eye space position is (2.0, 2.0, -7.0).
This is what happens with more complicated transformation on your camera. You will have a view matrix which will just be the inverse of your camera's transformation, and this is applied to every point in world space to convert it to eye (or camera) space.
In OpenGL, if you rotate first and translate afterwards, then all objects will rotate about their own origins. If you translate first and then rotate, objects should rotate around the origin (camera). But this doesn't happen. Everything rotates about the world axis, not the camera.
This:
transformationMatrix.setIdentity();
transformationMatrix.mul(rotationMatrixX);
transformationMatrix.mul(rotationMatrixZ);
transformationMatrix.mul(rotationMatrixY);
transformationMatrix.mul(translationMatrix);
doesn't work. How do I rotate everything around the camera? For object in the center of the "world" (a cube at 0,0,0), translation and rotation are relative to the camera. The code above rotates the whole world, but the center of the world never changes its coordinates relative to camera. The camera has always the same direction of view.
===========================================
ADDED:
THERE IS NO lwjgl.util IN lwjgl 3 ANYMORE. SO NO gluLookAt FUNCTION.
I'v solved the problem by rotation around arbitrary axis. Tries to use JOGL, but somethig is wrong: JOGL setPerspective wrong?
Forgive me if I am asking similar question but I am not getting the right answer or may be I am unable to understand how to implement it
I have to load HUD in front of camera I got camera DOF (x,y,z,apha, beta, gamma) I have only this information. How can I use camera DOF to translate the HUD in front of camera.
float x = eye[ 0 ].X()+ 0.465;
float y = eye[ 0 ].Y()+ 1.0; //bringing in front of camera
float z = eye[ 0 ].Z()- 0.08;
I am adding few magic numbers to x,z (above mentioned lines ) and then HUD is right on the screen but if the camera is moved the hud is disappeared because these magic numbers are for only that camera position. I want to know the solution
one of my friend told me following
Feed the camera rotation into the HUD_DOF_All so the HUD rotates to face the camera square on.
Then in SetInstancePosition use the eyePos + eyeDir * M
I dont know how to achieve that or if it is true.
Thanks in advance
How can I use camera DOF to translate the HUD in front of camera.
You're thinking too complicated: OpenGL just draws points, lines and triangles. OpenGL does not maintain a 3D scene!
To draw a HUD you simply draw it at the desired position. You do this simply be setting the right projection and modelview transformations that put the HUD at the desired location of the screen. If you're using the programmable pipeline (shaders) you set the appropriate uniforms. If you use the fixed function pipeline, setup a fresh, HUD appropriate projection and modelview matrix, then draw the HUD.
I've read through several over-complicated articles on rendering a 3D scene with OpenGL, and haven't really found something that helps me to visualize the basic concepts of scene navigation with respect to glRotate and glTranslate calls.
From experimenting with the examples provided by LWJGL (my particular OpenGL library), I understand very basically what effect comes of their use. I can use glTranslate to move to a point, glRotate to rotate about that point, and glLoadIdentity to snap back to the origin or glPopMatrix to go back to the last glPushMatrix, which are essentially snapshots of a location and rotation. Finally, the scene will render to screen with respect to the origin.
So basically, to put a cube at point A with rotation B:
glTranslate(A.x,A.y,A.z) [now focused on point A]
glRotate(B.,,*,*) for pitch, yaw, and roll; [now rotated to rotation B]
glBegin(GL_QUADS) and glVertex3f()x4 for each 'side'(quad) relative to object's origin
glEnd()
glLoadIdentity() [reset to origin for other objects, not needed if only drawing the cube]
As for the "camera", since openGL's "eye" is fixed, the scene has to move inversely from the camera in order to simulate moving the eye with the camera. This is my understanding so far, and if this is wrong, please put me on the right path.
Now for my specific situation and question:
My 'scene' consists of terrain and a player (some arbitrary shape, located at a terrain-relevant location and a 'camera' head). The view should rotate with respect to the player, and the player move with respect to the terrain. I want the final rendering to essentially "look through" the player's head, or camera. My confusion is with the order of translate/rotate calls for rendering each part, and the direction of translation. Is the following the proper way to render the terrain and player with respect to the player's "camera"?
translate away from the player by the player's distance from origin (move the scene)
rotate away from the player's rotation (player looks 40 degrees right, so rotate scene 40 left)
render terrain
reset via glLoadIdentity
render player's head (if needed)
translate to body/hands/whatever position
rotate away from the player's rotation (step 2 again)
render body/hands/whatever
Also, does rotating have an effect on translation? Aka, does OpenGL translate with respect to the rotation, or does rotation have no bearing on translation?
I can use glTranslate to move to a point, glRotate to rotate about that point, and glLoadIdentity to snap back to the origin or glPopMatrix to go back to the last glPushMatrix, which are essentially snapshots of a location and rotation.
No not quite. Those functions have now idea of what a scene is. All they do is manipulating matrices. Here's an excellent article about it:
http://www.opengl.org/wiki/Viewing_and_Transformations
One important thing to keep in mind when working with OpenGL is, that it is not a scene graph. All it does is rendering flat points, lines and triangles to the framebuffer. There's no such thing like a scene you navigate.
So basically, to put a cube at point A with rotation B:
(...)
Yes, you got that one right.
As for the "camera", since openGL's "eye" is fixed
Well, OpenGL got no camera. It's only pushing vertices through the modelview matrix, does lighting calculations on them, then passes them through the projection and maps them to the viewport.