Conversation
|
|
||
| ### OpenGL (The Bottom-Left API) | ||
|
|
||
| OpenGL is unique because its texture coordinate system origin \\((0, 0)\\) is at the **bottom-left**. |
There was a problem hiding this comment.
that's not "unique". That's actually typically how we learn math in school. Usually when you have a piece of paper, you naturally put the origin at the bottom left.
There was a problem hiding this comment.
removed and rephrased.
|
|
||
| OpenGL is unique because its texture coordinate system origin \\((0, 0)\\) is at the **bottom-left**. | ||
|
|
||
| - **Texture Upload:** To ensure texture sampling works "normally" (where $v=0$ is the top), images are typically flipped during upload. This results in the texture being stored **upside-down** in GPU memory. |
There was a problem hiding this comment.
No I think this is confusing.
Images are not technically "flipped", it's just that the opengl spec defines glTexImage2D's data pointer to be ordered with the bottom of the image at the low addresses.
This is contrary to how images are typically stored on a computer. So, yes, you have to "flip" your "Typical" bitmap if you use glTexImage2D and you want the bottom of the image to be at v=0.
We don't know how the image is stored in the GPU's memory (because in GL you can't read that buffer), so it's no correc to say that it's stored "upside down".
There was a problem hiding this comment.
Note that from a user's point of view, GL, VK and Metal are consistent.
i.e. if you do a glTexImage2D without inverting the texture, in all cases you end-up with the origin at the top of the image. No changes needed in the shader. it's just that "conceptually* in GL the image is "upside down" (whatever that means) and the y axis goes "up" (whatever that means). Whereas is Metal/VK the image is right side up, and the y-axis goes down.
So... unintuitively, you do not have to do anything special to have your textures uploads and texture coords work on all platforms.
The problem only arises with render targets and is compounded when you upload data into a texture (as opposed to drawing into it) and use it as an attachment and readpixels from it.
There was a problem hiding this comment.
I say "whatever that means" because the definition of "up" is the direction of the Y-axis.
| OpenGL is unique because its texture coordinate system origin \\((0, 0)\\) is at the **bottom-left**. | ||
|
|
||
| - **Texture Upload:** To ensure texture sampling works "normally" (where $v=0$ is the top), images are typically flipped during upload. This results in the texture being stored **upside-down** in GPU memory. | ||
| - **Standard `glReadPixels`:** Because OpenGL reads from the bottom-left, a standard `glReadPixels` call effectively flips the data back, resulting in an **upright** image in the CPU buffer. |
There was a problem hiding this comment.
Another way to say it is the glReadPIxel is consistent with glTexImage2D.
Neither operation is flipping the image you give it.
glReadPixel just transfers line 0, 1, 2... (with 0 at the bottom of the screen) in order.
Note that typically you don't do a glTexImage2D, then bind the texture as an attachment and then do a readPixels().
This exact combination of operation is inconsistant in Filament (because filament actually flips the result of readPixels in GL). This was a compromise we had to do, to be compatible with other APIs.
|
|
||
| - **Texture Upload:** To ensure texture sampling works "normally" (where $v=0$ is the top), images are typically flipped during upload. This results in the texture being stored **upside-down** in GPU memory. | ||
| - **Standard `glReadPixels`:** Because OpenGL reads from the bottom-left, a standard `glReadPixels` call effectively flips the data back, resulting in an **upright** image in the CPU buffer. | ||
| - **Filament's Handling:** To maintain consistency or specific internal alignment, the Filament OpenGL backend performs an additional **CPU flip** after the read. This results in a final buffer where the image is **upside-down** relative to the original source. |
There was a problem hiding this comment.
The reason for this is so that given a framebuffer (e.g. you draw a triangle into it), and you do a readpixels, the result is the same on all APIs. (with the "Typical" bitmap layout, low address are the top of the image).
This however "breaks" the consistency of uploading data into a texture and then reading it back with readPixel with the texture as an attachment. This is actually the only situation in which filament doesn't work the same across all backends!
| Metal, Vulkan, and WebGPU use a \\((0, 0)\\) **top-left** coordinate system, which aligns more closely with standard image memory layouts. | ||
|
|
||
| - **Texture Upload:** No flip is required. The image is stored in GPU memory in its **upright** orientation. | ||
| - **Filament `ReadPixels`:** The data is read directly. Since the GPU storage and the memory layout both favor top-left, the resulting CPU buffer is **upright**. |
There was a problem hiding this comment.
yes, however all these APIs are inconsistent imho. Because their clip-space puts the origin at the bottom left! so in these APIs the clip space is "inverted".
And remove the pngs that documented the same thing.
0985c4c to
bb73db2
Compare
No description provided.