godotengine / godotengine/godot
Meshes with a negative scale have incorrect normals when using `cull_disabled` and `cull_front` render modes
- Dominant language
- C++
- Stars
- 117k
- Forks
- 26.8k
- PR merge metrics
- PR metrics pending
Description
### Tested versions
- Reproducible in 4.1, 4.2.1, 4.3-beta 2, using the forward+ renderer.
- Haven't tested other builds
### System information
Godot v4.2.2.stable - Arch Linux #1 SMP PREEMPT_DYNAMIC Fri, 21 Jun 2024 19:49:19 +0000 - Wayland - Vulkan (Forward+) - dedicated AMD Radeon RX 6950 XT (RADV NAVI21) () - AMD Ryzen 7 3700X 8-Core Processor (16 Threads)
### Issue description
The following render modes cause incorrect normals to meshes with a negative scale:
- `cull_disabled`
- `cull_front`
`cull_back` works as expected, and `ensure_correct_normals` does not fix the issue.
The capsule on the left have a scale of (-1, 1, 1). The capsule on the right has the default scale.

Using `cull_back`:

### Steps to reproduce
+ Create a mesh
+ Set its scale to a negative one
+ Apply the following shader:
```glsl
shader_type spatial;
render_mode unshaded, cull_disabled; // Same happens with cull_front. cull_back works as expected.
void fragment() {
ALBEDO = NORMAL;
}
```
### Minimal reproduction project (MRP)
- MRP: [negative_scale.zip](https://github.com/user-attachments/files/16033514/negative_scale.zip)
Contributor guide
Research direction
Start by opening the linked negative_scale.zip project and reproducing the issue with the shader's cull_disabled, cull_front, and cull_back modes. Trace the rendering path responsible for transformed normals and negative scale handling. Done means the left and right meshes show matching correct normals for the affected modes without regressing cull_back.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- 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