I am rendering a simple cube with 8 vertices, but I am having an issue understanding how to get the camera closer to the cube. I was expecting setting the near plane below 1.0 would allow me to get closer to the objects, and they would appear bigger, however, setting the near plane below 1.0 does not do it (the entire code is public here, but here is the relevant part)
f32 r = 1;
f32 l = -1;
f32 t = 1;
f32 b = -1;
f32 n = 1.0f;
f32 f = 5.0;
mat4 Projection =
{{
2.0f*n/(r-l), 0, (l+r)/(r-l), 0,
0, 2.0f*n/(t-b), (t+b)/(t-b), 0,
0, 0, (f+n)/(n-f), (2*n*f)/(n-f) ,
0, 0, -1, 0,
}};
I based my projection matrix on this
The moment you set n < 1.0 then objects initially look further (that is because the projection matrix multiplies X,Y by n) thus, we achieved nothing because the maximum size an object can appear on the camera seems to be fixed! I do understand, that I can effectively zoom in by scaling the entire scene, but I believe I made a bug somewhere that might have caused this (or maybe my affine transformations are not complete? I have not added FOV and Aspect Ratio but that is because I want these to be fixed, to begin with). I think it is a bug because I have not read anything about an object having a maximum size on the screen, regardless of the camera distance.
So to summarize, my questions are: How do I get to make effectively make my camera get closer (and objects look bigger)? Or is it true that objects do have a maximum size that they can appear on screen? which is effectively their scaled coordinates multiplied by (1/z).
...how to get the camera closer to the cube.
As @Rabbid76 has pointed out, you move the camera closer by applying a translation to your model-view matrix. Changing the projection matrix can make the model bigger or smaller, but that's equivalent to zooming in/out (i.e. changing the FOV) while the camera remains stationary.
The moment you set n < 1.0 then objects initially look further ... thus, we achieved nothing because the maximum size an object can appear on the camera seems to be fixed!
Firstly, there's nothing special about n=1.0. The near and far planes are measured in your scene distance units, and those can be arbitrary. Just saying.
Secondly, the near and far planes are usually set according to your scene depth complexity, independent of the camera position. You should choose the near plane to be the closest your camera would ever get to any object, and then enforce that through collision detection and response (i.e. by preventing the camera from getting too close to the objects).
As an aside: in some circumstance one may want to change near/far planes to optimize the use of the fixed-precision depth buffer; however, nowadays there are better options to deal with that using a floating point depth buffer.
I do understand, that I can effectively zoom in by scaling the entire scene
Actually no. If you scale everything uniformly, its projection on the screen will stay the same. If you scale only the XY coordinates in the projective space then you get the zoom in/out effect, but that's what the projection matrix is already doing for you, and that's not the same as getting the camera closer to the object!
I have not added FOV and Aspect Ratio but that is because I want these to be fixed, to begin with.
I don't understand your reasoning. If you want these to be fixed, you isolate them as parameters and then calculate everything else based on those. In fact I never use that formula for the projection matrix with the top/left/bottom/right planes, precisely because it's counter-intuitive. Instead, use some math to calculate what you need from what you have. I prefer using physical camera properties as used in photography. In your case, use FOV and viewport size to set the projection matrix:
// parameters:
f32 n = 0.1; // the closest your camera ever be
f32 f = 10.0; // the farthest object you ever care
f32 fovx = 1.5; // horizontal fov in radians
f32 w = 1920, h = 1080; // the size of your viewport (for aspect ratio)
// temporaries:
f32 A = 1/tan(fovx/2);
f32 B = A*w/h;
mat4 Projection =
{{
A, 0, 0, 0,
0, B, 0, 0,
0, 0, (f+n)/(n-f), (2*n*f)/(n-f) ,
0, 0, -1, 0,
}};
After this those are fixed, and you move your camera by translating the model-view matrix as was said earlier.