| 1 |
--- |
| 2 |
title: "Order independent transparency changes to support premultiplied alpha modes and per-material opt-out" |
| 3 |
pull_requests: [22821, 24856] |
| 4 |
--- |
| 5 |
|
| 6 |
1. OIT now can be opt-out per material via the new `enable_oit` method on `Material` and `MaterialExtension`. The associated `ShaderDef` is `MATERIAL_OIT_ENABLED`. The original `OIT_ENABLED` is used for `mesh_view_bindings.wgsl` and is enabled per camera/view. So custom oit-compatible material shaders should gate `oit_draw` behind `MATERIAL_OIT_ENABLED` instead of `OIT_ENABLED`. |
| 7 |
2. The `oit_draw` function now expects alpha-premultiplied color to support `AlphaMode::Premultiplied` and `AlphaMode::Add` in addition to `AlphaMode::Blend` modes. |
| 8 |
|
| 9 |
```wgsl |
| 10 |
// BEFORE |
| 11 |
#ifdef OIT_ENABLED |
| 12 |
#import bevy_core_pipeline::oit::oit_draw |
| 13 |
#endif // OIT_ENABLED |
| 14 |
|
| 15 |
#ifdef OIT_ENABLED |
| 16 |
let alpha_mode = pbr_input.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS; |
| 17 |
if alpha_mode != pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE { |
| 18 |
// The fragments will only be drawn during the oit resolve pass. |
| 19 |
oit_draw(in.position, out.color); |
| 20 |
discard; |
| 21 |
} |
| 22 |
#endif // OIT_ENABLED |
| 23 |
|
| 24 |
// AFTER |
| 25 |
#ifdef MATERIAL_OIT_ENABLED |
| 26 |
#import bevy_core_pipeline::oit::oit_draw |
| 27 |
#endif // MATERIAL_OIT_ENABLED |
| 28 |
|
| 29 |
#ifdef MATERIAL_OIT_ENABLED |
| 30 |
let alpha_mode = pbr_input.material.flags & pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_RESERVED_BITS; |
| 31 |
if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_BLEND { |
| 32 |
// The fragments will only be drawn during the oit resolve pass. |
| 33 |
oit_draw(in.position, vec4(out.color.rgb * out.color.a, out.color.a)); |
| 34 |
discard; |
| 35 |
} |
| 36 |
// Both `Premultiplied` and `Add` colors are premultiplied in `premultiply_alpha()` |
| 37 |
if alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_PREMULTIPLIED |
| 38 |
|| alpha_mode == pbr_types::STANDARD_MATERIAL_FLAGS_ALPHA_MODE_ADD { |
| 39 |
// The fragments will only be drawn during the oit resolve pass. |
| 40 |
oit_draw(in.position, out.color); |
| 41 |
discard; |
| 42 |
} |
| 43 |
#endif // MATERIAL_OIT_ENABLED |
| 44 |
``` |