Picture rendered from above and below using an Orthographic camera do not match

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.

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. Here's 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.

Rendered from above

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)?

• The solution so far seems to be to move the camera that takes a picture from below exactly one pixel to the left (-x). However I cannot explain why and thus cannot guarantee that it will work for everything I throw at it. Any ideas? – Roy T. Jun 1 '14 at 9:01
• Did you thought about keeping everything in place, but scaling the Y of the model (cubes) by -1 ? Then you would have all the same except for the objects being flipped. P.S. Of course you will need to -1 the normals and polygons faces too. – Kromster says support Monica Jun 2 '14 at 8:33
• Thats actually a pretty cool idea – Roy T. Jun 3 '14 at 9:28
• Since you approve, I've posted it as an answer. Tell me if it works for you! – Kromster says support Monica Jun 3 '14 at 9:34

This is a different view on the problem presented, which might help to avoid rasterization differences issues altogether

Did you consider keeping everything in place, but scaling the Y of the model (cubes) by '-1' along the section plane? Then you will have everything exactly the same except for the objects being flipped upside-down - meaning you will get their down sides for your goal. Of course you will need to '-1' the normals and polygons facing directions too.

• Though your answer does not explain why my method didn't work. (And that's where the bounty was for) I'll not award the bounty right now. But because its a good suggestion the automatic 50% bounty should be awarded to you in a day, and I think you deserve it :). – Roy T. Jun 9 '14 at 12:06
• @RoyT.: Sounds fair. However you still ought to tell us, if suggested solution did solved your problem - so that others who face the same problem will know how to handle it. – Kromster says support Monica Jun 9 '14 at 12:09