godotengine / godotengine/godot
Shading issue with normal maps on a Sprite2D in a ParallaxLayer with 2D Lighting
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
- Reproducible in: 4.2.1.stable
### System information
Windows 10 - Godot v4.2.1.stable - Vulkan (Mobile, Forward+ and Compatibility) - Nvidia RTX3080 & GTX 1070ti
### Issue description
When using normal maps on a Sprite2D in a ParallaxLayer with mirroring, the normals aren't behaving as they should when lit by a PointLight2D, getting worse with lower values of the Height property, and better with higher ones, though with flatter shading. Duplicating the Sprite2D manually does not produce the same effect, and the shading is seamless. Additionally, the normals seem to "pop" when moving the camera across the seam.
Has been reproduced in a new project, and on multiple machines with different hardware.

### Steps to reproduce
In the attached project, adjust the Height of the PointLight2D to see the issue.
ParallaxBackground
- ParallaxLayer
-- Sprite2D
PointLight2D
ParallaxLayer Mirroring set to 2048x2048
Sprite2D: Texture > new canvas texture, add diffuse and normal maps
PointLight2D: Set texture to a radial 2D gradient, set Layer Min to -100, scale to cover borders between the duplicated sprites, adjust height to see the issue
### Minimal reproduction project (MRP)
[ParallaxLighting.zip](https://github.com/godotengine/godot/files/14037694/ParallaxLighting.zip)
Contributor guide
Research direction
Start by opening the attached ParallaxLighting.zip project and reproducing the shading changes while adjusting PointLight2D Height. Trace the ParallaxBackground, ParallaxLayer mirroring, Sprite2D normal map, and PointLight2D interaction; done means mirrored sprites have consistent lighting without normals popping at the seam.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, godot
- Domain
- computer-graphics, game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100