Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/examples/3d/decal.rs
9323 views
1
//! Decal rendering.
2
//! Note: On Wasm, this example only runs on WebGPU
3
4
use bevy::{
5
anti_alias::fxaa::Fxaa,
6
camera_controller::free_camera::{FreeCamera, FreeCameraPlugin},
7
core_pipeline::prepass::DepthPrepass,
8
pbr::decal::{ForwardDecal, ForwardDecalMaterial, ForwardDecalMaterialExt},
9
prelude::*,
10
};
11
use rand::{Rng, SeedableRng};
12
use rand_chacha::ChaCha8Rng;
13
14
fn main() {
15
App::new()
16
.add_plugins((DefaultPlugins, FreeCameraPlugin))
17
.add_systems(Startup, setup)
18
.run();
19
}
20
21
fn setup(
22
mut commands: Commands,
23
mut meshes: ResMut<Assets<Mesh>>,
24
mut standard_materials: ResMut<Assets<StandardMaterial>>,
25
mut decal_standard_materials: ResMut<Assets<ForwardDecalMaterial<StandardMaterial>>>,
26
asset_server: Res<AssetServer>,
27
) {
28
// Spawn the forward decal
29
commands.spawn((
30
Name::new("Decal"),
31
ForwardDecal,
32
MeshMaterial3d(decal_standard_materials.add(ForwardDecalMaterial {
33
base: StandardMaterial {
34
base_color_texture: Some(asset_server.load("textures/uv_checker_bw.png")),
35
..default()
36
},
37
extension: ForwardDecalMaterialExt {
38
depth_fade_factor: 1.0,
39
},
40
})),
41
Transform::from_scale(Vec3::splat(4.0)),
42
));
43
44
commands.spawn((
45
Name::new("Camera"),
46
Camera3d::default(),
47
FreeCamera::default(),
48
// Must enable the depth prepass to render forward decals
49
DepthPrepass,
50
// Must disable MSAA to use decals on WebGPU
51
Msaa::Off,
52
// FXAA is a fine alternative to MSAA for anti-aliasing
53
Fxaa::default(),
54
Transform::from_xyz(2.0, 9.5, 2.5).looking_at(Vec3::ZERO, Vec3::Y),
55
));
56
57
let white_material = standard_materials.add(Color::WHITE);
58
59
commands.spawn((
60
Name::new("Floor"),
61
Mesh3d(meshes.add(Rectangle::from_length(10.0))),
62
MeshMaterial3d(white_material.clone()),
63
Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
64
));
65
66
// Spawn a few cube with random rotations to showcase how the decals behave with non-flat geometry
67
let num_obs = 10;
68
let mut rng = ChaCha8Rng::seed_from_u64(19878367467713);
69
for i in 0..num_obs {
70
for j in 0..num_obs {
71
let rotation_axis: [f32; 3] = rng.random();
72
let rotation_vec: Vec3 = rotation_axis.into();
73
let rotation: u32 = rng.random_range(0..360);
74
let transform = Transform::from_xyz(
75
(-num_obs + 1) as f32 / 2.0 + i as f32,
76
-0.2,
77
(-num_obs + 1) as f32 / 2.0 + j as f32,
78
)
79
.with_rotation(Quat::from_axis_angle(
80
rotation_vec.normalize_or_zero(),
81
(rotation as f32).to_radians(),
82
));
83
84
commands.spawn((
85
Mesh3d(meshes.add(Cuboid::from_length(0.6))),
86
MeshMaterial3d(white_material.clone()),
87
transform,
88
));
89
}
90
}
91
92
commands.spawn((
93
Name::new("Light"),
94
PointLight {
95
shadow_maps_enabled: true,
96
..default()
97
},
98
Transform::from_xyz(4.0, 8.0, 4.0),
99
));
100
}
101
102