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

Unable to retrieve normal map from CanvasTexture atlas in TileSet/TileMap #61832

Closed
MyStarrySpace opened this issue Jun 8, 2022 · 6 comments · Fixed by #83489
Closed

Unable to retrieve normal map from CanvasTexture atlas in TileSet/TileMap #61832

MyStarrySpace opened this issue Jun 8, 2022 · 6 comments · Fixed by #83489
Assignees
Milestone

Comments

@MyStarrySpace
Copy link

Godot version

4.0.dev (alpha 9)

System information

Windows 11 Pro version 10.0.22000 Build 22000, NVIDIA GeForce RTX 2060, Game Ready Driver v511.79, Vulkan

Issue description

Using a CanvasTexture with a diffuse and normal map attached will only render tiles with the diffuse map, but will not add normals to the tiles. There is seemingly no way in Godot 4.0 to use normal maps with TileSets. When tiles are pulled from the atlas to draw the tiles, normal map data should also be retrieved and added. When a user configures an atlas texture with a CanvasTexture and the TileSet is drawn, during the draw step, information about the normals can be drawn and used. Adding normals to tilesets in 3.x was possible, but there is seemingly no way in 4.0.

Steps to reproduce

  1. Create TileMap
  2. Create TileSet
  3. Create a tile atlas for the TileSet
  4. Set the atlas texture to a new CanvasTexture
  5. Add a diffuse map to the CanvasTexture
  6. Add a normal map to the CanvasTexture
  7. Draw some tiles onto the TileMap
  8. Add a Light2D
  9. Watch disappointedly as the light illuminates the tiles indiscriminately with maximum intensity

Minimal reproduction project

No response

@Chaosus Chaosus added this to the 4.0 milestone Jun 10, 2022
@calebmhartshorn
Copy link

calebmhartshorn commented Sep 24, 2022

I've been trying to work on this issue as it's blocking progress on my game (my first time, so slightly overwhelmed), and I noticed that shader's NORMAL and NORMAL_TEXTURE aren't working on a TileMap either, preventing easy workarounds.

Sprite2D is working as expected, and digging into the code, they both call Texture2D::draw_rect_region() on Ref<Texture2D>. The only notable thing I've noticed in TileMap different from Sprite2D is that it seems to be creating lots of different CanvasItems, instead of just the one like Sprite2D.

I wonder if it's a bug with CanvasItem? Normals seem to stop working similarly in a CanvasGroup.

Clearly don't know the code very well, so any insight would be appreciated.

@calebmhartshorn
Copy link

In the meantime, I've found a hacky workaround using a Sprite2D with a CanvasTexture and SubViewports works as expected.

image

Somewhat frustrating, but it works.

@MyStarrySpace
Copy link
Author

MyStarrySpace commented Sep 29, 2022

In the meantime, I've found a hacky workaround using a Sprite2D with a CanvasTexture and SubViewports works as expected.

image

Somewhat frustrating, but it works.

How did you manage to get the contents of the SubViewport to display in the sprite? I can't make Viewport textures as maps for the canvas texture because they are not local to the scene. Do the viewports need any special settings?

This is a much better workaround than what I've currently been doing, which is to copy the normals and diffuse onto a sprite, then give a sprite a canvasitem shader set to premultiplied Alpha blending mode with Light Only on top of the tileset.

@calebmhartshorn
Copy link

Yes, the local to scene property is in the resources group of the CanvasTexture.
image

Couple caveats with this whole approach:

  • You need two copies of your tileset. One with diffuse textures and one with normal textures (plus specular if you want it).
  • With every change you make to one TileMap, you need to copy paste to the other to avoid lighting artifacts.
  • There's a few bugs with SubViewports at the moment. If you get glitchy or missing textures, try changing the SubViewport size to something other than the defualt, set their Render Target Update Mode to always, and/or just reopen the project.

Here's an example project I made for you this morning, in case you get stuck:

NormalTilemaps.zip

Due to the issues mentioned above, I would strongly recommend writing a script to automatically replace your TileMap with this setup at runtime.

@mrcdk
Copy link
Contributor

mrcdk commented Oct 30, 2022

Looks like the issue comes from enabling Use texture padding under the atlas properties of the tileset which creates a new ImageTexture from whatever source texture has been assigned. (https://github.com/godotengine/godot/blob/master/scene/resources/tile_set.cpp#L4587) Disabling that property fixes the issue.

Godot_v4 0-beta3_win64_8GYsOHx8jn

EDIT: I'm using v4.0.beta3.official [01ae26d]

@groud
Copy link
Member

groud commented Nov 2, 2022

Looks like the issue comes from enabling Use texture padding under the atlas properties of the tileset which creates a new ImageTexture from whatever source texture has been assigned. (master/scene/resources/tile_set.cpp#L4587) Disabling that property fixes the issue.

Oh right, that makes a lot of sense! Support for CanvasTexture then has to be added to the texture padding feature.

@akien-mga akien-mga modified the milestones: 4.0, 4.x Feb 22, 2023
@akien-mga akien-mga changed the title [Godot 4.0] - Unable to retrieve normal map from CanvasTexture atlas in TileSet/TileMap Unable to retrieve normal map from CanvasTexture atlas in TileSet/TileMap Feb 22, 2023
@akien-mga akien-mga modified the milestones: 4.x, 4.2 Oct 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment