Skip to content

Commit

Permalink
simplify configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
IceSentry committed Oct 27, 2022
1 parent a3f2121 commit 7558b80
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 51 deletions.
10 changes: 8 additions & 2 deletions crates/bevy_pbr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod pbr_material;
mod render;

pub use alpha::*;
use bevy_utils::default;
pub use bundle::*;
pub use light::*;
pub use material::*;
Expand Down Expand Up @@ -76,7 +77,9 @@ pub const SHADOW_SHADER_HANDLE: HandleUntyped =

/// Sets up the entire PBR infrastructure of bevy.
#[derive(Default)]
pub struct PbrPlugin;
pub struct PbrPlugin {
pub prepass_enabled: bool,
}

impl Plugin for PbrPlugin {
fn build(&self, app: &mut App) {
Expand Down Expand Up @@ -136,7 +139,10 @@ impl Plugin for PbrPlugin {
.register_type::<PointLight>()
.register_type::<SpotLight>()
.add_plugin(MeshRenderPlugin)
.add_plugin(MaterialPlugin::<StandardMaterial>::default())
.add_plugin(MaterialPlugin::<StandardMaterial> {
prepass_enabled: self.prepass_enabled,
..default()
})
.register_type::<AmbientLight>()
.register_type::<DirectionalLightShadowMap>()
.register_type::<PointLightShadowMap>()
Expand Down
30 changes: 10 additions & 20 deletions crates/bevy_pbr/src/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,6 @@ pub trait Material: AsBindGroup + Send + Sync + Clone + TypeUuid + Sized + 'stat
ShaderRef::Default
}

/// Controls if this Material is used in the prepass
/// You also need to enable the prepass globally using `GlobalMaterialOptions` for this to work
fn prepass_enabled() -> bool {
true
}

/// Customizes the default [`RenderPipelineDescriptor`] for a specific entity using the entity's
/// [`MaterialPipelineKey`] and [`MeshVertexBufferLayout`] as input.
#[allow(unused_variables)]
Expand All @@ -171,21 +165,19 @@ pub trait Material: AsBindGroup + Send + Sync + Clone + TypeUuid + Sized + 'stat
}
}

/// Options that affects all materials
#[derive(Resource, Default)]
pub struct GlobalMaterialOptions {
// Controls if the prepass will be used when rendering
// Disabled by default
pub prepass_enabled: bool,
}

/// Adds the necessary ECS resources and render logic to enable rendering entities using the given [`Material`]
/// asset type.
pub struct MaterialPlugin<M: Material>(PhantomData<M>);
pub struct MaterialPlugin<M: Material> {
pub prepass_enabled: bool,
pub _marker: PhantomData<M>,
}

impl<M: Material> Default for MaterialPlugin<M> {
fn default() -> Self {
Self(Default::default())
Self {
prepass_enabled: false,
_marker: Default::default(),
}
}
}

Expand All @@ -195,8 +187,7 @@ where
{
fn build(&self, app: &mut App) {
app.add_asset::<M>()
.add_plugin(ExtractComponentPlugin::<Handle<M>>::extract_visible())
.init_resource::<GlobalMaterialOptions>();
.add_plugin(ExtractComponentPlugin::<Handle<M>>::extract_visible());

if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
Expand All @@ -215,8 +206,7 @@ where
.add_system_to_stage(RenderStage::Queue, queue_material_meshes::<M>);
}

let options = app.world.resource::<GlobalMaterialOptions>();
if options.prepass_enabled && M::prepass_enabled() {
if self.prepass_enabled {
app.add_plugin(PrepassPlugin::<M>::default());
}
}
Expand Down
4 changes: 0 additions & 4 deletions crates/bevy_pbr/src/pbr_material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,8 +445,4 @@ impl Material for StandardMaterial {
fn depth_bias(&self) -> f32 {
self.depth_bias
}

fn prepass_enabled() -> bool {
true
}
}
46 changes: 21 additions & 25 deletions examples/shader/shader_prepass.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,24 @@
use bevy::{
core_pipeline::core_3d::PrepassSettings,
pbr::GlobalMaterialOptions,
pbr::PbrPlugin,
prelude::*,
reflect::TypeUuid,
render::render_resource::{AsBindGroup, ShaderRef},
};

fn main() {
App::new()
.insert_resource(Msaa { samples: 4 })
// The prepass is enabled per material
.insert_resource(GlobalMaterialOptions {
// the prepass is disabled by default so we need to enable it
// To enable the prepass on the StandardMaterial, we need to set it on the PbrPlugin
.add_plugins(DefaultPlugins.set(PbrPlugin {
prepass_enabled: true,
}))
// The prepass is enabled per material and is disabled by default
.add_plugin(MaterialPlugin::<CustomMaterial> {
prepass_enabled: true,
..Default::default()
})
// It's important to add the `GlobalMaterialOptions` before the `DefaultPlugins`,
// otherwise the StandardMaterial will not use the prepass
.add_plugins(DefaultPlugins)
.add_plugin(MaterialPlugin::<CustomMaterial>::default())
.add_plugin(MaterialPlugin::<DepthMaterial>::default())
.add_plugin(MaterialPlugin::<PrepassOutputMaterial>::default())
.add_startup_system(setup)
.add_system(rotate)
.run();
Expand All @@ -32,7 +31,7 @@ fn setup(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<CustomMaterial>>,
mut std_materials: ResMut<Assets<StandardMaterial>>,
mut depth_materials: ResMut<Assets<DepthMaterial>>,
mut depth_materials: ResMut<Assets<PrepassOutputMaterial>>,
asset_server: Res<AssetServer>,
) {
// plane
Expand All @@ -42,19 +41,19 @@ fn setup(
..default()
});

// depth plane
// A plane that shows the output of the depth prepass
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(shape::Quad {
flip: false,
size: Vec2::new(2.0, 2.0),
size: Vec2::new(1.5, 1.5),
})),
material: depth_materials.add(DepthMaterial {}),
transform: Transform::from_xyz(-1.0, 1.0, 2.0)
material: depth_materials.add(PrepassOutputMaterial {}),
transform: Transform::from_xyz(-0.75, 1.25, 2.0)
.looking_at(Vec3::new(2.0, -2.5, -5.0), Vec3::Y),
..default()
});

// opaque cube
// Opaque cube using the StandardMaterial
commands.spawn((
PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
Expand All @@ -65,7 +64,7 @@ fn setup(
Rotates,
));

// cube with alpha mask
// Cube with alpha mask
commands.spawn(PbrBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: std_materials.add(StandardMaterial {
Expand All @@ -78,7 +77,8 @@ fn setup(
..default()
});

// cube with alpha blending. Should be ignored by the prepass
// Cube with alpha blending.
// Transparent materials are ignored by the prepass
commands.spawn(MaterialMeshBundle {
mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })),
material: materials.add(CustomMaterial {
Expand Down Expand Up @@ -124,10 +124,6 @@ pub struct CustomMaterial {
alpha_mode: AlphaMode,
}

/// The Material trait is very configurable, but comes with sensible defaults for all methods.
/// You only need to implement functions for features that need non-default behavior.
/// See the Material api docs for details!
///
/// Not shown in this example, but if you need to specialize your material, the specialize
/// function will also be used in the prepass
impl Material for CustomMaterial {
Expand Down Expand Up @@ -156,12 +152,12 @@ fn rotate(mut q: Query<&mut Transform, With<Rotates>>, time: Res<Time>) {
}
}

// This is the struct that will be passed to your shader
// This shader simply loads the prepass texture and outputs it directly
#[derive(AsBindGroup, TypeUuid, Debug, Clone)]
#[uuid = "0af99895-b96e-4451-bc12-c6b1c1c52750"]
pub struct DepthMaterial {}
pub struct PrepassOutputMaterial {}

impl Material for DepthMaterial {
impl Material for PrepassOutputMaterial {
fn fragment_shader() -> ShaderRef {
"shaders/show_depth.wgsl".into()
}
Expand Down

0 comments on commit 7558b80

Please sign in to comment.