Replies: 12 comments 12 replies
-
Proposal: Z-Up for 3DTo quote the arguments made by @Keavon on Discord:
|
Beta Was this translation helpful? Give feedback.
-
Proposal: Camera facing down in 2D (if using Z-Up for 3D)If we switch to using Z-Up in 3D, but still want to use the same coordinate system in 2D and 3D, then the camera would have to be rotated to look downwards at the XY plane. This adds an additional requirement onto the camera transform. This further adds to the issue/pitfall mentioned in the OP -- with requiring users to know how to correctly orient/position the camera, if overriding the default transform. |
Beta Was this translation helpful? Give feedback.
-
Proposal: Using different coordinate systems for 2D (Y-up) and 3D (Z-up)This could allow the default configuration to be intuitive to work with, in each respective domain. However, it also means that the coordinate systems are inconsistent, and it further separates 2D and 3D logic and rendering. |
Beta Was this translation helpful? Give feedback.
-
Proposal: Using Y-down in UI and Y-up in 2DBreak the consistency between UI and 2D, to make working with UI match common intuition from other UI toolkits and layout systems. |
Beta Was this translation helpful? Give feedback.
-
Proposal: Make coordinate systems easily configurableThis would let users pick whatever they like / whatever works well for their application. The drawbacks include:
|
Beta Was this translation helpful? Give feedback.
-
Assertion: There is no truly intuitive coordinate systemInstead, there's only "what someone is already used to". The might be Y-up from using OpenGL. That might be left-handed from DirectX. That might be Y-down from UIs. Etc. But they all work, and anyone importing models from different places may well need to deal with the mismatch no matter what Bevy uses. |
Beta Was this translation helpful? Give feedback.
-
Voting for "right hand" and Z upi personally never understood why the "industry" stick to that 2 "systems", although i know why they there (historically). i dont like the terms left/right hand. it has effects even down into for example culling (triangle culling clockwise/counter clock) the second property often used is: what axis points up, but its the thing that i think is most confusing, because in my mindset z is up! I asked some people (who where not yet polluted by existings (programmesrs,artists...) ) how they would do the coordinates. but this doesnt work well with 2d, i also think 3d should be 2d + Z-axis thats why i vote for "right hand" and Z up and let the "identity"-rotation look along the positive y axis.
could be?: |
Beta Was this translation helpful? Give feedback.
-
As a game engine, Y-up + "left hand" is the best. |
Beta Was this translation helpful? Give feedback.
-
+1 for rh Z-up I've always thought 3D as "first two describe floor position and the last one describes height". The floor coordinates are similar so should go next to each other while the height is more special (humans move on the floor more easily than vertically). I think code tends to be nicer with rh Z-up. Also I don't think using g the argument: "3D should be 2D + 3rd axis" doesn't work for a few reasons:
|
Beta Was this translation helpful? Give feedback.
-
I want to give my insights with using the current system for 2d top-down games. To start off, the current system is not great because using z for layering is not intuitive and makes a lot of problems. To name problems I encountered: y-ordering of sprites is a common need for top down games. Currently, this is only possible by updating the z component constantly. If you would want to introduce layergroups, such as a background and foreground layer, the current system would become even more troublesome. I also noticed that the current system plays badly with other crates that rely on the transform component. I'm not really sure how exactly a solution would look like but I'd love to get rid of the z for layering. struct Layer {
layer_group: u8,
layer: f32
} |
Beta Was this translation helpful? Give feedback.
-
Vote for Y as up-down axis, because Y on the screen looks like an arrow pointing downwards and because it does not matter in the end, and whatever it is changed will piss people off: so why not just let it go as it is then? |
Beta Was this translation helpful? Give feedback.
-
I am in agreement with the fact that the coordinate system should be configurable by the user. There is no "best" coordinate representation globally, but there is a "best" coordinate representation for the task at hand. Maybe I can give some background in my experience on how coordinate spaces are handled. 1. You define only Left Hand/Right Hand and an Up Vector (or inversely gravity vector)
2. You define Left/Right Hand and an Up AND Forward Vector
Just for clarity, I want to provide some context on cameras and how to potentially implement custom coordinate spaces on bevy side with the least amount of friction possible. Traditionally, we have the 4 spaces:
Now there are two (common) approaches to get to Camera Space.Camera Local space is tied to your Renderer ImplementationThe first, is the technique Blender & GLTF uses (and others). In these programs world coordinate spaces, the cameras are defined with a local transform (Object space) different than that of their world space, in this case OpenGL convention where cameras look down (forward vector) is To further clarify this point, if you add in an "Identity" camera in Blender, it will point "straight down". This is because the local convention of the camera is to look down -Z, and world up is +Z. Then, to get to camera space, you perform:
In this case, the view matrix is simply the inverse of the cameras world matrix. The math is simple. If we look at the blender image as an example, we can say that blender is -Y Forwards, +X Left, +Z Up.
However, look at the image above! The camera in blender is at the identity, and it looks down If we wanted to support a user-provided world space coordinate system, we would need to apply a change of basis to the view matrix on the left hand side, such that the camera is "framed correctly" in our custom system. The math for this isn't difficult per-say, but perhaps not as intuitive. The second approach also must do this, but the change of basis you provide is different.
Camera Local space is tied to your World SpaceThis is a technique where your camera local space is exactly the same as your world system coordinate conventions. If Blender was theoretically in this mode, then your camera at the identity would look like this: The ergonomics of this make a bit more sense for 3D programming - the coordinate system of your world and the coordinate system of your camera match. It means that for generic transform code, the transform of your camera and the transform of your models have the same symbolic meaning when it comes to forward vector. If you look at the image above, the identity matrix of the camera, and the identity matrix of the model both have them "looking" the same direction. The camera space math then looks like this:
Ignoring custom world spaces for a second, you may see that there is now always a change of basis matrix, where the previous method did not! That is because our cameras are defined in our world space, not the renderers. Before we give it to the renderer, we must put it into the space it understands! However, with a custom coordinate space, you would only have to be concerned with changing that single change of basis, not caring about the world space convention used by Bevy/User code. As an example, according to https://bevy-cheatbook.github.io/fundamentals/coords.html, Bevy uses This means that bevy's world space is the exact same as renderer space, so identity transform! Thus, the change of basis matrix for bevy's current coordinate system would be the identity.
However, let's say you wanted to use a more mathematical/ISO defintion of world space, such that your up vector is
Then, to convert from our world space convention to renderer convention, our change of basis from
How would I do this in Bevy?IIRC I believe Bevy is currently both Thus, I think the cleanest solution would be something along the lines of removing directional getters in Introducing a The Using this resource when computing the |
Beta Was this translation helpful? Give feedback.
-
I am creating this post, to have a consolidated place for any discussion about the tradeoffs/merits/drawbacks regarding different coordinate systems, and what would be best to use in Bevy by default. There have been many scattered discussions about this on Discord, so we clearly need a better place to keep this information.
Status Quo (Bevy 0.5)
(explanation in Bevy Cheatbook)
Currently, Bevy uses a Right-Handed Y-Up coordinate system in all domains: 2d, 3d, UI.
This makes the coordinate system identical/consistent everywhere (for better or for worse).
One upside to this is that the implementations of 2D and UI things can converge / be very similar. They can have the same assumptions, the same rendering, the same camera configuration. One downside is that it can make things non-intuitive and confusing to work with.
When working with UI
This leads to the common confusion/pitfall: that the Y/vertical axis is inverted -- it behaves opposite to common intuition, other toolkits, and the flexbox model (as it behaves in web browsers, where it originates).
When working with 2D
This allows layers to be represented as positive +Z coordinates, with the background at 0. All of the axes behave intuitively.
However, an issue with the current implementation (IDK how much that is directly dependent on the coordinate system per se, but it needs to be addressed) is that the camera needs to be placed far away. The default bundle constructor creates a Transform with Z=9999, close to the clipping plane. It is a common pitfall -- if users override the default transform and don't know that this is necessary.
When working with 3D
The coordinate system matches 2D. This could work well, for example, in side-scrolling platform games that imitate 2D gameplay but use 3D graphics.
However: it is less intuitive for other applications, is inconsistent with important open-source software like Blender, and is different from the typical 3D conventions in other domains (CAD, architecture, mathematics).
Alternative Proposals
To keep the discussion organized/structured, I will create "answer" posts to this thread, for each aspect of the discussion. This should allow people to respond in comments to those sub-posts and make everything less chaotic.
Note that, while Bevy does not provide an API to easily change the default coordinate system, it is possible (and seems to work OK) to use other coordinate systems, by creating a camera with a custom projection.
Beta Was this translation helpful? Give feedback.
All reactions