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

Transparent textures are not sorting correctly #53974

Closed
acatxnamedvirtue opened this issue Oct 18, 2021 · 6 comments
Closed

Transparent textures are not sorting correctly #53974

acatxnamedvirtue opened this issue Oct 18, 2021 · 6 comments

Comments

@acatxnamedvirtue
Copy link

Godot version

3.3.4

System information

Windows 10, GLES3, NVIDIA GeForce RTX 2060, 30.0.14.7168

Issue description

Hello!

I am working on a prototype that uses 2D pixel art tiles applied to simple square meshes in 3D gridmaps. Everything was working very well until I tried upgrading Godot from 3.3.2 to 3.3.3 or 3.3.4

I noticed that 3.3.3 included two PRs, which I have confirmed are causing my issue. On the 3.x branch, I manually reverted those two changes, compiled Godot, and tested my project, and no longer experienced the issue.

#50721
#43506

Since I am using pixel art, transparency is pretty important (especially in sprites, but also in the tiles themselves).

I know that those two PRs above are positioned as fixes themselves, so I am unsure if I was just relying on Godot incorrectly sorting my sprites/tiles, but the way Godot sorted my sprites/meshes in 3.3.2 seems to me to be correct.

Sorting in 3.3.2:
image

Sorting in 3.3.3+:
image

I have also noticed the same sorting issues when I compile Godot 4 (master branch) from source. If I have to stay on 3.3.2, I guess I could, but I was really hoping to start taking advantage of the incredible TIleMap editor improvements.

Please let me know if you have any questions!

Thanks!

Steps to reproduce

  1. Open project in Godot 3.3.2

  2. Move around in the 3D editor or play the scene, and notice that the "Player" (Godot icon) is correctly drawn in front of cliffs.

  3. Open project in Godot 3.3.3

  4. Move around in the 3D editor or play the scene, and notice that the "Player" (Godot icon) is drawn behind cliffs when they should be drawn in front of them.

Minimal reproduction project

godot-transparency-sort-bug.zip

@Calinou
Copy link
Member

Calinou commented Oct 18, 2021

See also #50794.

Make sure to use alpha testing (alpha scissor) instead of alpha blending on the SpatialMaterial when you only need 1-bit transparency. This eliminates most sorting issues.

@clayjohn
Copy link
Member

I took a look at the example project and I think I have figured out what is going on. Unfortunately, it doesn't look like a bug.

Godot uses AABBs to sort transparent objects and determine what order they should be drawn in. AABBs are created from the source mesh. The corner tiles in your tilemap are using a vertex shader to manually offset the vertex positions so they are not captured by the AABB.

Notice in the below photo h
Screenshot (32)
ow the AABB (the orange square) appears in front of the sprite while the actual mesh appears behind it?

Now notice the scene viewed from the front. You can see that the renderer incorrectly thinks the tile is in front of the sprite.
Screenshot (33)

Previously, you didn't notice this because the old (buggy) behaviour resulted in objects drawing in an arbitrary order based on their position relative to the DirectionalLight in the scene. Once your project became more complex, you would likely have run into #50721.

The solution to this issue is to create a mesh to use for your corner tiles instead of relying on offsetting the tile in the vertex shader. This will provide Godot with the correct AABB so the tiles will sort properly.

I have not used the GridMap node extensively, but I think you can even create a gridmap tile using a rotated QuadMesh.

@acatxnamedvirtue
Copy link
Author

@clayjohn Oh, that makes a lot of sense, thank you so much for walking through that! I'll see if I can play around in blender and make some new meshes and apply the textures to them.

I'll also see if I can switch over to using alpha scissor as @Calinou suggested for cases where pixels are either fully transparent or fully opaque.

Just so I fully understand it, would partially transparent pixels in meshes still potentially have sorting problems?

Thank you both for your time and assistance!

@Calinou
Copy link
Member

Calinou commented Oct 19, 2021

Just so I fully understand it, would partially transparent pixels in meshes still potentially have sorting problems?

Yes. The only way to combat this is to use the Render Priority property in the Material, or rely on dithering to simulate partial transparency while still using an alpha-scissor material.

@acatxnamedvirtue
Copy link
Author

acatxnamedvirtue commented Oct 19, 2021

Hi again! I spent some time in Blender and created the appropriate mesh shapes.

I'm really pleased with the results!! Not using the shader approach also allows me to simplify my scene tree and code a bit, plus 3D shadows/lighting works perfectly.

Would you like me to close this issue?

Thanks again!

@Calinou
Copy link
Member

Calinou commented Oct 19, 2021

Would you like me to close this issue?

Indeed, I consider this resolved as best as we can in a real-time 3D rendering engine. (Order-independent transparency is a thing, but it's expensive and not something you want to use in a game with a pixel art aesthetic.)

@Calinou Calinou closed this as completed Oct 19, 2021
@Calinou Calinou removed this from the 3.3 milestone Oct 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants