Picture rendered from above and below using an Orthographic camera do not match
- by Roy T.
I'm using an orthographic camera to render slices of a model (in order to voxelize it). I render each slice both from above and below in order to determine what is inside each slice. I am using an orthographic camera
The model I render is a simple 'T' shape constructed from two cubes. The cubes have the same dimensions and have the same Y (height) coordinate. See figure 1 for a render of it in Blender.
I render this model once directly from above and once directly from below. My expectation was that I would get exactly the same image (except for mirroring over the y-axis). However when I render using a very low resolution render target (25x25) the position (in pixels) of the 'T' is different when rendered from above as opposed to rendered from below. See figure 2 and 3. The pink blocks are not part of the original rendering but I've added them so you can easily count/see the differences.
Figure 2: the T rendered from above
Figure 3: the T rendered from below
This is probably due to what I've read about pixel and texel coordinates which might be biased to the top-left as seen from the camera. Since I'm using the same 'up' vector for both of my camera's my bias only shows on the x-axis. I've tried to change the position of the camera and it's look-at by, what I thought, should be half a pixel. I've tried both shifting a single camera and shifting both cameras and while I see some effect I am not able to get a pixel-by-pixel perfect copy from both camera's.
Here I initialize the camera and compute, what I believe to be, half pixel. boundsDimX and boundsDimZ is a slightly enlarged bounding box around the model which I also use as the width and height of the view volume of the orthographic camera.
Matrix projection = Matrix.CreateOrthographic(boundsDimX, boundsDimZ, 0.5f, sliceHeight + 0.5f);
Vector3 halfPixel = new Vector3(boundsDimX / (float)renderTarget.Width, 0,
boundsDimY / (float)renderTarget.Height) * 0.5f;
This is the code where I set the camera position and camera look ats
// Position camera
if (downwards)
{
float cameraHeight = bounds.Max.Y + 0.501f - (sliceHeight * i);
Vector3 cameraPosition = new Vector3
(
boundsCentre.X, // possibly adjust by half a pixel?
cameraHeight,
boundsCentre.Z
);
camera.Position = cameraPosition;
camera.LookAt = new Vector3(cameraPosition.X, cameraHeight - 1.0f, cameraPosition.Z);
}
else
{
float cameraHeight = bounds.Max.Y - 0.501f - (sliceHeight * i);
Vector3 cameraPosition = new Vector3
(
boundsCentre.X,
cameraHeight,
boundsCentre.Z
);
camera.Position = cameraPosition;
camera.LookAt = new Vector3(cameraPosition.X, cameraHeight + 1.0f, cameraPosition.Z);
}
Main Question
Now you've seen all the problems and code you can guess it. My main question is. How do I align both camera's so that they each render exactly the same image (mirrored along the Y axis)?
Figure 1 the original model rendered in blender