Created
January 3, 2025 04:36
-
-
Save gbrls/6d3096f7d905c6358dfb023ad96a51ff to your computer and use it in GitHub Desktop.
genuary-2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //! Shows how to render to a texture. Useful for mirrors, UI, or exporting images. | |
| use std::f32::consts::PI; | |
| use bevy::{ | |
| prelude::*, | |
| render::{ | |
| render_asset::RenderAssetUsages, | |
| render_resource::{Extent3d, TextureDimension, TextureFormat, TextureUsages}, | |
| view::RenderLayers, | |
| }, | |
| }; | |
| use bevy_inspector_egui::quick::WorldInspectorPlugin; | |
| fn main() { | |
| App::new() | |
| .add_plugins(DefaultPlugins) | |
| .add_plugins(WorldInspectorPlugin::new()) | |
| .add_systems(Startup, setup) | |
| .add_systems(Update, cube_rotator_system) | |
| .run(); | |
| } | |
| // Marks the first pass cube (rendered to a texture.) | |
| #[derive(Component)] | |
| struct Cube { | |
| depth: usize, | |
| } | |
| fn add_layer( | |
| commands: &mut Commands, | |
| images: &mut ResMut<Assets<Image>>, | |
| meshes: &mut ResMut<Assets<Mesh>>, | |
| materials: &mut ResMut<Assets<StandardMaterial>>, | |
| layer: usize, | |
| previous: Option<Handle<Image>>, | |
| ) -> Handle<Image> { | |
| let size = Extent3d { | |
| width: 512, | |
| height: 512, | |
| ..default() | |
| }; | |
| let mut image = Image::new_fill( | |
| size, | |
| TextureDimension::D2, | |
| &[0, 0, 0, 0], | |
| TextureFormat::Bgra8UnormSrgb, | |
| RenderAssetUsages::default(), | |
| ); | |
| // You need to set these texture usage flags in order to use the image as a render target | |
| // @@step a - setup image | |
| image.texture_descriptor.usage = | |
| TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST | TextureUsages::RENDER_ATTACHMENT; | |
| let image_handle = images.add(image); | |
| commands.spawn(( | |
| PointLight::default(), | |
| Transform::from_translation(Vec3::new(0.0, 0.0, 10.0)), | |
| RenderLayers::layer(layer), | |
| )); | |
| let layer_handle = RenderLayers::layer(layer); | |
| let cube_size = 5.0; | |
| let cube_handle = meshes.add(Cuboid::new(cube_size, cube_size, cube_size)); | |
| //let cube_handle = meshes.add(Cuboid::new(cube_size, cube_size, cube_size)); | |
| let projection = Projection::from(PerspectiveProjection { | |
| fov: 30.0_f32.to_radians(), | |
| ..default() | |
| }); | |
| let cam_pos = 14.0; | |
| if layer == 0 { | |
| commands.spawn(( | |
| Camera3d::default(), | |
| Camera { | |
| clear_color: Color::WHITE.into(), | |
| ..default() | |
| }, | |
| projection, | |
| Transform::from_xyz(0.0, 0.0, cam_pos).looking_at(Vec3::ZERO, Vec3::Y), | |
| )); | |
| } else { | |
| commands.spawn(( | |
| Camera3d::default(), | |
| Camera { | |
| target: image_handle.clone().into(), | |
| clear_color: Color::WHITE.into(), | |
| ..default() | |
| }, | |
| projection, | |
| Transform::from_translation(Vec3::new(0.0, 0.0, cam_pos)) | |
| .looking_at(Vec3::ZERO, Vec3::Y), | |
| layer_handle.clone(), | |
| )); | |
| } | |
| match previous { | |
| Some(previous_cube_handle) => { | |
| let cube_material_handle = materials.add(StandardMaterial { | |
| base_color_texture: Some(previous_cube_handle), | |
| base_color: Color::srgb( | |
| 0.0 + (layer as f32 * 0.01).fract().max(0.9).min(1.0), | |
| 1.0 - (layer as f32 * 0.01).fract().max(0.9).min(1.0), | |
| (layer as f32 * 128.0).sin().abs().max(0.9).min(1.0), | |
| ) | |
| .into(), | |
| unlit: true, | |
| ..default() | |
| }); | |
| commands.spawn(( | |
| Mesh3d(cube_handle), | |
| MeshMaterial3d(cube_material_handle), | |
| Transform::from_translation(Vec3::new(0.0, 0.0, 1.0)), | |
| Cube { depth: layer }, | |
| layer_handle.clone(), | |
| )); | |
| } | |
| None => { | |
| let cube_material_handle = materials.add(StandardMaterial { | |
| base_color: Color::srgb( | |
| 0.0 + (layer as f32 * 0.1), | |
| 1.0 - (layer as f32 * 0.1), | |
| (layer as f32 * 128.0).sin().abs(), | |
| ) | |
| .into(), | |
| unlit: true, | |
| ..default() | |
| }); | |
| commands.spawn(( | |
| Mesh3d(cube_handle), | |
| MeshMaterial3d(cube_material_handle), | |
| Transform::from_translation(Vec3::new(0.0, 0.0, 1.0)), | |
| Cube { depth: layer }, | |
| layer_handle.clone(), | |
| )); | |
| } | |
| } | |
| image_handle | |
| } | |
| fn setup( | |
| mut commands: Commands, | |
| mut meshes: ResMut<Assets<Mesh>>, | |
| mut materials: ResMut<Assets<StandardMaterial>>, | |
| mut images: ResMut<Assets<Image>>, | |
| ) { | |
| let image_handle = (1..32).fold(None, |acc, i| { | |
| Some(add_layer( | |
| &mut commands, | |
| &mut images, | |
| &mut meshes, | |
| &mut materials, | |
| i, | |
| acc, | |
| )) | |
| }); | |
| let _final_handle = add_layer( | |
| &mut commands, | |
| &mut images, | |
| &mut meshes, | |
| &mut materials, | |
| 0, | |
| image_handle, | |
| ); | |
| } | |
| /// Rotates the outer cube (main pass) | |
| fn cube_rotator_system(time: Res<Time>, mut query: Query<(&mut Transform, &Cube)>) { | |
| let scale = 0.5; | |
| for (mut transform, cube) in &mut query { | |
| transform.rotate_x(1.0 * scale * time.delta_secs()); | |
| transform.rotate_y(0.11 * scale * time.delta_secs()); | |
| transform.rotate_z(0.017 * scale * time.delta_secs()); | |
| //if cube.depth % 2 == 0 { | |
| // transform.rotate_x(1.0 * scale * time.delta_secs()); | |
| // transform.rotate_y(0.7 * scale * time.delta_secs()); | |
| //} else { | |
| // transform.rotate_x(1.5 * scale * time.delta_secs()); | |
| // transform.rotate_z(1.3 * scale * time.delta_secs()); | |
| //} | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment