godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
91.14k stars 21.19k forks source link

Polygon2D normals ignore bone transformation #79043

Open Xorblax opened 1 year ago

Xorblax commented 1 year ago

Godot version

v4.0.3.stable.official [5222a99f5]

System information

Windows 10

Issue description

The normals for a polygon2D do not update when the polygon is transformed using bones. This causes 2D lighting to shade incorrectly. This only happens when using bones, as rotating a polygon2D's own transform, when it is not synced to bones, will update the normals correctly. My main desire for this is so that I can use the deformation feature of bones with normal shading. I think that this is possible, as each individual polygon in the polygon2D has its own transform information I assume it could send to the shader.

Steps to reproduce

Create a polygon2D, add a canvas texture that has a texture and a corresponding normal map, sync the polygon2D to a skeleton, and then add a directional light source. Transform the bones on the skeleton. The texture will move and deform correctly but the normals will act as if there was no transformation. Polygon2D before transformation: image Rotated using bones: image Rotated by itself, without any bone syncing: image

Minimal reproduction project

Rotate the polygon, and the shading correctly updates. Rotate the bones, and the shading does not update. polygon_normal_bug.zip

Calinou commented 1 year ago

@Xorblax Please upload a minimal reproduction project to make this easier to troubleshoot.

Xorblax commented 1 year ago

@Xorblax Please upload a minimal reproduction project to make this easier to troubleshoot.

Done

clayjohn commented 1 year ago

This is a tough one. I'm not totally sure whether it can be classified as a bug or not. In 2D, normals are a texture property and they are read from a texture. So when you move the bones in your skeleton, the normal map is deformed the same way that the texture is. In other words, they both follow the uvs of the underlying mesh and rotate and deform properly.

The issue is that the normal map is assumed to be in world space. When you rotate the entire Polygon, we can correct by using the polygon's transform to align the normal into the proper space. But when you modify the vertices of the polygon with a bone, we have no access to the new final transform. So we can't rotate the individual normals

Xorblax commented 1 year ago

I had thought there would be a way to get the individual triangle transform from within the polygons. I imagined it similar to however its done in 3D, where I know mesh deformation would still shade correctly. Not my area of expertise, thanks for adding the suggestion tag.