I'm using FireMonkey to create a 3D scene, which works well: camera set up and in the image below, three stretched cubes show the three axes (red X, green Y, blue Z.)
Normal 3D perspective view in FireMonkey -
Projection
ispjCamera
.
However, this is a perspective 3D scene, and I would like an orthographic 3D projection instead - that is, one in which the size of objects does not diminish as they get further away. (The ultimate idea is to use this to show a 3D isometric view.) FireMonkey seems to have no orthographic projection code - pjCamera
translates to using a perspective matrix.
I have no need for a perspective 3D view at all so have approached this by replacing the perspective matrix method with a method to create an orthographic matrix instead. That is, TContext3D.GetProjectionMatrix
(which gets the perspective matrix) calls MatrixPerspectiveFovRH
to calculate a perspective matrix:
Result := MatrixPerspectiveFovRH(cPI / 4, FWidth / FHeight, 1.0, 1000.0);
I am replacing this with a call to an ortho matrix instead:
Result := IdentityMatrix3D;
Result.m11 := 2 / FWidth;
Result.m22 := 2 / FHeight;
Result.m33 := 1 / (zn - zf);
Result.m43 := zn / (zn - zf);
where zn
= 1 and zf
= 1000. FWidth
is the width of the view in pixels (say, 320) and FHeight
the height in pixels, say 240.
This initially appears to work okay-ish, although further away from the objects than I expected:
The problem is that the rendered image no longer seems to change with the camera position. I have verified the world-view matrix is calculated the same (ie unaffected by my changes) but when I move the camera closer to (0,0,0) the visible objects get trimmed, but the rendered image itself doesn't change. For example, here I have moved the camera very close to (0,0,0) and here are the perspective and orthographic renderings of the same camera position:
Clearly something is wrong with how I'm calculating the orthographic projection, but what I don't know.
- I do know that changing the width and height used in the ortho calculation appears to move the objects nearer and further - smaller width and height moves them closer to the screen.
- I am fairly sure the ortho matrix setup is supposed to be correct - although obviously this is wrong :)
- Although it uses DirectX under the hood, the perspective matrix is a right-handed matrix, so the ortho one should be too.
I have read quite a lot about how to set up an orthographic matrix but obviously not the right things. For example:
- Do
width
andheight
represent the screen width and height, or something else - frustum for example? Nothing I read explained what these were, assuming they were obvious. - If they are something else, where can I extract their values from? Can I extract them from the perspective matrix if I allow that to be calculated?
Thankyou for your help.