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

Fix handling of double_sided for normal maps #10326

Merged
merged 1 commit into from
Oct 31, 2023

Conversation

coreh
Copy link
Contributor

@coreh coreh commented Oct 31, 2023

Objective

Right now, we flip the world_normal in response to double_sided && !is_front, however when calculating N from tangents and the normal map, we don't flip the normal read from the normal map, which produces extremely weird results.

Solution

  • Pass double_sided and is_front flags to the apply_normal_mapping() function and use them to conditionally flip Nt

Comparison

Note: These are from a custom scene running with the transmission branch, (#8015) I noticed lighting got pretty weird for the back side of translucent double_sided materials whenever I added a normal map.

Before

Screenshot 2023-10-31 at 01 26 06

After

Screenshot 2023-10-31 at 01 25 42

Changelog

  • Fixed a bug where StandardMaterial::double_sided would interact incorrectly with normal maps, producing broken results.

@coreh coreh changed the title Fix handling of double_sided with normal maps Fix handling of double_sided in normal maps Oct 31, 2023
@coreh coreh changed the title Fix handling of double_sided in normal maps Fix handling of double_sided for normal maps Oct 31, 2023
@IceSentry IceSentry added the A-Rendering Drawing game state to the screen label Oct 31, 2023
@IceSentry
Copy link
Contributor

IceSentry commented Oct 31, 2023

Could this have any potential side effects with the mikktspace stuff right after?

I don't really see where the issue would be but maybe I'm missing something

@JMS55 JMS55 added this to the 0.12 milestone Oct 31, 2023
@IceSentry IceSentry added S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it C-Bug An unexpected or incorrect behavior labels Oct 31, 2023
@coreh
Copy link
Contributor Author

coreh commented Oct 31, 2023

Could this have any potential side effects with the mikktspace stuff right after?

Hmm... I honestly can't say I fully understand the Mikktspace tangent generation part, but all that the follow up code is doing is getting the existing tangents and normal and multiplying them by each component of the normal read from the map... In that case the (now) flipped normal from the map should match the flipped world normal to produce the (hopefully) correct results.

It looked completely broken before, after this change it at least looks plausibly right. The one thing I'm not 100% sure is if we'd also need to flip T to match the handedness of a fully flipped Nt, but since this looked okay with the changes and that seemed risky, I didn't do it.

@superdump superdump added this pull request to the merge queue Oct 31, 2023
Merged via the queue into bevyengine:main with commit dc1f76d Oct 31, 2023
25 checks passed
@rparrett
Copy link
Contributor

rparrett commented Oct 31, 2023

This seems to have missed a few calls to apply_normal_mapping, in

crates/bevy_pbr/src/render/pbr_prepass.wgsl
assets/shaders/array_texture.wgsl
examples/wasm/assets/shaders/array_texture.wgsl

As a result, the array_texture, ssao, shader_prepass examples are broken.

github-merge-queue bot pushed a commit that referenced this pull request Nov 1, 2023
# Objective

- After #10326, examples `array_texture`, `ssao` and `shader_prepass`
don't render correctly
```
error: failed to build a valid final module: Entry point fragment at Fragment is invalid
   ┌─ crates/bevy_pbr/src/render/pbr_prepass.wgsl:26:22
   │
26 │           let normal =  evy_pbr::pbr_functions::31mapply_normal_mapping(
   │ ╭──────────────────────^
27 │ │             bevy_pbr::pbr_bindings::material.flags,
28 │ │             world_normal,
29 │ │
   · │
36 │ │
37 │ │             bevy_pbr::mesh_view_bindings::view.mip_bias,
   │ ╰───────────────────────────────────────────────────────────────────────────────────────^ invalid function call
   │
   = Call to [9] is invalid
   = Requires 6 arguments, but 4 are provided

```

## Solution

- fix `apply_normal_mapping` calls
ameknite pushed a commit to ameknite/bevy that referenced this pull request Nov 6, 2023
# Objective

Right now, we flip the `world_normal` in response to `double_sided &&
!is_front`, however when calculating `N` from tangents and the normal
map, we don't flip the normal read from the normal map, which produces
extremely weird results.

## Solution

- Pass `double_sided` and `is_front` flags to the
`apply_normal_mapping()` function and use them to conditionally flip
`Nt`

## Comparison

Note: These are from a custom scene running with the `transmission`
branch, (bevyengine#8015) I noticed lighting got pretty weird for the back side of
translucent `double_sided` materials whenever I added a normal map.

### Before

<img width="1392" alt="Screenshot 2023-10-31 at 01 26 06"
src="https://github.com/bevyengine/bevy/assets/418473/d5f8c9c3-aca1-4c2f-854d-f0d0fd2fb19a">

### After

<img width="1392" alt="Screenshot 2023-10-31 at 01 25 42"
src="https://github.com/bevyengine/bevy/assets/418473/fa0e1aa2-19ad-4c27-bb08-37299d97971c">


---

## Changelog

- Fixed a bug where `StandardMaterial::double_sided` would interact
incorrectly with normal maps, producing broken results.
ameknite pushed a commit to ameknite/bevy that referenced this pull request Nov 6, 2023
# Objective

- After bevyengine#10326, examples `array_texture`, `ssao` and `shader_prepass`
don't render correctly
```
error: failed to build a valid final module: Entry point fragment at Fragment is invalid
   ┌─ crates/bevy_pbr/src/render/pbr_prepass.wgsl:26:22
   │
26 │           let normal =  evy_pbr::pbr_functions::31mapply_normal_mapping(
   │ ╭──────────────────────^
27 │ │             bevy_pbr::pbr_bindings::material.flags,
28 │ │             world_normal,
29 │ │
   · │
36 │ │
37 │ │             bevy_pbr::mesh_view_bindings::view.mip_bias,
   │ ╰───────────────────────────────────────────────────────────────────────────────────────^ invalid function call
   │
   = Call to [9] is invalid
   = Requires 6 arguments, but 4 are provided

```

## Solution

- fix `apply_normal_mapping` calls
rdrpenguin04 pushed a commit to rdrpenguin04/bevy that referenced this pull request Jan 9, 2024
# Objective

Right now, we flip the `world_normal` in response to `double_sided &&
!is_front`, however when calculating `N` from tangents and the normal
map, we don't flip the normal read from the normal map, which produces
extremely weird results.

## Solution

- Pass `double_sided` and `is_front` flags to the
`apply_normal_mapping()` function and use them to conditionally flip
`Nt`

## Comparison

Note: These are from a custom scene running with the `transmission`
branch, (bevyengine#8015) I noticed lighting got pretty weird for the back side of
translucent `double_sided` materials whenever I added a normal map.

### Before

<img width="1392" alt="Screenshot 2023-10-31 at 01 26 06"
src="https://github.com/bevyengine/bevy/assets/418473/d5f8c9c3-aca1-4c2f-854d-f0d0fd2fb19a">

### After

<img width="1392" alt="Screenshot 2023-10-31 at 01 25 42"
src="https://github.com/bevyengine/bevy/assets/418473/fa0e1aa2-19ad-4c27-bb08-37299d97971c">


---

## Changelog

- Fixed a bug where `StandardMaterial::double_sided` would interact
incorrectly with normal maps, producing broken results.
rdrpenguin04 pushed a commit to rdrpenguin04/bevy that referenced this pull request Jan 9, 2024
# Objective

- After bevyengine#10326, examples `array_texture`, `ssao` and `shader_prepass`
don't render correctly
```
error: failed to build a valid final module: Entry point fragment at Fragment is invalid
   ┌─ crates/bevy_pbr/src/render/pbr_prepass.wgsl:26:22
   │
26 │           let normal =  evy_pbr::pbr_functions::31mapply_normal_mapping(
   │ ╭──────────────────────^
27 │ │             bevy_pbr::pbr_bindings::material.flags,
28 │ │             world_normal,
29 │ │
   · │
36 │ │
37 │ │             bevy_pbr::mesh_view_bindings::view.mip_bias,
   │ ╰───────────────────────────────────────────────────────────────────────────────────────^ invalid function call
   │
   = Call to [9] is invalid
   = Requires 6 arguments, but 4 are provided

```

## Solution

- fix `apply_normal_mapping` calls
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior S-Ready-For-Final-Review This PR has been approved by the community. It's ready for a maintainer to consider merging it
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants