From ad322d24fe48d44f3df2cc233bc276287cad3dc7 Mon Sep 17 00:00:00 2001 From: Chris Biscardi Date: Sat, 27 Jul 2024 11:26:45 -0700 Subject: [PATCH] Fix render layers (#68) This is a rebased version of #49 which looks like it only needed merge conflicts resolved --------- Co-authored-by: Conner Petzold Co-authored-by: Spencer C. Imbleau --- CHANGELOG.md | 7 + Cargo.toml | 2 + examples/cube3d/Cargo.toml | 12 ++ examples/cube3d/src/main.rs | 169 +++++++++++++++++ examples/render_layers/Cargo.toml | 12 ++ examples/render_layers/src/main.rs | 148 +++++++++++++++ examples/text/Cargo.toml | 2 +- examples/text/src/main.rs | 23 ++- src/render/extract.rs | 91 +++++---- src/render/mod.rs | 27 ++- src/render/plugin.rs | 24 ++- src/render/prepare.rs | 291 ++++++++++++++++------------- src/render/systems.rs | 245 +++++++++++++----------- 13 files changed, 747 insertions(+), 306 deletions(-) create mode 100644 examples/cube3d/Cargo.toml create mode 100644 examples/cube3d/src/main.rs create mode 100644 examples/render_layers/Cargo.toml create mode 100644 examples/render_layers/src/main.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 05c1ee7..71e00d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,8 @@ Subheadings to categorize changes are `added, changed, deprecated, removed, fixe ### Added - There is now a `default_font` feature that uses the same `FiraMono-subset.ttf` font used in the bevy/default_font feature. +- There is now a `render_layers` example. +- There is now a `cube_3d` example. ### Changed @@ -24,11 +26,16 @@ Subheadings to categorize changes are `added, changed, deprecated, removed, fixe - The field `VelloAssetBundle.vector` was renamed to `VelloAssetBundle.asset`. - Renamed `VelloAssetAlignment` to `VelloAssetAnchor`. Fields were renamed `alignment` were renamed to `asset_anchor`. - Renamed `VelloTextAlignment` to `VelloTextAnchor`. Fields were renamed `alignment` were renamed to `text_anchor`. +- The `SSRenderTarget` (fullscreen quad that renders your frame) no longer renders at a zepth of `-0.001`. This was a legacy hack used to ensure Gizmos rendered on-top. ### Removed - Removed `ZFunction`s from the render pipeline. Now ordering is based solely on the `Transform`'s z component. If you dependeded on this behavior, you'll need to adjust the transform Z in a system prior to render. +### Fixed + +- Text, assets, and scenes rendered will now correctly respect camera `RenderLayers`. + ## 0.5.1 ### Fixed diff --git a/Cargo.toml b/Cargo.toml index cf74bb9..86cb96d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,8 @@ members = [ "examples/svg", "examples/lottie", "examples/scene_ui", + "examples/render_layers", + "examples/cube3d", ] [workspace.package] diff --git a/examples/cube3d/Cargo.toml b/examples/cube3d/Cargo.toml new file mode 100644 index 0000000..0b66c94 --- /dev/null +++ b/examples/cube3d/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "cube3d" +version.workspace = true +license.workspace = true +edition.workspace = true +repository.workspace = true +publish = false + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[dependencies] +bevy_vello = { path = "../../" } +bevy = { workspace = true } diff --git a/examples/cube3d/src/main.rs b/examples/cube3d/src/main.rs new file mode 100644 index 0000000..6940bcf --- /dev/null +++ b/examples/cube3d/src/main.rs @@ -0,0 +1,169 @@ +use bevy::{ + prelude::*, + render::{ + extract_component::{ExtractComponent, ExtractComponentPlugin}, + render_asset::RenderAssets, + render_resource::{ + Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages, + }, + renderer::{RenderDevice, RenderQueue}, + texture::GpuImage, + Render, RenderApp, RenderSet, + }, +}; +use bevy_vello::{prelude::*, render::VelloRenderer, VelloPlugin}; + +#[derive(Component)] +pub struct VelloTarget(Handle); + +impl ExtractComponent for VelloTarget { + type QueryData = &'static VelloTarget; + type QueryFilter = (); + type Out = Self; + fn extract_component(target: bevy::ecs::query::QueryItem<'_, Self::QueryData>) -> Option { + Some(Self(target.0.clone())) + } +} + +// Marks the main pass cube, to which the texture is applied. +#[derive(Component)] +struct MainPassCube; + +fn main() { + let mut app = App::new(); + + app.add_plugins(DefaultPlugins) + .add_plugins(VelloPlugin) + .add_systems(Startup, setup) + .add_systems(Update, cube_rotator_system) + .add_plugins(ExtractComponentPlugin::::default()); + + let Some(render_app) = app.get_sub_app_mut(RenderApp) else { + return; + }; + render_app.add_systems( + Render, + render_texture + .in_set(RenderSet::Render) + .run_if(resource_exists::), + ); + + app.run(); +} + +fn setup( + mut commands: Commands, + mut meshes: ResMut>, + mut materials: ResMut>, + mut images: ResMut>, +) { + let size = Extent3d { + width: 512, + height: 512, + ..default() + }; + // This is the texture that will be rendered to. + let mut image = Image { + texture_descriptor: TextureDescriptor { + label: None, + size, + dimension: TextureDimension::D2, + format: TextureFormat::Rgba8Unorm, + mip_level_count: 1, + sample_count: 1, + usage: TextureUsages::TEXTURE_BINDING + | TextureUsages::COPY_DST + | TextureUsages::STORAGE_BINDING, + view_formats: &[], + }, + ..default() + }; + + // fill image.data with zeroes + image.resize(size); + + let image_handle = images.add(image); + + // This material has the texture that has been rendered. + let material_handle = materials.add(StandardMaterial { + base_color_texture: Some(image_handle.clone()), + reflectance: 0.02, + unlit: false, + ..default() + }); + // Main pass cube, with material containing the rendered first pass texture. + commands.spawn(( + PbrBundle { + mesh: meshes.add(Cuboid::new(4.0, 4.0, 4.0)), + material: material_handle, + transform: Transform::from_xyz(0.0, 0.0, 1.5) + .with_rotation(Quat::from_rotation_x(-std::f32::consts::PI / 5.0)), + ..default() + }, + MainPassCube, + )); + // The main pass camera. + commands.spawn(PointLightBundle { + transform: Transform::from_translation(Vec3::new(0.0, 0.0, 10.0)), + ..default() + }); + commands.spawn(Camera3dBundle { + transform: Transform::from_xyz(0.0, 0.0, 15.0).looking_at(Vec3::ZERO, Vec3::Y), + ..default() + }); + commands.spawn(VelloTarget(image_handle)); +} + +fn render_texture( + mut vello_renderer: Local>, + target: Query<&VelloTarget>, + device: Res, + gpu_images: Res>, + queue: Res, + time: Res