Thread: [Algorithms] Left-handed vs. right-handed
Brought to you by:
vexxed72
|
From: Eric H. <eri...@gm...> - 2009-05-06 04:09:43
|
I've written up my way of thinking about left-handed and right-handed world and viewing systems. It's a bit long-winded, but here it is: http://www.realtimerendering.com/blog/left-handed-vs-right-handed-viewing/ This topic is in one sense basic stuff, but it leads to so much confusion. Neither DirectX nor OpenGL does a good job of dealing with this confusion, IMO. In our book we kind of sidestep the whole issue (choose RH, stay RH). I'd love to get any feedback and corrections from people on this list (either here on the list, via private email, or on the blog), as I expect there are ways of thinking about it I hadn't even considered or have misinterpreted. Eric |
|
From: Ruben P. <rub...@gm...> - 2009-05-06 05:28:52
|
In my honest opinion, this is the same with "column major vs row major". Whatever you choose just stick with it. Make a clear documentation about your choose and how are you going to convert the data to your system. Then, forget about it and never ever change the decision you made. :) On Wed, May 6, 2009 at 6:09 AM, Eric Haines <eri...@gm...> wrote: > I've written up my way of thinking about left-handed and right-handed world > and viewing systems. It's a bit long-winded, but here it is: > http://www.realtimerendering.com/blog/left-handed-vs-right-handed-viewing/ > This topic is in one sense basic stuff, but it leads to so much confusion. > Neither DirectX nor OpenGL does a good job of dealing with this confusion, > IMO. In our book we kind of sidestep the whole issue (choose RH, stay RH). > I'd love to get any feedback and corrections from people on this list > (either here on the list, via private email, or on the blog), as I expect > there are ways of thinking about it I hadn't even considered or have > misinterpreted. > > Eric > > > ------------------------------------------------------------------------------ > The NEW KODAK i700 Series Scanners deliver under ANY circumstances! Your > production scanning environment may not be a perfect world - but thanks to > Kodak, there's a perfect scanner to get the job done! With the NEW KODAK > i700 > Series Scanner you'll get full speed at 300 dpi even with all image > processing features enabled. http://p.sf.net/sfu/kodak-com > _______________________________________________ > GDAlgorithms-list mailing list > GDA...@li... > https://lists.sourceforge.net/lists/listinfo/gdalgorithms-list > Archives: > http://sourceforge.net/mailarchive/forum.php?forum_name=gdalgorithms-list > |
|
From: Jon W. <jw...@gm...> - 2009-05-06 18:09:21
|
Ruben Penalva wrote: > In my honest opinion, this is the same with "column major vs row > major". Whatever you choose just stick with it. Make a clear > documentation about your choose and how are you going to convert the > data to your system. Then, forget about it and never ever change the > decision you made. :) Hey, how about "row vector on left" vs "column vector on right" ? Or "WXYZ" vs "XYZW" quaternions? However, it turns out that if you're mainly D3D, you end up with left-handed, row major, row vectors on the left, and if you're mainly OpenGL, you end up with right-handed, column-major, column vectors on the right, and because you flip both the storage and the multiplication convention, the in-memory representation turns out to be the same, which confuses people even more, because they don't even realize that they're mixing and matching code from different conventions, and it "mostly" works anyway. Sincerely, jw |
|
From: Graham H. <gra...@ge...> - 2009-05-06 10:12:54
|
In the best of all possible worlds you would flip a coin and set a universal convention for your whole project. Just check the appropriate box in your authoring application, create your graphics device with a suitable flag and---oh, wait... Since it's clearly "correct" to be agnostic, I prefer to work with the chirality that the graphics driver expects. You may have to apply a transform with negative determinant to your data somewhere---but I would rather do that once and for all time in a pre-process. If you try to cope in your code you will inevitably end up stuck between artists (or---worse---mathematicians) who fervently believe the world is right-handed and a driver which stubbornly assumes it's left-handed. I can guarantee that keeping track of where all the minus signs have to go will hurt your head (been there!). The view matrix is only one of your worries---there are several other operations which are inherently 3D and come with a sign convention built in. The cross-product springs immediately to mind, but the really filthy one is sampling a cube map---there are six faces, each with an orientation, so if you have two different coordinate systems floating around the sheer combinatorial possibilities for screwing this up are pretty daunting... Graham From: Eric Haines [mailto:eri...@gm...] Sent: 06 May 2009 05:10 To: Game Development Algorithms Subject: [Algorithms] Left-handed vs. right-handed I've written up my way of thinking about left-handed and right-handed world and viewing systems. It's a bit long-winded, but here it is: http://www.realtimerendering.com/blog/left-handed-vs-right-handed-viewin g/ This topic is in one sense basic stuff, but it leads to so much confusion. Neither DirectX nor OpenGL does a good job of dealing with this confusion, IMO. In our book we kind of sidestep the whole issue (choose RH, stay RH). I'd love to get any feedback and corrections from people on this list (either here on the list, via private email, or on the blog), as I expect there are ways of thinking about it I hadn't even considered or have misinterpreted. Eric |
|
From: Alen L. <ale...@cr...> - 2009-05-06 11:32:00
|
Graham wrote at 5/6/2009: > Since it’s clearly “correct” to be agnostic, I prefer to work with > the chirality that the graphics driver expects. Which one of the driver multitude of possible drivers and APIs? Even if you are single-platform-single-API and if you adapt everything to "The One API" you use now, few years from now you may have to adapt the same codebase to a different platform/API. I'd bet you are safer sticking to the winding (or chirality, call it all you want) that _you_ prefer, and be prepared to convert signs and windings on every interfacing point with any external API. It's not _that_ much of a hassle, as long as you are clear on what you use internally. JM2C, Alen |
|
From: Graham H. <gra...@ge...> - 2009-05-07 08:17:52
|
I haven't explained myself very well, so let me try to be more specific. In my way of thinking I have to change neither my code nor my data. What I do have to change is the _representation_ of my data. My world has a bunch of vectors and transformations in it. Mathematically speaking, these do not start life with an intrinsic coordinate representation---it's only once you've picked a coordinate frame that you can evaluate basis functions and write down some numbers. It's worth remembering that you've made a choice and done some work here. (The fact that they're called Cartesian coordinates should help you remember that once upon a time this was not a trivial idea.) Unfortunately, computers are good at numbers and bad at abstraction, which means that to do anything useful at all you have to pick a basis before you start. This is a Bad Thing. Typically, picking a basis is the last thing you want to do---ask anyone who's had to write down a bunch of proofs in linear algebra. Now, my contention is that at run-time you want to avoid having to deal with reflections: SO(3) is much nicer than O(3). Given that requirement, the assumptions implicit in whatever driver/API is underneath may make your choice of basis for you. This is fine---just transform the representation of your data and away you go. Everything will still work---clockwise is still clockwise since it's well-defined in your world, independently of the coordinate representation. The key is to make all your own code basis-agnostic. This is easy if you have no preference! Graham -----Original Message----- From: Alen Ladavac [mailto:ale...@cr...] Sent: 06 May 2009 12:32 To: Graham Hazel Cc: Game Development Algorithms Subject: Re: [Algorithms] Left-handed vs. right-handed Graham wrote at 5/6/2009: > Since it's clearly "correct" to be agnostic, I prefer to work with > the chirality that the graphics driver expects. Which one of the driver multitude of possible drivers and APIs? Even if you are single-platform-single-API and if you adapt everything to "The One API" you use now, few years from now you may have to adapt the same codebase to a different platform/API. I'd bet you are safer sticking to the winding (or chirality, call it all you want) that _you_ prefer, and be prepared to convert signs and windings on every interfacing point with any external API. It's not _that_ much of a hassle, as long as you are clear on what you use internally. JM2C, Alen |
|
From: Alen L. <ale...@cr...> - 2009-05-07 12:27:15
|
Graham wrote at 5/7/2009: > Now, my contention is that at run-time you want to avoid having to deal > with reflections: SO(3) is much nicer than O(3). Given that > requirement, the assumptions implicit in whatever driver/API is > underneath may make your choice of basis for you. Erm, wrong requirement. You _want_ to be able to deal with reflections at run time. I mean - its easier for me not to, but the artists need it - so it has to be that way. Stretches that are not multiples of identity and even those involving different signs on different axes are here to stay, for us at least. > The key is to make all your own code basis-agnostic. This is easy if > you have no preference! You can, and should, make majority of your code basis-agnostic. Internals of math, physics, lighting, etc. can be agnostic. But you cannot do it at the points of interfacing with the reality. When the user presses movement stick on the gamepad forward, you have to choose to map it to -Z, +Z, -Y, +Y, whatever... Same way when you want to output something on the screen, you have to know which of the axes in your internal representation is "front", which is "right" etc. and have to adjust your output to match the basis used by the rendering API. Cheers, Alen |
|
From: Graham H. <gra...@ge...> - 2009-05-07 13:55:31
|
Yes, you're right about the reflections: I should have said "you want to avoid dealing with more reflections than you have to". I think the argument still applies---by the time your data is transformed to the run-time representation the only reflections should be the ones the artists have asked for. That way you can detect them and flip the sense of forward and back faces as necessary. This will work independently of the basis representation. I don't understand your other objection though. When the user presses "forward" I just ask my camera class which way forward is :-). Graham -----Original Message----- From: Alen Ladavac [mailto:ale...@cr...] Sent: 07 May 2009 13:27 To: Graham Hazel Cc: Game Development Algorithms Subject: Re: [Algorithms] Left-handed vs. right-handed Graham wrote at 5/7/2009: > Now, my contention is that at run-time you want to avoid having to deal > with reflections: SO(3) is much nicer than O(3). Given that > requirement, the assumptions implicit in whatever driver/API is > underneath may make your choice of basis for you. Erm, wrong requirement. You _want_ to be able to deal with reflections at run time. I mean - its easier for me not to, but the artists need it - so it has to be that way. Stretches that are not multiples of identity and even those involving different signs on different axes are here to stay, for us at least. > The key is to make all your own code basis-agnostic. This is easy if > you have no preference! You can, and should, make majority of your code basis-agnostic. Internals of math, physics, lighting, etc. can be agnostic. But you cannot do it at the points of interfacing with the reality. When the user presses movement stick on the gamepad forward, you have to choose to map it to -Z, +Z, -Y, +Y, whatever... Same way when you want to output something on the screen, you have to know which of the axes in your internal representation is "front", which is "right" etc. and have to adjust your output to match the basis used by the rendering API. Cheers, Alen |
|
From: Alen L. <ale...@cr...> - 2009-05-07 13:52:45
|
Graham wrote at 5/7/2009: > I don't understand your other objection though. When the user presses > "forward" I just ask my camera class which way forward is :-). Then it's the camera. But some piece of code, or content has to know it. Granted, you can make things like "which way is front", "which way is up" and "which way is north" configurable in the game's tools and you can make games with different basis. But it is the same thing. Whether you fix a basis in the code, or the artists determine it in the tools (once for each game), you still have to decide on one, right? Alen |
|
From: Graham H. <gra...@ge...> - 2009-05-07 14:31:48
|
The fundamental truth is that for boring technical reasons certain drivers/APIs make it more convenient to use certain basis representations. So yes, at some point some competent person has to specify which basis to use for each target platform. This information can live in an exporter script, or in asset processing code somewhere. Of course there are a few gory details in the asset conversion itself that I'm conveniently glossing over, but morally that's the whole extent of how much you have to care. Compare this to your original suggestion: > Which one of the driver multitude of possible drivers and APIs? Even if you are single-platform-single-API and if you > adapt everything to "The One API" you use now, few years from now you may have to adapt the same codebase to a different > platform/API. I'd bet you are safer sticking to the winding (or chirality, call it all you want) that _you_ prefer, and be > prepared to convert signs and windings on every interfacing point with any external API. It's not _that_ much of a hassle, > as long as you are clear on what you use internally. YMMV, but for me that is a lot of unnecessary hassle. Graham -----Original Message----- From: Alen Ladavac [mailto:ale...@cr...] Sent: 07 May 2009 14:46 To: Graham Hazel Cc: Game Development Algorithms Subject: Re: [Algorithms] Left-handed vs. right-handed Graham wrote at 5/7/2009: > I don't understand your other objection though. When the user presses > "forward" I just ask my camera class which way forward is :-). Then it's the camera. But some piece of code, or content has to know it. Granted, you can make things like "which way is front", "which way is up" and "which way is north" configurable in the game's tools and you can make games with different basis. But it is the same thing. Whether you fix a basis in the code, or the artists determine it in the tools (once for each game), you still have to decide on one, right? Alen |
|
From: Eric H. <eri...@gm...> - 2009-05-07 15:37:50
|
Thanks for all the replies. Yes, I should mention something about loop reversal (I was tempted to in the original post, but it was getting quite long as it was). I'm planning to try to unify some camera parameters in our own system, so thanks, Patryck, for the pointer to the Eberly document http://www.geometrictools.com/Documentation/LeftHandedToRightHanded.pdf. On Thu, May 7, 2009 at 10:31 AM, Graham Hazel <gra...@ge...> wrote: > The fundamental truth is that for boring technical reasons certain > drivers/APIs make it more convenient to use certain basis > representations. So yes, at some point some competent person has to > specify which basis to use for each target platform. I guess I'd like to know more about the boring details that make it more convenient to go with one basis or another - we don't have to clutter the list with this (it's not truly algorithmic), but I'd be interested if you'd be willing to email me. Do you just mean the built-in calls like glFrustum? Or something else? I did find this in Jeff Weeks' documentation, which mentions one old fixed-function lighting feature of OpenGL that forces -Z to be used. I thought I'd include the note here in full, as it's relevant. --------------------- Appendix: My two programming idiosyncracies. --------------------- OpenGL Conventions For the most part OpenGL's conventions are simple and elegant. However, my conventions differ from OpenGL's in two major ways. Matrices (... column-major discussion deleted...) Coordinate Systems OpenGL orients projection space with the observer looking down the positive z-axis, with with x-axis pointing to the right and the y-axis pointing up. However, OpenGL forces no assumptions about the orientation of world space; the programmer is free to choose his/her coordinate system and projection matrix however s/he wishes. So far so good. The only complication is that the OpenGL documentation adopts the unfortunate convention of looking down the negative z-axis, and requiring that the projection matrix invert the z-axis when passing from world to projection space. The motivation for this convention, as far as I can tell, was to use a right-handed coordinate system ("like mathematicians use") in world space. (Computer scientists seem to have suffered from a bit of an inferiority complex back in the early days, or at least needed to convince people that their work was intellectually rigorous.) Fortunately the negative z-axis convention appears only in the documentation and in certain helper functions like glFrustum(), but otherwise is not forced on us. [One other exception is that when you turn off GL_LIGHT_MODEL_LOCAL_VIEWER, OpenGL assumes the viewer is looking from infinity down the negative z-axis, and there seems to be no way to change that assumption.] Within this program, we adopt the convention that the x-axis points to the right the y-axis points up the z-axis points forward in world space as well as projection space. Eric |