AcademySoftwareFoundation / openexr

The OpenEXR project provides the specification and reference implementation of the EXR file format, the professional-grade image storage format of the motion picture industry.
http://www.openexr.com/
BSD 3-Clause "New" or "Revised" License
1.64k stars 619 forks source link

understanding openEXR's 3D coordinate system #1687

Open kfjahnke opened 8 months ago

kfjahnke commented 8 months ago

I have a problem understanding the openEXR documentation. In the Technical Introduction, there's a section "Projection, camera coordinate system and screen window". Above it there's a drawing. In the drawing, the x axis points to the right. In the text it says:

Projection, camera coordinate system and screen window

Many images are generated by a perspective projection. We assume that a camera is located at the origin, O, of a 3D
camera coordinate system. The camera looks along the positive z axis. The positive x and y axes correspond to the
camera’s left and up directions.
...

It seems to me that the image and text do not agree about the direction of the x axis. Am I missing something? Which one is correct?

kfjahnke commented 7 months ago

ping! Anybody out there?

peterhillman commented 7 months ago

I think the lack of response indicates how few people understand that diagram, but yes I think it's a typo in the text and positive X should be right not left

kfjahnke commented 7 months ago

few people understand that diagram

you're kidding. everyone doing 3D geometry must understand which way their axes point.

I am currently working my way into environment formats, bot lat/lon and cubemap, and their representation as openEXR and OIIO understand them. I assume (!) that OIIO uses openEXR axis semantics, but I'm not sure. When I access a lat/lon environment using OIIO's 'environment' function (the access is via 3D directional vectors), the axis order which works for me is this (quote from my program envutil

// openEXR uses different 3D axis semantics, and if we want to use
// OIIO's environment lookup function, we need openEXR 3D coordinates.

// Here's what the openEXR documentation sys about their axis
// order (next to a drawing which says differently, see this issue:
// https://github.com/AcademySoftwareFoundation/openexr/issues/1687)

// quote:
// We assume that a camera is located at the origin, O, of a 3D
// camera coordinate system. The camera looks along the positive z
// axis. The positive x and y axes correspond to the camera’s left
// and up directions.
// end quote

// so we'd get this axis order, assuming they store x,y,z:

enum { EXR_LEFT , EXR_UP , EXR_FORWARD } ;

// the cubemap comes out right this way, so I assume that their text
// is correct and the drawing is wrong.

so my conclusion is just the opposite: the diagram is wrong and the text is right. There must be people at openEXR who can say what's right, hence the ping.

meshula commented 7 months ago

The OrientationCube.exr file that we distribute is correct. If you position a camera in the center of an environment mapped with it and look around, you should see the axis indicated in each face (+x, -x, etc) in the expected direction, and the little axis images should also be oriented as expected. I don't think this helps you with the question you are asking but I personally use the observable behavior as a ground truth, and the reference to OpenImageIO face ordering in relationship to the OpenEXR documentation diagram is confusing to me :)

image

The picture you are referring to is this one.

If we are inside the cube looking at the faces, with a camera that looks down the NEGATIVE axis (even though the text says the camera is looking down the POSITIVE axis), then cube faces work as expected.

My opinion is that in the cubemap case, that diagram is doing too much work with too little context, and I'm not sure we can reconcile that image with what the text is trying to say about planar images with the facts about cube maps simultaneously, without making things worse. I think we need another diagram for cube maps using the strip map I posted above mapped on to a cube to unambiguously illustrate how it works.

Furthermore, latlong images are also meant to be environment mapped. I think we would be overburdening that image of a planar projection to try to say meaningful things about latlong environment maps, and so there should be another image, using the the cube strip remapped to latlong to show how things work when the camera is at the center of the projection. Furthermore, the diagram should show where 0,0 in the 2d image is so that one may know how the latlong image is rotated about the polar axis.

If I had time I would create these images, but perhaps someone besides me might undertake some improvements.

kfjahnke commented 7 months ago

If we are inside the cube looking at the faces, with a camera that looks down the NEGATIVE axis (even though the text says the camera is looking down the POSITIVE axis), then cube faces work as expected.

If you're changing the sign on the z axis, the x axis goes the other way, and the y axis is not affected. This is just the same as changing the sign on the x axis. The two are linked - you can't change only one of them, whereas the y axis 'stands by itself'. This is what you see when converting between polar and cartesian coordinates: to produce the azimuth, you need a sine and a cosine term. The elevation only needs a cosine. So changing the sign on the x or the z axis is just the other side of the same coin.

We can agree on the fact that the diagram is wrong. I think the diagram could be stripped down to the essential to clarify openEXR axis semantics - if you need a diagram at all for that: the text is sufficient, and the diagram (wrong as it is) only confuses matters.

Thanks for clarifying, @meshula - we've had a bit of discussion already in this issue, and I've made some progress towards writing a new tool to convert between lat/lon and cubemap formats - maybe you've had a look at the link to envutil I gave in my previous post. This was mainly fun, with an issue in OIIO which needed setting straight, but otherwise it was a good way to 'exercise' may library zimt to code the conversions in multithreaded SIMD code, and the program is coming as a zimt example program. I think it does pretty much the same thing which exrenvmap does, but with the 'better mathematics' you thought should be applied. For environment lookup, it uses OIIO's texture system code, which uses an anisotropic antialiasing filter steered by the derivatives of the transformed coordinates. That's the default - it can also use fast bilinear directly on the source data. Have a look!

meshula commented 7 months ago

Nice to see the final result of envutil, nice way to wrap up that thread :)

I was thinking about the diagram some more, and started wondering why the camera is in the diagram at all. I think "Projection, camera coordinate system and screen window" refers to the standard attributes in the EXR file, and I have a feeling that originally OpenEXR might have been more tied to a camera model. If the diagram is that, we should definitely say so, and name the attributes being illustrated. A further problem, if it's an attribute explanation, is that we've revised and clarified the standard attributes and I don't have a memory of us reviewing the diagram to make sure it still agrees with the standard attributes.

kfjahnke commented 6 months ago

Nice to see the final result of envutil, nice way to wrap up that thread :)

I carried on with this project - envutil is now quite complete and has several options to do the environment/texture lookup, among them OIIO's sophisticated lookup code, and my own invention: 'twining', in-lined supersampling and subsequent weighted pixel binning. Then I decided to add a second program 'extract' which can produce reprojected/cropped images from a lat/lon or cubemap environment. This has now reached a 'presentable' stage as well, and today I've uploaded an experimental debian package. Documentation is on the github project page.

kfjahnke commented 4 months ago

I rejoined the code paths, there is now only one program 'envutil' which does all sorts of environment lookups and generates images, image sequences and videos. This is pretty much how far I want to take it right now, there are a few issues left to be dealt with (see the project's issue tracker).

meshula commented 4 months ago

Congrats on getting to that milestone!