extended_material/
extended_material.rs1use bevy::{
4 color::palettes::basic::RED,
5 pbr::{ExtendedMaterial, MaterialExtension, OpaqueRendererMethod},
6 prelude::*,
7 render::render_resource::*,
8 shader::ShaderRef,
9};
10
11const SHADER_ASSET_PATH: &str = "shaders/extended_material.wgsl";
13
14fn main() {
15 App::new()
16 .add_plugins(DefaultPlugins)
17 .add_plugins(MaterialPlugin::<
18 ExtendedMaterial<StandardMaterial, MyExtension>,
19 >::default())
20 .add_systems(Startup, setup)
21 .add_systems(Update, rotate_things)
22 .run();
23}
24
25fn setup(
26 mut commands: Commands,
27 mut meshes: ResMut<Assets<Mesh>>,
28 mut materials: ResMut<Assets<ExtendedMaterial<StandardMaterial, MyExtension>>>,
29) {
30 commands.spawn((
32 Mesh3d(meshes.add(Sphere::new(1.0))),
33 MeshMaterial3d(materials.add(ExtendedMaterial {
34 base: StandardMaterial {
35 base_color: RED.into(),
36 opaque_render_method: OpaqueRendererMethod::Auto,
38 ..Default::default()
44 },
45 extension: MyExtension::new(1),
46 })),
47 Transform::from_xyz(0.0, 0.5, 0.0),
48 ));
49
50 commands.spawn((
52 DirectionalLight::default(),
53 Transform::from_xyz(1.0, 1.0, 1.0).looking_at(Vec3::ZERO, Vec3::Y),
54 Rotate,
55 ));
56
57 commands.spawn((
59 Camera3d::default(),
60 Transform::from_xyz(-2.0, 2.5, 5.0).looking_at(Vec3::ZERO, Vec3::Y),
61 ));
62}
63
64#[derive(Component)]
65struct Rotate;
66
67fn rotate_things(mut q: Query<&mut Transform, With<Rotate>>, time: Res<Time>) {
68 for mut t in &mut q {
69 t.rotate_y(time.delta_secs());
70 }
71}
72
73#[derive(Asset, AsBindGroup, Reflect, Debug, Clone, Default)]
74struct MyExtension {
75 #[uniform(100)]
78 quantize_steps: u32,
79 #[cfg(feature = "webgl2")]
81 #[uniform(100)]
82 _webgl2_padding_8b: u32,
83 #[cfg(feature = "webgl2")]
84 #[uniform(100)]
85 _webgl2_padding_12b: u32,
86 #[cfg(feature = "webgl2")]
87 #[uniform(100)]
88 _webgl2_padding_16b: u32,
89}
90impl MyExtension {
91 fn new(quantize_steps: u32) -> Self {
92 Self {
93 quantize_steps,
94 ..default()
95 }
96 }
97}
98
99impl MaterialExtension for MyExtension {
100 fn fragment_shader() -> ShaderRef {
101 SHADER_ASSET_PATH.into()
102 }
103
104 fn deferred_fragment_shader() -> ShaderRef {
105 SHADER_ASSET_PATH.into()
106 }
107}