Skip to content

Commit

Permalink
Pass RenderLayers to VelloCanvas (#71)
Browse files Browse the repository at this point in the history
This is the fix I talked about in #70 and the PR that would be merged
(the other should be closed)

This PR adds a config option to `VelloPlugin` and `VelloRenderPlugin`
that can control the `RenderLayers` that the `VelloCanvas` is on. This
allows fully taking advantage of `RenderLayers` as before the canvas was
rendering on the default layer, layer 0, which meant any camera that
wanted to render it also had to render everything else on the default
layer, layer 0.

---------

Co-authored-by: Spencer C. Imbleau <[email protected]>
  • Loading branch information
ChristopherBiscardi and simbleau committed Aug 4, 2024
1 parent ad322d2 commit f21cdc2
Show file tree
Hide file tree
Showing 15 changed files with 104 additions and 82 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Subheadings to categorize changes are `added, changed, deprecated, removed, fixe

### Changed

- `VelloPlugin` now has configuration. To retain previous behavior, use `VelloPlugin::default()`.
- The font API has changed significantly. Please visit `examples/text` for further usage. This is to prepare for additional text features such as linebreak behavior, bounded text, and text justification.
- `VelloText` has been renamed to `VelloTextSection`.
- `VelloText.content` has been renamed to `VelloText.value`.
Expand Down
2 changes: 1 addition & 1 deletion examples/cube3d/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fn main() {
let mut app = App::new();

app.add_plugins(DefaultPlugins)
.add_plugins(VelloPlugin)
.add_plugins(VelloPlugin::default())
.add_systems(Startup, setup)
.add_systems(Update, cube_rotator_system)
.add_plugins(ExtractComponentPlugin::<VelloTarget>::default());
Expand Down
2 changes: 1 addition & 1 deletion examples/demo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn main() {
..default()
}))
.add_plugins(EguiPlugin)
.add_plugins(VelloPlugin)
.add_plugins(VelloPlugin::default())
.init_resource::<EmbeddedAssetRegistry>()
.add_plugins(bevy_pancam::PanCamPlugin)
.add_systems(Startup, setup_vector_graphics)
Expand Down
2 changes: 1 addition & 1 deletion examples/drag_n_drop/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fn main() {
meta_check: AssetMetaCheck::Never,
..default()
}))
.add_plugins(VelloPlugin)
.add_plugins(VelloPlugin::default())
.add_systems(Startup, setup_vector_graphics)
.add_systems(Update, drag_and_drop);
embedded_asset!(app, "assets/fountain.svg");
Expand Down
2 changes: 1 addition & 1 deletion examples/lottie/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fn main() {
meta_check: AssetMetaCheck::Never,
..default()
}))
.add_plugins(VelloPlugin)
.add_plugins(VelloPlugin::default())
.add_systems(Startup, load_lottie);
embedded_asset!(app, "assets/Tiger.json");
app.run();
Expand Down
112 changes: 50 additions & 62 deletions examples/render_layers/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,55 +6,71 @@ use bevy_vello::{prelude::*, VelloPlugin};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(VelloPlugin)
.add_systems(Startup, (setup_animation, setup_background))
.add_plugins(VelloPlugin::default())
.add_systems(
Update,
Startup,
(
layer0_animation,
layer1_animation,
layer2_background,
run_gizmos,
setup_canvas,
setup_gizmos,
setup_animation,
setup_background,
),
)
.add_systems(Update, (animation, background, run_gizmos))
.run();
}

/// A tag that will mark the scene on RenderLayer 0.
/// A tag that will mark the scene with animation.
#[derive(Component)]
struct Layer0Scene;
struct AnimationScene;

/// A tag that will mark the scene on RenderLayer 1.
/// A tag that will mark the scene with the blue square.
#[derive(Component)]
struct Layer1Scene;
struct BackgroundScene;

/// A tag that will mark the scene on RenderLayer 2.
#[derive(Component)]
struct Layer2Scene;
fn setup_canvas(mut settings: ResMut<VelloRenderSettings>) {
// There's only 1 Vello canvas, so as long as you use a layer that has a camera, you're good!
settings.canvas_render_layers = RenderLayers::layer(3); // the gizmo camera layer
}

fn setup_animation(mut commands: Commands) {
const LAYER_0: RenderLayers = RenderLayers::layer(0);
const LAYER_1: RenderLayers = RenderLayers::layer(1);
fn setup_gizmos(mut commands: Commands, mut config_store: ResMut<GizmoConfigStore>) {
// This camera can only see Gizmos.
commands.spawn((
Camera2dBundle {
camera: Camera {
// This camera will render LAST.
order: 1,
..default()
},
..default()
},
RenderLayers::layer(3),
));
let (config, _) = config_store.config_mut::<DefaultGizmoConfigGroup>();
config.render_layers = RenderLayers::layer(3);
}

// This camera can see everything on Layer 1 and Layer 2.
fn setup_animation(mut commands: Commands) {
commands.spawn((
Camera2dBundle {
camera: Camera {
// This camera will render AFTER the blue background camera!
order: 1,
order: 0,
..default()
},
..default()
},
LAYER_0.union(&LAYER_1),
RenderLayers::layer(2),
));

commands.spawn((VelloSceneBundle::default(), Layer0Scene, LAYER_0));
commands.spawn((VelloSceneBundle::default(), Layer1Scene, LAYER_1));
commands.spawn((
VelloSceneBundle::default(),
AnimationScene,
RenderLayers::layer(2),
));
}

fn setup_background(mut commands: Commands) {
const LAYER: RenderLayers = RenderLayers::layer(2);
commands.spawn((
Camera2dBundle {
camera: Camera {
Expand All @@ -64,13 +80,17 @@ fn setup_background(mut commands: Commands) {
},
..default()
},
LAYER,
RenderLayers::layer(1),
));
commands.spawn((
VelloSceneBundle::default(),
BackgroundScene,
RenderLayers::layer(1),
));
commands.spawn((VelloSceneBundle::default(), Layer2Scene, LAYER));
}

fn layer0_animation(
mut query_scene: Query<(&mut Transform, &mut VelloScene), With<Layer0Scene>>,
fn animation(
mut query_scene: Query<(&mut Transform, &mut VelloScene), With<AnimationScene>>,
time: Res<Time>,
) {
let sin_time = time.elapsed_seconds().sin().mul_add(0.5, 0.5);
Expand All @@ -95,43 +115,11 @@ fn layer0_animation(
);

transform.scale = Vec3::lerp(Vec3::ONE * 0.5, Vec3::ONE * 1.0, sin_time);
transform.translation =
Vec3::lerp(Vec3::X * -100.0, Vec3::X * 100.0, sin_time) - Vec3::Y * 100.0;
transform.rotation = Quat::from_rotation_z(-std::f32::consts::TAU * sin_time);
}

fn layer1_animation(
mut query_scene: Query<(&mut Transform, &mut VelloScene), With<Layer1Scene>>,
time: Res<Time>,
) {
let sin_time = time.elapsed_seconds().sin().mul_add(0.5, 0.5);
let (mut transform, mut scene) = query_scene.single_mut();
// Reset scene every frame
*scene = VelloScene::default();

// Animate color green to blue
let c = Vec3::lerp(
Vec3::new(1.0, -1.0, 0.0),
Vec3::new(1.0, 1.0, 0.0),
sin_time + 0.5,
);

// Animate the corner radius
scene.fill(
peniko::Fill::NonZero,
kurbo::Affine::default(),
peniko::Color::rgb(c.x as f64, c.y as f64, c.z as f64),
None,
&kurbo::RoundedRect::new(-50.0, -50.0, 50.0, 50.0, (sin_time as f64) * 50.0),
);

transform.scale = Vec3::lerp(Vec3::ONE * 0.5, Vec3::ONE * 1.0, sin_time);
transform.translation =
Vec3::lerp(Vec3::X * -100.0, Vec3::X * 100.0, sin_time) * Vec3::NEG_X + Vec3::Y * 100.0;
transform.translation = Vec3::lerp(Vec3::X * -100.0, Vec3::X * 100.0, sin_time);
transform.rotation = Quat::from_rotation_z(-std::f32::consts::TAU * sin_time);
}

fn layer2_background(mut query_scene: Query<&mut VelloScene, With<Layer2Scene>>) {
fn background(mut query_scene: Query<&mut VelloScene, With<BackgroundScene>>) {
let mut scene = query_scene.single_mut();
*scene = VelloScene::default();
scene.fill(
Expand All @@ -144,5 +132,5 @@ fn layer2_background(mut query_scene: Query<&mut VelloScene, With<Layer2Scene>>)
}

fn run_gizmos(mut gizmos: Gizmos) {
gizmos.circle_2d(Vec2::splat(0.0), 20.0, css::RED);
gizmos.circle_2d(Vec2::splat(0.0), 100.0, css::MAGENTA);
}
2 changes: 1 addition & 1 deletion examples/scene/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use bevy_vello::{
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(VelloPlugin)
.add_plugins(VelloPlugin::default())
.add_systems(Startup, setup_vector_graphics)
.add_systems(Update, simple_animation)
.run();
Expand Down
2 changes: 1 addition & 1 deletion examples/scene_ui/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::f64::consts::{FRAC_PI_4, SQRT_2};
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(VelloPlugin)
.add_plugins(VelloPlugin::default())
.add_systems(Startup, setup_ui)
.add_systems(Update, update_ui)
.run();
Expand Down
2 changes: 1 addition & 1 deletion examples/svg/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fn main() {
meta_check: AssetMetaCheck::Never,
..default()
}))
.add_plugins(VelloPlugin)
.add_plugins(VelloPlugin::default())
.add_systems(Startup, load_svg);
embedded_asset!(app, "assets/fountain.svg");
app.run();
Expand Down
2 changes: 1 addition & 1 deletion examples/text/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fn main() {
meta_check: AssetMetaCheck::Never,
..default()
}))
.add_plugins(VelloPlugin)
.add_plugins(VelloPlugin::default())
.add_systems(
Startup,
(setup_camera, setup_screenspace_text, setup_worldspace_text),
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub mod prelude {
pub use crate::{
debug::DebugVisualizations,
integrations::{VectorFile, VelloAsset, VelloAssetAnchor},
render::VelloCanvasMaterial,
render::{VelloCanvasMaterial, VelloRenderSettings},
text::{VelloFont, VelloTextAnchor, VelloTextSection, VelloTextStyle},
CoordinateSpace, VelloAssetBundle, VelloScene, VelloSceneBundle, VelloTextBundle,
};
Expand Down
12 changes: 9 additions & 3 deletions src/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
use crate::{
debug::DebugVisualizationsPlugin, render::VelloRenderPlugin, text::VelloFontLoader, VelloAsset,
VelloFont,
VelloFont, VelloRenderSettings,
};
use bevy::{asset::load_internal_binary_asset, prelude::*};
use bevy::{asset::load_internal_binary_asset, prelude::*, render::view::RenderLayers};

pub struct VelloPlugin;
#[derive(Resource, Default, Debug)]
pub struct VelloPlugin {
pub canvas_render_layers: RenderLayers,
}

impl Plugin for VelloPlugin {
fn build(&self, app: &mut App) {
app.add_plugins(VelloRenderPlugin)
.insert_resource(VelloRenderSettings {
canvas_render_layers: self.canvas_render_layers.clone(),
})
.add_plugins(DebugVisualizationsPlugin)
.init_asset::<VelloAsset>()
.init_asset::<VelloFont>()
Expand Down
1 change: 1 addition & 0 deletions src/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ mod prepare;
mod systems;

pub use plugin::VelloRenderPlugin;
pub use plugin::VelloRenderSettings;

/// A handle to the screen space render target shader.
pub const SSRT_SHADER_HANDLE: Handle<Shader> = Handle::weak_from_u128(2314894693238056781);
Expand Down
14 changes: 12 additions & 2 deletions src/render/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,20 @@ use bevy::{
extract_component::ExtractComponentPlugin,
render_asset::RenderAssetPlugin,
renderer::RenderDevice,
view::{check_visibility, VisibilitySystems},
view::{check_visibility, RenderLayers, VisibilitySystems},
Render, RenderApp, RenderSet,
},
sprite::Material2dPlugin,
};

pub struct VelloRenderPlugin;

#[derive(Resource, Default, Clone, Debug)]
pub struct VelloRenderSettings {
/// The render layer that will be used for the vello canvas mesh.
pub canvas_render_layers: RenderLayers,
}

impl Plugin for VelloRenderPlugin {
fn build(&self, app: &mut App) {
load_internal_asset!(
Expand Down Expand Up @@ -75,7 +81,11 @@ impl Plugin for VelloRenderPlugin {
.add_systems(Startup, systems::setup_ss_rendertarget)
.add_systems(
Update,
(systems::resize_rendertargets, systems::clear_when_empty),
(
systems::resize_rendertargets,
systems::hide_when_empty,
systems::settings_change_detection,
),
)
.add_systems(
PostUpdate,
Expand Down
28 changes: 22 additions & 6 deletions src/render/systems.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::{
extract::{ExtractedRenderAsset, ExtractedRenderText, SSRenderTarget},
plugin::VelloRenderSettings,
prepare::PreparedAffine,
VelloRenderer,
};
Expand Down Expand Up @@ -282,6 +283,7 @@ pub fn setup_ss_rendertarget(
mut custom_materials: ResMut<Assets<VelloCanvasMaterial>>,
windows: Query<&Window>,
mut render_target_mesh_handle: Local<Option<Handle<Mesh>>>,
settings: Res<VelloRenderSettings>,
) {
let Ok(window) = windows.get_single() else {
return;
Expand Down Expand Up @@ -321,17 +323,31 @@ pub fn setup_ss_rendertarget(
.spawn(MaterialMesh2dBundle {
mesh,
material,
transform: Transform::from_translation(0.001 * Vec3::NEG_Z), /* Make sure the vello
* canvas renders behind
* Gizmos */
..Default::default()
..default()
})
.insert(NoFrustumCulling)
.insert(render_target);
.insert(render_target)
.insert(settings.canvas_render_layers.clone());
}

/// Listen for settings changes that a developer could make.
pub fn settings_change_detection(
mut commands: Commands,
mut query_render_target: Query<Entity, With<SSRenderTarget>>,
settings: Res<VelloRenderSettings>,
) {
if let Ok(entity) = query_render_target.get_single_mut() {
if settings.is_changed() {
// Replace the canvas render layers
commands
.entity(entity)
.insert(settings.canvas_render_layers.clone());
}
}
}

/// Hide the render target canvas if there is nothing to render
pub fn clear_when_empty(
pub fn hide_when_empty(
mut query_render_target: Query<&mut Visibility, With<SSRenderTarget>>,
render_items: Query<
(),
Expand Down

0 comments on commit f21cdc2

Please sign in to comment.