Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basis Textures Load Flipped on the Y Axis #18

Closed
sybixsus opened this issue Oct 15, 2020 · 7 comments · Fixed by #20
Closed

Basis Textures Load Flipped on the Y Axis #18

sybixsus opened this issue Oct 15, 2020 · 7 comments · Fixed by #20
Assignees
Labels
bug Something isn't working question Further information is requested

Comments

@sybixsus
Copy link

All of my Basis textures come in flipped on the Y-axis. I've tested unpacking them with the BasisU executable and they are definitely being created correctly.

In order to test, I created a new project in Unity 2019. I created a screen space canvas and added a UIImage that fills the entire screen. Then I assign my test image (sprite) to the UI image. (See image 1 with the png texture correctly applied.)

BasisFlip1

Then I create a simple class and apply it to the GameObject with the Image component on it.

`public class LoadTexture : TextureFileLoader
{

protected override void ApplyTexture(Texture2D T)
{
    GetComponent<Image>().sprite = Sprite.Create(T, new Rect(Vector2.zero, new Vector2(T.width, T.height)), Vector2.zero);
}

}`

I put the basis file in Streaming assets, of course, and I set the file path in the inspector. I hit play and I get the correct image, upside down. (See image 2 with the same texture upside down.)

BasisFlip2

I've tested it across various platforms, inside and outside of the editor and it's always the same. I've also tested loading the texture manually :

`/*
private void Awake()
{
BasisUniversalTexture T = new BasisUniversalTexture();
T.LoadFromStreamingAssets("Shadow.basis", this);
T.onTextureLoaded += TextureLoaded;
}

protected void TextureLoaded(Texture2D T)
{
    Debug.LogError("Texture Loaded::" + T.width + "," + T.height + "," + T.format);
    GetComponent<Image>().sprite = Sprite.Create(T, new Rect(Vector2.zero, new Vector2(T.width, T.height)), Vector2.zero);
}
*/`

Again, in all instances, the texture is flipped on the Y-axis.

I've uploaded my test project folder (using Unity 2019.3.11f1) in case you find that useful.

https://drive.google.com/file/d/1Gp8Obz_x6ANkGnCWyNUirjI6amVU8X7w/view?usp=sharing

Note: I'm only using Basis textures so I can't say if this affects all texture or just Basis textures.

Let me know if there's anything else you need to reproduce and fix this problem.

@DerrickBarra
Copy link

@sybixsus I was planning on reporting the same bug today, good to see others can reproduce this issue.

@atteneder For my tests, I'm using .basis textures created with basisu.exe with default settings (although the same bug occurs on all .basis textures, including the examples used by this repo).

Here are some good test images that show the problem off.
mario_transparent.jpg - The original file
mario_transparent.basis - The file generated by basisu

If I open mario_transparent.basis in the WebGL testing page that's part of the BinomialLLC/basis_universal repo by downloading the repo, then hosting the WebGL folder using Servez, we can use their web viewer to see the mario_transparent.basis file as it's supposed to be.

image

And in Unity, if I load a .basis using KtxUnity onto a 2D Image renderer on a Canvas, this is what I see.

image

Note: My KTXDemo.cs component is just loading the .basis bytes via a WebRequest and then passing the NativeArray to your plugin, like in the examples and what @sybixsus mentioned earlier.

@atteneder
Copy link
Owner

Thanks a lot for reporting!

I could reproduce the issue! I'm not sure where the error is introduced (maybe Unity's Texture API), or how/if I can resolve it. I'll investigate more on it later this week.

A workaround would be to counter-act the orientation in the Sprite:

protected override void ApplyTexture(Texture2D T)
    {
        GetComponent<Image>().sprite = Sprite.Create(T, new Rect(new Vector2(0,1), new Vector2(T.width, -T.height)), Vector2.zero);
    }

@atteneder atteneder self-assigned this Oct 19, 2020
@atteneder atteneder added bug Something isn't working question Further information is requested labels Oct 19, 2020
@atteneder
Copy link
Owner

This issue seems to confirm the suspicion that Unity has a certain definition of the y-axis reference point and it's not changable at runtime. See:

https://issuetracker.unity3d.com/issues/loadrawtexturedata-loads-dds-textures-upside-down

Also quotes from a Blender issue:

OpenGL and DirectX/DDS have different conventions for UV mapping, putting 0,0 at the bottom and top left respectively. Blender uses the OpenGL convention and converts accordingly, as it does for many image file formats.

further:

According to our code, Blender does make the required vertical flip, while it seems Unity does not

So that means you'd have to encode your basis files with the -y_flip option for Unity.

That's a bummer, because I thought KTX/basis would be truly platform/gameengine/middleware independent.

Still needs more confirmation/investigation.

@sybixsus
Copy link
Author

I knew that OpenGL and DX used different world/object coordinate systems (left/right handed) but I was not aware that the UV coordinates were also different between OpenGL and DX.

That does make a lot of sense though. And it would explain why the BasisU.exe comes with an option to flip on the y-axis. In point of fact, I'm already using the -y_flip option as a workaround for my development so it's no hardship for me if this is the ultimate answer.

Thanks for looking into it!

@atteneder
Copy link
Owner

No problem.

The remaining question is:

Can KtxUnity provide a consistent orientation (in-data), regardless of the -y_flip option or is it up to its user to handle that?

My current understanding is that it can't and KtxUnity has to expose the y_flip flag (or the KTXorientation for ktx files) so that the user can properly alter UVs/texture scale/Sprite coordinates to compensate for it.

Once I'm certain, I'll comment and close this issue.

Thanks!

@atteneder
Copy link
Owner

Further information on this topic:

PR about a transcode time y-flip in BasisU ETC1S
issue about a transcode time y-flip in BasisU UASTC

Seems that it's possible, but not implemented atm.

atteneder added a commit that referenced this issue Oct 21, 2020
…t (=flip) them (fixes #18)

change: Unsupported basis file texture types (non 2D Images) raise a proper error now
change: Updated KTX-Software (native libs) to 4.0.0 beta 4 (now based on KTX-Software-Unity build project; binaries to be commited!)
change: Removed support for 32-bit Desktop platforms (Windows, Linux)
@atteneder atteneder mentioned this issue Oct 23, 2020
@atteneder
Copy link
Owner

TLDR:
With version 0.8.0 textures will still be flipped, but you get the orientation and can counter-act reliably now.

Read the updated README on the projects page for details.

Hope that helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working question Further information is requested
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants