-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This is a rebased version of #49 which looks like it only needed merge conflicts resolved --------- Co-authored-by: Conner Petzold <[email protected]> Co-authored-by: Spencer C. Imbleau <[email protected]>
- Loading branch information
1 parent
5882f36
commit ad322d2
Showing
13 changed files
with
747 additions
and
306 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 } |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Image>); | ||
|
||
impl ExtractComponent for VelloTarget { | ||
type QueryData = &'static VelloTarget; | ||
type QueryFilter = (); | ||
type Out = Self; | ||
fn extract_component(target: bevy::ecs::query::QueryItem<'_, Self::QueryData>) -> Option<Self> { | ||
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::<VelloTarget>::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::<RenderDevice>), | ||
); | ||
|
||
app.run(); | ||
} | ||
|
||
fn setup( | ||
mut commands: Commands, | ||
mut meshes: ResMut<Assets<Mesh>>, | ||
mut materials: ResMut<Assets<StandardMaterial>>, | ||
mut images: ResMut<Assets<Image>>, | ||
) { | ||
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<Option<VelloRenderer>>, | ||
target: Query<&VelloTarget>, | ||
device: Res<RenderDevice>, | ||
gpu_images: Res<RenderAssets<GpuImage>>, | ||
queue: Res<RenderQueue>, | ||
time: Res<Time>, | ||
) { | ||
let renderer = | ||
vello_renderer.get_or_insert_with(|| VelloRenderer::from_device(device.wgpu_device())); | ||
let target = target.single(); | ||
|
||
let mut scene = VelloScene::default(); | ||
// Animate the scene | ||
let sin_time = time.elapsed_seconds().sin().mul_add(0.5, 0.5); | ||
let c = Vec3::lerp( | ||
Vec3::new(-1.0, 0.0, 1.0), | ||
Vec3::new(1.0, 0.0, 1.0), | ||
sin_time + 0.5, | ||
); | ||
scene.fill( | ||
peniko::Fill::NonZero, | ||
kurbo::Affine::translate((128.0, 128.0)), | ||
peniko::Color::rgb(c.x as f64, c.y as f64, c.z as f64), | ||
None, | ||
&kurbo::RoundedRect::new(0.0, 0.0, 256.0, 256.0, (sin_time as f64) * 128.0), | ||
); | ||
|
||
let gpu_image = gpu_images.get(&target.0).unwrap(); | ||
let params = vello::RenderParams { | ||
base_color: vello::peniko::Color::WHITE, | ||
width: gpu_image.size.x, | ||
height: gpu_image.size.y, | ||
antialiasing_method: vello::AaConfig::Area, | ||
}; | ||
renderer | ||
.render_to_texture( | ||
device.wgpu_device(), | ||
&queue, | ||
&scene, | ||
&gpu_image.texture_view, | ||
¶ms, | ||
) | ||
.unwrap(); | ||
} | ||
|
||
/// Rotates the outer cube (main pass) | ||
fn cube_rotator_system(time: Res<Time>, mut query: Query<&mut Transform, With<MainPassCube>>) { | ||
for mut transform in &mut query { | ||
transform.rotate_x(1.0 * time.delta_seconds()); | ||
transform.rotate_y(0.7 * time.delta_seconds()); | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
[package] | ||
name = "render_layers" | ||
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, features = ["bevy_gizmos"] } |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
//! Shows how to use render layers. | ||
|
||
use bevy::{color::palettes::css, prelude::*, render::view::RenderLayers}; | ||
use bevy_vello::{prelude::*, VelloPlugin}; | ||
|
||
fn main() { | ||
App::new() | ||
.add_plugins(DefaultPlugins) | ||
.add_plugins(VelloPlugin) | ||
.add_systems(Startup, (setup_animation, setup_background)) | ||
.add_systems( | ||
Update, | ||
( | ||
layer0_animation, | ||
layer1_animation, | ||
layer2_background, | ||
run_gizmos, | ||
), | ||
) | ||
.run(); | ||
} | ||
|
||
/// A tag that will mark the scene on RenderLayer 0. | ||
#[derive(Component)] | ||
struct Layer0Scene; | ||
|
||
/// A tag that will mark the scene on RenderLayer 1. | ||
#[derive(Component)] | ||
struct Layer1Scene; | ||
|
||
/// A tag that will mark the scene on RenderLayer 2. | ||
#[derive(Component)] | ||
struct Layer2Scene; | ||
|
||
fn setup_animation(mut commands: Commands) { | ||
const LAYER_0: RenderLayers = RenderLayers::layer(0); | ||
const LAYER_1: RenderLayers = RenderLayers::layer(1); | ||
|
||
// This camera can see everything on Layer 1 and Layer 2. | ||
commands.spawn(( | ||
Camera2dBundle { | ||
camera: Camera { | ||
// This camera will render AFTER the blue background camera! | ||
order: 1, | ||
..default() | ||
}, | ||
..default() | ||
}, | ||
LAYER_0.union(&LAYER_1), | ||
)); | ||
|
||
commands.spawn((VelloSceneBundle::default(), Layer0Scene, LAYER_0)); | ||
commands.spawn((VelloSceneBundle::default(), Layer1Scene, LAYER_1)); | ||
} | ||
|
||
fn setup_background(mut commands: Commands) { | ||
const LAYER: RenderLayers = RenderLayers::layer(2); | ||
commands.spawn(( | ||
Camera2dBundle { | ||
camera: Camera { | ||
// Render first | ||
order: -1, | ||
..default() | ||
}, | ||
..default() | ||
}, | ||
LAYER, | ||
)); | ||
commands.spawn((VelloSceneBundle::default(), Layer2Scene, LAYER)); | ||
} | ||
|
||
fn layer0_animation( | ||
mut query_scene: Query<(&mut Transform, &mut VelloScene), With<Layer0Scene>>, | ||
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(0.0, 1.0, -1.0), | ||
Vec3::new(0.0, 1.0, 1.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::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.rotation = Quat::from_rotation_z(-std::f32::consts::TAU * sin_time); | ||
} | ||
|
||
fn layer2_background(mut query_scene: Query<&mut VelloScene, With<Layer2Scene>>) { | ||
let mut scene = query_scene.single_mut(); | ||
*scene = VelloScene::default(); | ||
scene.fill( | ||
peniko::Fill::NonZero, | ||
kurbo::Affine::default(), | ||
peniko::Color::rgb(0.0, 0.0, 1.0), | ||
None, | ||
&kurbo::RoundedRect::new(-200.0, -200.0, 200.0, 200.0, 0.0), | ||
); | ||
} | ||
|
||
fn run_gizmos(mut gizmos: Gizmos) { | ||
gizmos.circle_2d(Vec2::splat(0.0), 20.0, css::RED); | ||
} |
This file contains 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
Oops, something went wrong.