Skip to content

Commit f817af9

Browse files
committed
adds global world and screen scaling
1 parent 98a6c49 commit f817af9

File tree

8 files changed

+158
-13
lines changed

8 files changed

+158
-13
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ This release supports Bevy version 0.16 and has an [MSRV][] of 1.87.
1717

1818
### Added
1919

20+
- Adds `VelloScreenScale` resource to control the scale of screen space rendering.
21+
- Adds `VelloWorldScale` resource to control the scale of world space rendering.
22+
- Adds `NoVelloScale` component to disable scaling for specific entities.
2023
- Adds `VelloScreenSpace` component.
2124
- Adds `VelloScreenSpace` to `bevy_vello::prelude`.
2225
- Adds `calculate_text_content_size` system that calculates the content size of `VelloTextSection` if it has a `ContentSize` component.

src/integrations/lottie/render.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use super::{
1616
use crate::{
1717
SkipEncoding, VelloScreenSpace,
1818
render::{
19-
VelloEntityCountData, VelloView,
19+
NoVelloScale, VelloEntityCountData, VelloScreenScale, VelloView, VelloWorldScale,
2020
prepare::{PrepareRenderInstance, PreparedAffine, PreparedTransform},
2121
},
2222
};
@@ -31,6 +31,7 @@ pub struct ExtractedLottieAsset {
3131
pub theme: Option<Theme>,
3232
pub playhead: f64,
3333
pub screen_space: Option<VelloScreenSpace>,
34+
pub no_scaling: Option<NoVelloScale>,
3435
}
3536

3637
pub fn extract_lottie_assets(
@@ -52,6 +53,7 @@ pub fn extract_lottie_assets(
5253
&ViewVisibility,
5354
&InheritedVisibility,
5455
Option<&VelloScreenSpace>,
56+
Option<&NoVelloScale>,
5557
),
5658
Without<SkipEncoding>,
5759
>,
@@ -76,6 +78,7 @@ pub fn extract_lottie_assets(
7678
view_visibility,
7779
inherited_visibility,
7880
screen_space,
81+
no_scaling,
7982
) in query_vectors.iter()
8083
{
8184
// Skip if visibility conditions are not met
@@ -102,6 +105,7 @@ pub fn extract_lottie_assets(
102105
alpha: asset.alpha,
103106
ui_node: ui_node.cloned(),
104107
screen_space: screen_space.cloned(),
108+
no_scaling: no_scaling.cloned(),
105109
})
106110
.insert(TemporaryRenderEntity);
107111
n_lotties += 1;
@@ -115,13 +119,21 @@ pub fn prepare_asset_affines(
115119
mut commands: Commands,
116120
views: Query<(&ExtractedCamera, &ExtractedView), With<Camera2d>>,
117121
mut render_entities: Query<(Entity, &ExtractedLottieAsset)>,
122+
world_scale: Res<VelloWorldScale>,
123+
screen_scale: Res<VelloScreenScale>,
118124
) {
119125
for (camera, view) in views.iter() {
120126
let viewport_size: UVec2 = camera.physical_viewport_size.unwrap();
121127
for (entity, render_entity) in render_entities.iter_mut() {
122128
// Prepare render data needed for the subsequent render system
123129
let final_transform = render_entity.final_transform();
124-
let affine = render_entity.scene_affine(view, *final_transform, viewport_size);
130+
let affine = render_entity.scene_affine(
131+
view,
132+
*final_transform,
133+
viewport_size,
134+
world_scale.0,
135+
screen_scale.0,
136+
);
125137

126138
commands.entity(entity).insert((affine, final_transform));
127139
}
@@ -142,12 +154,19 @@ impl PrepareRenderInstance for ExtractedLottieAsset {
142154
view: &ExtractedView,
143155
world_transform: GlobalTransform,
144156
viewport_size: UVec2,
157+
world_scale: f32,
158+
screen_scale: f32,
145159
) -> PreparedAffine {
146160
let local_center_matrix = self.asset.local_transform_center.compute_matrix().inverse();
147161

148162
let raw_transform = if let Some(node) = self.ui_node {
149163
let mut model_matrix = world_transform.compute_matrix();
150164

165+
if self.no_scaling.is_none() {
166+
model_matrix.x_axis.x *= screen_scale;
167+
model_matrix.y_axis.y *= screen_scale;
168+
}
169+
151170
let asset_size = Vec2::new(self.asset.width, self.asset.height);
152171

153172
// Make the screen space vector instance sized to fill the
@@ -161,7 +180,13 @@ impl PrepareRenderInstance for ExtractedLottieAsset {
161180
local_center_matrix.w_axis.y *= -1.0;
162181
model_matrix * local_center_matrix
163182
} else if self.screen_space.is_some() {
164-
let model_matrix = world_transform.compute_matrix();
183+
let mut model_matrix = world_transform.compute_matrix();
184+
185+
if self.no_scaling.is_none() {
186+
model_matrix.x_axis.x *= screen_scale;
187+
model_matrix.y_axis.y *= screen_scale;
188+
}
189+
165190
let mut local_center_matrix = local_center_matrix;
166191
local_center_matrix.w_axis.y *= -1.0;
167192
model_matrix * local_center_matrix
@@ -180,6 +205,11 @@ impl PrepareRenderInstance for ExtractedLottieAsset {
180205
let mut model_matrix = world_transform.compute_matrix() * local_matrix;
181206
model_matrix.w_axis.y *= -1.0;
182207

208+
if self.no_scaling.is_none() {
209+
model_matrix.x_axis.x *= world_scale;
210+
model_matrix.y_axis.y *= world_scale;
211+
}
212+
183213
let (projection_mat, view_mat) = {
184214
let mut view_mat = view.world_from_view.compute_matrix();
185215
view_mat.w_axis.y *= -1.0;

src/integrations/svg/render.rs

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use crate::{
1717
VelloScreenSpace,
1818
prelude::*,
1919
render::{
20-
VelloEntityCountData,
20+
NoVelloScale, VelloEntityCountData, VelloScreenScale, VelloWorldScale,
2121
prepare::{PrepareRenderInstance, PreparedAffine, PreparedTransform},
2222
},
2323
};
@@ -30,6 +30,7 @@ pub struct ExtractedVelloSvg {
3030
pub ui_node: Option<ComputedNode>,
3131
pub alpha: f32,
3232
pub screen_space: Option<VelloScreenSpace>,
33+
pub no_scaling: Option<NoVelloScale>,
3334
}
3435

3536
pub fn extract_svg_assets(
@@ -49,6 +50,7 @@ pub fn extract_svg_assets(
4950
&ViewVisibility,
5051
&InheritedVisibility,
5152
Option<&VelloScreenSpace>,
53+
Option<&NoVelloScale>,
5254
),
5355
Without<SkipEncoding>,
5456
>,
@@ -71,6 +73,7 @@ pub fn extract_svg_assets(
7173
view_visibility,
7274
inherited_visibility,
7375
screen_space,
76+
no_scaling,
7477
) in query_vectors.iter()
7578
{
7679
// Skip if visibility conditions are not met
@@ -95,6 +98,7 @@ pub fn extract_svg_assets(
9598
ui_node: ui_node.cloned(),
9699
alpha: asset.alpha,
97100
screen_space: screen_space.cloned(),
101+
no_scaling: no_scaling.cloned(),
98102
})
99103
.insert(TemporaryRenderEntity);
100104
n_svgs += 1;
@@ -108,13 +112,21 @@ pub fn prepare_asset_affines(
108112
mut commands: Commands,
109113
views: Query<(&ExtractedCamera, &ExtractedView), With<Camera2d>>,
110114
mut render_entities: Query<(Entity, &ExtractedVelloSvg)>,
115+
world_scale: Res<VelloWorldScale>,
116+
screen_scale: Res<VelloScreenScale>,
111117
) {
112118
for (camera, view) in views.iter() {
113119
let viewport_size: UVec2 = camera.physical_viewport_size.unwrap();
114120
for (entity, render_entity) in render_entities.iter_mut() {
115121
// Prepare render data needed for the subsequent render system
116122
let final_transform = render_entity.final_transform();
117-
let affine = render_entity.scene_affine(view, *final_transform, viewport_size);
123+
let affine = render_entity.scene_affine(
124+
view,
125+
*final_transform,
126+
viewport_size,
127+
world_scale.0,
128+
screen_scale.0,
129+
);
118130
commands.entity(entity).insert((affine, final_transform));
119131
}
120132
}
@@ -134,6 +146,8 @@ impl PrepareRenderInstance for ExtractedVelloSvg {
134146
view: &ExtractedView,
135147
world_transform: GlobalTransform,
136148
viewport_size: UVec2,
149+
world_scale: f32,
150+
screen_scale: f32,
137151
) -> PreparedAffine {
138152
let local_center_matrix = self.asset.local_transform_center.compute_matrix().inverse();
139153

@@ -149,11 +163,22 @@ impl PrepareRenderInstance for ExtractedVelloSvg {
149163
model_matrix.x_axis.x *= scale_factor;
150164
model_matrix.y_axis.y *= scale_factor;
151165

166+
if self.no_scaling.is_none() {
167+
model_matrix.x_axis.x *= screen_scale;
168+
model_matrix.y_axis.y *= screen_scale;
169+
}
170+
152171
let mut local_center_matrix = local_center_matrix;
153172
local_center_matrix.w_axis.y *= -1.0;
154173
model_matrix * local_center_matrix
155174
} else if self.screen_space.is_some() {
156-
let model_matrix = world_transform.compute_matrix();
175+
let mut model_matrix = world_transform.compute_matrix();
176+
177+
if self.no_scaling.is_none() {
178+
model_matrix.x_axis.x *= screen_scale;
179+
model_matrix.y_axis.y *= screen_scale;
180+
}
181+
157182
let mut local_center_matrix = local_center_matrix;
158183
local_center_matrix.w_axis.y *= -1.0;
159184
model_matrix * local_center_matrix
@@ -172,6 +197,11 @@ impl PrepareRenderInstance for ExtractedVelloSvg {
172197
let mut model_matrix = world_transform.compute_matrix() * local_matrix;
173198
model_matrix.w_axis.y *= -1.0;
174199

200+
if self.no_scaling.is_none() {
201+
model_matrix.x_axis.x *= world_scale;
202+
model_matrix.y_axis.y *= world_scale;
203+
}
204+
175205
let (projection_mat, view_mat) = {
176206
let mut view_mat = view.world_from_view.compute_matrix();
177207
view_mat.w_axis.y *= -1.0;

src/integrations/text/render.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ use vello::kurbo::Affine;
1212
use super::{VelloFont, VelloTextAnchor, VelloTextSection};
1313
use crate::{
1414
VelloScreenSpace,
15-
render::{SkipEncoding, VelloEntityCountData, VelloView, prepare::PreparedAffine},
15+
render::{
16+
NoVelloScale, SkipEncoding, VelloEntityCountData, VelloScreenScale, VelloView,
17+
VelloWorldScale, prepare::PreparedAffine,
18+
},
1619
};
1720

1821
#[derive(Component, Clone)]
@@ -22,6 +25,7 @@ pub struct ExtractedVelloText {
2225
pub transform: GlobalTransform,
2326
pub ui_node: Option<ComputedNode>,
2427
pub screen_space: Option<VelloScreenSpace>,
28+
pub no_scaling: Option<NoVelloScale>,
2529
}
2630

2731
pub fn extract_text(
@@ -41,6 +45,7 @@ pub fn extract_text(
4145
Option<&RenderLayers>,
4246
Option<&ComputedNode>,
4347
Option<&VelloScreenSpace>,
48+
Option<&NoVelloScale>,
4449
),
4550
Without<SkipEncoding>,
4651
>,
@@ -63,6 +68,7 @@ pub fn extract_text(
6368
render_layers,
6469
ui_node,
6570
screen_space,
71+
no_scaling,
6672
) in query_scenes.iter()
6773
{
6874
// Skip if visibility conditions are not met
@@ -86,6 +92,7 @@ pub fn extract_text(
8692
transform: *transform,
8793
ui_node: ui_node.cloned(),
8894
screen_space: screen_space.cloned(),
95+
no_scaling: no_scaling.cloned(),
8996
})
9097
.insert(TemporaryRenderEntity);
9198
n_texts += 1;
@@ -99,6 +106,8 @@ pub fn prepare_text_affines(
99106
mut commands: Commands,
100107
views: Query<(&ExtractedCamera, &ExtractedView), (With<Camera2d>, With<VelloView>)>,
101108
render_entities: Query<(Entity, &ExtractedVelloText)>,
109+
world_scale: Res<VelloWorldScale>,
110+
screen_scale: Res<VelloScreenScale>,
102111
) {
103112
for (camera, view) in views.iter() {
104113
let size_pixels: UVec2 = camera.physical_viewport_size.unwrap();
@@ -118,8 +127,17 @@ pub fn prepare_text_affines(
118127

119128
let raw_transform =
120129
if render_entity.ui_node.is_some() || render_entity.screen_space.is_some() {
130+
if render_entity.no_scaling.is_none() {
131+
model_matrix.x_axis.x *= screen_scale.0;
132+
model_matrix.y_axis.y *= screen_scale.0;
133+
}
121134
model_matrix
122135
} else {
136+
if render_entity.no_scaling.is_none() {
137+
model_matrix.x_axis.x *= world_scale.0;
138+
model_matrix.y_axis.y *= world_scale.0;
139+
}
140+
123141
model_matrix.w_axis.y *= -1.0;
124142

125143
let (projection_mat, view_mat) = {

src/render/extract.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use bevy::{
66
},
77
};
88

9-
use super::{VelloEntityCountData, VelloFrameProfileData};
10-
use crate::{VelloScreenSpace, prelude::*};
9+
use super::{NoVelloScale, VelloEntityCountData, VelloFrameProfileData};
10+
use crate::prelude::*;
1111

1212
#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)]
1313
pub enum VelloExtractStep {
@@ -23,6 +23,7 @@ pub struct ExtractedVelloScene {
2323
pub transform: GlobalTransform,
2424
pub ui_node: Option<ComputedNode>,
2525
pub screen_space: Option<VelloScreenSpace>,
26+
pub no_scaling: Option<NoVelloScale>,
2627
}
2728

2829
pub fn extract_scenes(
@@ -41,6 +42,7 @@ pub fn extract_scenes(
4142
Option<&ComputedNode>,
4243
Option<&RenderLayers>,
4344
Option<&VelloScreenSpace>,
45+
Option<&NoVelloScale>,
4446
),
4547
Without<SkipEncoding>,
4648
>,
@@ -61,6 +63,7 @@ pub fn extract_scenes(
6163
ui_node,
6264
render_layers,
6365
screen_space,
66+
no_scaling,
6467
) in query_scenes.iter()
6568
{
6669
// Skip if visibility conditions are not met
@@ -79,6 +82,7 @@ pub fn extract_scenes(
7982
scene: scene.clone(),
8083
ui_node: ui_node.cloned(),
8184
screen_space: screen_space.cloned(),
85+
no_scaling: no_scaling.cloned(),
8286
})
8387
.insert(TemporaryRenderEntity);
8488
n_scenes += 1;

src/render/mod.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,45 @@ pub const SSRT_SHADER_HANDLE: Handle<Shader> = weak_handle!("e7235b72-1181-4e18-
3535
#[derive(Component, Debug, Clone, Copy, ExtractComponent)]
3636
pub struct VelloView;
3737

38+
/// A resource that holds the scale factor for Vello world coordinates.
39+
#[derive(Resource, Clone)]
40+
pub struct VelloWorldScale(pub f32);
41+
42+
impl Default for VelloWorldScale {
43+
fn default() -> Self {
44+
Self(1.0)
45+
}
46+
}
47+
48+
impl ExtractResource for VelloWorldScale {
49+
type Source = VelloWorldScale;
50+
51+
fn extract_resource(source: &Self::Source) -> Self {
52+
source.clone()
53+
}
54+
}
55+
56+
/// A resource that holds the scale factor for Vello screen coordinates.
57+
#[derive(Resource, Clone)]
58+
pub struct VelloScreenScale(pub f32);
59+
60+
impl Default for VelloScreenScale {
61+
fn default() -> Self {
62+
Self(1.0)
63+
}
64+
}
65+
66+
impl ExtractResource for VelloScreenScale {
67+
type Source = VelloScreenScale;
68+
69+
fn extract_resource(source: &Self::Source) -> Self {
70+
source.clone()
71+
}
72+
}
73+
74+
#[derive(Component, Debug, Clone)]
75+
pub struct NoVelloScale;
76+
3877
/// A canvas material, with a shader that samples a texture with view-independent UV coordinates.
3978
#[derive(AsBindGroup, TypePath, Asset, Clone)]
4079
pub struct VelloCanvasMaterial {

0 commit comments

Comments
 (0)