Path: blob/main/examples/stress_tests/many_gradients.rs
9358 views
//! Stress test demonstrating gradient performance improvements.1//!2//! This example creates many UI nodes with gradients to measure the performance3//! impact of pre-converting colors to the target color space on the CPU.45use argh::FromArgs;6use bevy::{7color::palettes::css::*,8diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},9math::ops::sin,10prelude::*,11ui::{12BackgroundGradient, ColorStop, Display, Gradient, InterpolationColorSpace, LinearGradient,13RepeatedGridTrack,14},15window::{PresentMode, WindowResolution},16winit::WinitSettings,17};1819const COLS: usize = 30;2021#[derive(FromArgs, Resource, Debug)]22/// Gradient stress test23struct Args {24/// how many gradients per group (default: 900)25#[argh(option, default = "900")]26gradient_count: usize,2728/// whether to animate gradients by changing colors29#[argh(switch)]30animate: bool,3132/// use sRGB interpolation33#[argh(switch)]34srgb: bool,3536/// use HSL interpolation37#[argh(switch)]38hsl: bool,39}4041fn main() {42let args: Args = argh::from_env();43let total_gradients = args.gradient_count;4445println!("Gradient stress test with {total_gradients} gradients");46println!(47"Color space: {}",48if args.srgb {49"sRGB"50} else if args.hsl {51"HSL"52} else {53"OkLab (default)"54}55);5657App::new()58.add_plugins((59LogDiagnosticsPlugin::default(),60FrameTimeDiagnosticsPlugin::default(),61DefaultPlugins.set(WindowPlugin {62primary_window: Some(Window {63title: "Gradient Stress Test".to_string(),64resolution: WindowResolution::new(1920, 1080).with_scale_factor_override(1.0),65present_mode: PresentMode::AutoNoVsync,66..default()67}),68..default()69}),70))71.insert_resource(WinitSettings::continuous())72.insert_resource(args)73.add_systems(Startup, setup)74.add_systems(Update, animate_gradients)75.run();76}7778fn setup(mut commands: Commands, args: Res<Args>) {79commands.spawn(Camera2d);8081let rows_to_spawn = args.gradient_count.div_ceil(COLS);8283// Create a grid of gradients84commands85.spawn(Node {86width: percent(100),87height: percent(100),88display: Display::Grid,89grid_template_columns: RepeatedGridTrack::flex(COLS as u16, 1.0),90grid_template_rows: RepeatedGridTrack::flex(rows_to_spawn as u16, 1.0),91..default()92})93.with_children(|parent| {94for i in 0..args.gradient_count {95let angle = (i as f32 * 10.0) % 360.0;9697let mut gradient = LinearGradient::new(98angle,99vec![100ColorStop::new(RED, percent(0)),101ColorStop::new(BLUE, percent(100)),102ColorStop::new(GREEN, percent(20)),103ColorStop::new(YELLOW, percent(40)),104ColorStop::new(ORANGE, percent(60)),105ColorStop::new(LIME, percent(80)),106ColorStop::new(DARK_CYAN, percent(90)),107],108);109110gradient.color_space = if args.srgb {111InterpolationColorSpace::Srgba112} else if args.hsl {113InterpolationColorSpace::Hsla114} else {115InterpolationColorSpace::Oklaba116};117118parent.spawn((119Node {120width: percent(100),121height: percent(100),122..default()123},124BackgroundGradient(vec![Gradient::Linear(gradient)]),125GradientNode { index: i },126));127}128});129}130131#[derive(Component)]132struct GradientNode {133index: usize,134}135136fn animate_gradients(137mut gradients: Query<(&mut BackgroundGradient, &GradientNode)>,138args: Res<Args>,139time: Res<Time>,140) {141if !args.animate {142return;143}144145let t = time.elapsed_secs();146147for (mut bg_gradient, node) in &mut gradients {148let offset = node.index as f32 * 0.01;149let hue_shift = sin(t + offset) * 0.5 + 0.5;150151if let Some(Gradient::Linear(gradient)) = bg_gradient.0.get_mut(0) {152let color1 = Color::hsl(hue_shift * 360.0, 1.0, 0.5);153let color2 = Color::hsl((hue_shift + 0.3) * 360.0 % 360.0, 1.0, 0.5);154155gradient.stops = vec![156ColorStop::new(color1, percent(0)),157ColorStop::new(color2, percent(100)),158ColorStop::new(159Color::hsl((hue_shift + 0.1) * 360.0 % 360.0, 1.0, 0.5),160percent(20),161),162ColorStop::new(163Color::hsl((hue_shift + 0.15) * 360.0 % 360.0, 1.0, 0.5),164percent(40),165),166ColorStop::new(167Color::hsl((hue_shift + 0.2) * 360.0 % 360.0, 1.0, 0.5),168percent(60),169),170ColorStop::new(171Color::hsl((hue_shift + 0.25) * 360.0 % 360.0, 1.0, 0.5),172percent(80),173),174ColorStop::new(175Color::hsl((hue_shift + 0.28) * 360.0 % 360.0, 1.0, 0.5),176percent(90),177),178];179}180}181}182183184