Skip to content

Commit

Permalink
0.12 Material Extensions (#790)
Browse files Browse the repository at this point in the history
  • Loading branch information
cart authored Nov 2, 2023
1 parent 390cc89 commit 9294e55
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
83 changes: 83 additions & 0 deletions content/news/2023-10-21-bevy-0.12/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,89 @@ bevy_pbr::pbr_functions::pbr()

Rusty Imports remove a number of "API weirdness" gotchas from the old system and expand the capabilities of the import system. And by reusing Rust syntax and semantics, we remove the need for Bevy users to learn a new system.

## Material Extensions

<div class="release-feature-authors">authors: @robtfm</div>

Bevy has a powerful shader import system, allowing modular (and granular) shader code reuse. In previous versions of Bevy, this meant that in theory, you could import Bevy's PBR shader logic and use it in your own shaders. However in practice this was challenging, as you had to re-wire everything up yourself, which required intimate knowledge of the base material. For complicated materials like Bevy's PBR [`StandardMaterial`], this was full of boilerplate, resulted in code duplication, and was prone to errors.

In **Bevy 0.12**, we've built a **Material Extensions** system, which enables defining new materials that build on existing materials:

![material extension](material_extension.png)

This is accomplished via a new [`ExtendedMaterial`] type:

```rust
app.add_plugin(
MaterialPlugin::<ExtendedMaterial<StandardMaterial, QuantizedMaterial>>::default()
);

#[derive(Asset, AsBindGroup, TypePath, Debug, Clone)]
struct QuantizedMaterial {
// Start at a high binding number to ensure bindings don't conflict
// with the base material
#[uniform(100)]
quantize_steps: u32,
}

impl MaterialExtension for QuantizedMaterial {
fn fragment_shader() -> ShaderRef {
"quantized_material.wgsl".into()
}
}

let material = ExtendedMaterial<StandardMaterial, QuantizedMaterial> {
base: StandardMaterial::from(Color::rgb(0.1, 0.1, 0.8)),
extension: QuantizedMaterial { quantize_steps: 2 },
};
```

We also paired this with some [`StandardMaterial`] shader refactors to make it much easier to pick and choose which parts you want:

```rust
// quantized_material.wgsl

struct QuantizedMaterial {
quantize_steps: u32,
}

@group(1) @binding(100)
var<uniform> my_extended_material: QuantizedMaterial;

@fragment
fn fragment(
input: VertexOutput,
@builtin(front_facing) is_front: bool,
) -> FragmentOutput {
// Generate a PbrInput struct from the StandardMaterial bindings
var pbr_input = pbr_input_from_standard_material(input, is_front);

// Alpha discard
pbr_input.material.base_color = alpha_discard(
pbr_input.material,
pbr_input.material.base_color
);

var out: FragmentOutput;

// Apply lighting
out.color = apply_pbr_lighting(pbr_input);

// Our "quantize" effect
out.color = vec4<f32>(vec4<u32>(out.color * f32(my_extended_material.quantize_steps))) / f32(my_extended_material.quantize_steps);

// Apply in-shader post processing.
// Ex: fog, alpha-premultiply, etc. For non-hdr cameras: tonemapping and debanding
out.color = main_pass_post_lighting_processing(pbr_input, out.color);

return out;
}
```

This _vastly_ simplifies writing custom PBR materials, making it accessible to pretty much everyone!

[`ExtendedMaterial`]: https://dev-docs.bevyengine.org/bevy/pbr/struct.ExtendedMaterial.html

## Deferred Rendering

<div class="release-feature-authors">authors: @DGriffin91</div>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 9294e55

Please sign in to comment.