Path: blob/main/examples/stress_tests/many_gradients.rs
6592 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::{UpdateMode, 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 {72focused_mode: UpdateMode::Continuous,73unfocused_mode: UpdateMode::Continuous,74})75.insert_resource(args)76.add_systems(Startup, setup)77.add_systems(Update, animate_gradients)78.run();79}8081fn setup(mut commands: Commands, args: Res<Args>) {82commands.spawn(Camera2d);8384let rows_to_spawn = args.gradient_count.div_ceil(COLS);8586// Create a grid of gradients87commands88.spawn(Node {89width: percent(100),90height: percent(100),91display: Display::Grid,92grid_template_columns: RepeatedGridTrack::flex(COLS as u16, 1.0),93grid_template_rows: RepeatedGridTrack::flex(rows_to_spawn as u16, 1.0),94..default()95})96.with_children(|parent| {97for i in 0..args.gradient_count {98let angle = (i as f32 * 10.0) % 360.0;99100let mut gradient = LinearGradient::new(101angle,102vec![103ColorStop::new(RED, percent(0)),104ColorStop::new(BLUE, percent(100)),105ColorStop::new(GREEN, percent(20)),106ColorStop::new(YELLOW, percent(40)),107ColorStop::new(ORANGE, percent(60)),108ColorStop::new(LIME, percent(80)),109ColorStop::new(DARK_CYAN, percent(90)),110],111);112113gradient.color_space = if args.srgb {114InterpolationColorSpace::Srgba115} else if args.hsl {116InterpolationColorSpace::Hsla117} else {118InterpolationColorSpace::Oklaba119};120121parent.spawn((122Node {123width: percent(100),124height: percent(100),125..default()126},127BackgroundGradient(vec![Gradient::Linear(gradient)]),128GradientNode { index: i },129));130}131});132}133134#[derive(Component)]135struct GradientNode {136index: usize,137}138139fn animate_gradients(140mut gradients: Query<(&mut BackgroundGradient, &GradientNode)>,141args: Res<Args>,142time: Res<Time>,143) {144if !args.animate {145return;146}147148let t = time.elapsed_secs();149150for (mut bg_gradient, node) in &mut gradients {151let offset = node.index as f32 * 0.01;152let hue_shift = sin(t + offset) * 0.5 + 0.5;153154if let Some(Gradient::Linear(gradient)) = bg_gradient.0.get_mut(0) {155let color1 = Color::hsl(hue_shift * 360.0, 1.0, 0.5);156let color2 = Color::hsl((hue_shift + 0.3) * 360.0 % 360.0, 1.0, 0.5);157158gradient.stops = vec![159ColorStop::new(color1, percent(0)),160ColorStop::new(color2, percent(100)),161ColorStop::new(162Color::hsl((hue_shift + 0.1) * 360.0 % 360.0, 1.0, 0.5),163percent(20),164),165ColorStop::new(166Color::hsl((hue_shift + 0.15) * 360.0 % 360.0, 1.0, 0.5),167percent(40),168),169ColorStop::new(170Color::hsl((hue_shift + 0.2) * 360.0 % 360.0, 1.0, 0.5),171percent(60),172),173ColorStop::new(174Color::hsl((hue_shift + 0.25) * 360.0 % 360.0, 1.0, 0.5),175percent(80),176),177ColorStop::new(178Color::hsl((hue_shift + 0.28) * 360.0 % 360.0, 1.0, 0.5),179percent(90),180),181];182}183}184}185186187