lightmaps/
lightmaps.rs

1//! Rendering a scene with baked lightmaps.
2
3use argh::FromArgs;
4use bevy::{
5    core_pipeline::prepass::{DeferredPrepass, DepthPrepass, MotionVectorPrepass},
6    gltf::GltfMeshName,
7    pbr::{DefaultOpaqueRendererMethod, Lightmap},
8    prelude::*,
9};
10
11/// Demonstrates lightmaps
12#[derive(FromArgs, Resource)]
13struct Args {
14    /// enables deferred shading
15    #[argh(switch)]
16    deferred: bool,
17    /// enables bicubic filtering
18    #[argh(switch)]
19    bicubic: bool,
20}
21
22fn main() {
23    #[cfg(not(target_arch = "wasm32"))]
24    let args: Args = argh::from_env();
25    #[cfg(target_arch = "wasm32")]
26    let args: Args = Args::from_args(&[], &[]).unwrap();
27
28    let mut app = App::new();
29    app.add_plugins(DefaultPlugins)
30        .insert_resource(AmbientLight::NONE);
31
32    if args.deferred {
33        app.insert_resource(DefaultOpaqueRendererMethod::deferred());
34    }
35
36    app.insert_resource(args)
37        .add_systems(Startup, setup)
38        .add_systems(Update, add_lightmaps_to_meshes)
39        .run();
40}
41
42fn setup(mut commands: Commands, asset_server: Res<AssetServer>, args: Res<Args>) {
43    commands.spawn(SceneRoot(asset_server.load(
44        GltfAssetLabel::Scene(0).from_asset("models/CornellBox/CornellBox.glb"),
45    )));
46
47    let mut camera = commands.spawn((
48        Camera3d::default(),
49        Transform::from_xyz(-278.0, 273.0, 800.0),
50    ));
51
52    if args.deferred {
53        camera.insert((
54            DepthPrepass,
55            MotionVectorPrepass,
56            DeferredPrepass,
57            Msaa::Off,
58        ));
59    }
60}
61
62fn add_lightmaps_to_meshes(
63    mut commands: Commands,
64    asset_server: Res<AssetServer>,
65    mut materials: ResMut<Assets<StandardMaterial>>,
66    meshes: Query<
67        (Entity, &GltfMeshName, &MeshMaterial3d<StandardMaterial>),
68        (With<Mesh3d>, Without<Lightmap>),
69    >,
70    args: Res<Args>,
71) {
72    let exposure = 250.0;
73    for (entity, name, material) in meshes.iter() {
74        if &**name == "large_box" {
75            materials.get_mut(material).unwrap().lightmap_exposure = exposure;
76            commands.entity(entity).insert(Lightmap {
77                image: asset_server.load("lightmaps/CornellBox-Large.zstd.ktx2"),
78                bicubic_sampling: args.bicubic,
79                ..default()
80            });
81            continue;
82        }
83
84        if &**name == "small_box" {
85            materials.get_mut(material).unwrap().lightmap_exposure = exposure;
86            commands.entity(entity).insert(Lightmap {
87                image: asset_server.load("lightmaps/CornellBox-Small.zstd.ktx2"),
88                bicubic_sampling: args.bicubic,
89                ..default()
90            });
91            continue;
92        }
93
94        if name.starts_with("cornell_box") {
95            materials.get_mut(material).unwrap().lightmap_exposure = exposure;
96            commands.entity(entity).insert(Lightmap {
97                image: asset_server.load("lightmaps/CornellBox-Box.zstd.ktx2"),
98                bicubic_sampling: args.bicubic,
99                ..default()
100            });
101            continue;
102        }
103    }
104}