bevy/assets/shaders
Robert Swain fc56c686af bevy_pbr: Fix incorrect and unnecessary normal-mapping code (#5766)
# Objective

- Fixes #4019 
- Fix lighting of double-sided materials when using a negative scale
- The FlightHelmet.gltf model's hose uses a double-sided material. Loading the model with a uniform scale of -1.0, and comparing against Blender, it was identified that negating the world-space tangent, bitangent, and interpolated normal produces incorrect lighting. Discussion with Morten Mikkelsen clarified that this is both incorrect and unnecessary.

## Solution

- Remove the code that negates the T, B, and N vectors (the interpolated world-space tangent, calculated world-space bitangent, and interpolated world-space normal) when seeing the back face of a double-sided material with negative scale.
- Negate the world normal for a double-sided back face only when not using normal mapping

### Before, on `main`, flipping T, B, and N

<img width="932" alt="Screenshot 2022-08-22 at 15 11 53" src="https://user-images.githubusercontent.com/302146/185965366-f776ff2c-cfa1-46d1-9c84-fdcb399c273c.png">

### After, on this PR

<img width="932" alt="Screenshot 2022-08-22 at 15 12 11" src="https://user-images.githubusercontent.com/302146/185965420-8be493e2-3b1a-4188-bd13-fd6b17a76fe7.png">

### Double-sided material without normal maps

https://user-images.githubusercontent.com/302146/185988113-44a384e7-0b55-4946-9b99-20f8c803ab7e.mp4

---

## Changelog

- Fixed: Lighting of normal-mapped, double-sided materials applied to models with negative scale
- Fixed: Lighting and shadowing of back faces with no normal-mapping and a double-sided material

## Migration Guide

`prepare_normal` from the `bevy_pbr::pbr_functions` shader import has been reworked.

Before:
```rust
    pbr_input.world_normal = in.world_normal;

    pbr_input.N = prepare_normal(
        pbr_input.material.flags,
        in.world_normal,
#ifdef VERTEX_TANGENTS
#ifdef STANDARDMATERIAL_NORMAL_MAP
        in.world_tangent,
#endif
#endif
        in.uv,
        in.is_front,
    );
```

After:
```rust
    pbr_input.world_normal = prepare_world_normal(
        in.world_normal,
        (material.flags & STANDARD_MATERIAL_FLAGS_DOUBLE_SIDED_BIT) != 0u,
        in.is_front,
    );

    pbr_input.N = apply_normal_mapping(
        pbr_input.material.flags,
        pbr_input.world_normal,
#ifdef VERTEX_TANGENTS
#ifdef STANDARDMATERIAL_NORMAL_MAP
        in.world_tangent,
#endif
#endif
        in.uv,
    );
```
2022-11-03 20:37:32 +00:00
..
animate_shader.wgsl add globals to mesh view bind group (#5409) 2022-09-28 04:20:27 +00:00
array_texture.wgsl bevy_pbr: Fix incorrect and unnecessary normal-mapping code (#5766) 2022-11-03 20:37:32 +00:00
cubemap_unlit.wgsl Support array / cubemap / cubemap array textures in KTX2 (#5325) 2022-07-30 07:02:58 +00:00
custom_material.frag Update shader_material_glsl example to include texture sampling (#5215) 2022-07-08 01:14:22 +00:00
custom_material.vert Update shader_material_glsl example to include texture sampling (#5215) 2022-07-08 01:14:22 +00:00
custom_material.wgsl update wgpu to 0.13 (#5168) 2022-07-14 21:17:16 +00:00
custom_material_chromatic_aberration.wgsl adjust cluster index for viewport origin (#5947) 2022-09-15 21:58:14 +00:00
custom_material_screenspace_texture.wgsl adjust cluster index for viewport origin (#5947) 2022-09-15 21:58:14 +00:00
custom_vertex_attribute.wgsl update wgpu to 0.13 (#5168) 2022-07-14 21:17:16 +00:00
game_of_life.wgsl Remove unused code in game of life shader (#5349) 2022-07-17 15:24:24 +00:00
instancing.wgsl update wgpu to 0.13 (#5168) 2022-07-14 21:17:16 +00:00
line_material.wgsl Fix line material shader (#5348) 2022-07-17 15:02:57 +00:00
shader_defs.wgsl update wgpu to 0.13 (#5168) 2022-07-14 21:17:16 +00:00