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