Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Colored lightning of colored Mesh2d seems wrong #32

Open
victorb opened this issue Sep 5, 2024 · 2 comments
Open

Colored lightning of colored Mesh2d seems wrong #32

victorb opened this issue Sep 5, 2024 · 2 comments
Labels

Comments

@victorb
Copy link

victorb commented Sep 5, 2024

With ambient brightness 1.0:

image

With ambient brightness ~0.0:

image

Example code:

use bevy::input::common_conditions::input_just_pressed;
use bevy::prelude::*;
use bevy::sprite::MaterialMesh2dBundle;
use bevy_light_2d::prelude::*;

fn main() {
    App::new()
        .insert_resource(GlobalBrightness::default())
        .add_plugins((DefaultPlugins, Light2dPlugin))
        .add_systems(Startup, setup)
        .add_systems(Update, update_brightness)
        .add_systems(
            Update,
            (reset, setup)
                .chain()
                .run_if(input_just_pressed(KeyCode::KeyR)),
        )
        .run();
}

#[derive(Resource)]
struct GlobalBrightness {
    value: f32,
    transition_timer: Timer,
    transition_direction: f32,
}

impl Default for GlobalBrightness {
    fn default() -> Self {
        Self {
            value: 1.0,
            transition_timer: Timer::from_seconds(3.0, TimerMode::Repeating),
            transition_direction: -1.0,
        }
    }
}

fn reset(query: Query<Entity, Without<Window>>, mut commands: Commands) {
    println!("Reset");
    for entity in query.iter() {
        commands.entity(entity).despawn_recursive();
    }
}

fn setup(
    brightness: Res<GlobalBrightness>,
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<ColorMaterial>>,
) {
    println!("Setup");
    for i in 0..20 {
        let pos_x = -500.0 + (i as f32 * 50.0);
        let pos_y = 50.0;
        commands.spawn((MaterialMesh2dBundle {
            mesh: meshes.add(Circle::new(16.0)).into(),
            material: materials.add(Color::from(bevy::color::palettes::css::BLUE)),
            transform: Transform::from_translation(Vec3::ZERO.with_x(pos_x).with_y(pos_y)),
            ..default()
        },));
    }

    commands.spawn((
        Camera2dBundle {
            camera: Camera {
                hdr: true,
                ..Default::default()
            },
            ..Default::default()
        },
        bevy_light_2d::light::AmbientLight2d {
            brightness: brightness.value,
            ..default()
        },
    ));

    for i in 0..20 {
        let pos_x = -500.0 + (i as f32 * 50.0);
        let pos_y = 0.0;
        commands.spawn((MaterialMesh2dBundle {
            mesh: meshes.add(Circle::new(16.0)).into(),
            material: materials.add(Color::from(bevy::color::palettes::css::GREEN)),
            transform: Transform::from_translation(Vec3::ZERO.with_x(pos_x).with_y(pos_y)),
            ..default()
        },));
    }

    // Weak light
    commands.spawn((PointLight2dBundle {
        transform: Transform::from_xyz(-200.0, 0.0, 0.0),
        point_light: PointLight2d {
            color: Color::srgba(1.0, 0.0, 0.0, 1.0),
            intensity: 5.0,
            radius: 100.0,
            ..default()
        },
        ..default()
    },));

    // Medium light
    commands.spawn((PointLight2dBundle {
        transform: Transform::from_xyz(0.0, 0.0, 0.0),
        point_light: PointLight2d {
            color: Color::srgba(0.0, 1.0, 0.0, 1.0),
            intensity: 25.0,
            radius: 100.0,
            ..default()
        },
        ..default()
    },));

    // Strong light
    commands.spawn((PointLight2dBundle {
        transform: Transform::from_xyz(200.0, 0.0, 0.0),
        point_light: PointLight2d {
            color: Color::srgba(0.0, 0.0, 1.0, 1.0),
            intensity: 50.0,
            radius: 100.0,
            ..default()
        },
        ..default()
    },));

    commands.spawn(
        TextBundle::from_section("", TextStyle::default()).with_style(Style {
            position_type: PositionType::Absolute,
            top: Val::Px(10.0),
            left: Val::Px(10.0),
            ..default()
        }),
    );

    for i in 0..20 {
        let pos_x = -500.0 + (i as f32 * 50.0);
        let pos_y = -50.0;
        commands.spawn((MaterialMesh2dBundle {
            mesh: meshes.add(Circle::new(16.0)).into(),
            material: materials.add(Color::from(bevy::color::palettes::css::RED)),
            transform: Transform::from_translation(Vec3::ZERO.with_x(pos_x).with_y(pos_y)),
            ..default()
        },));
    }
}

fn update_brightness(
    time: Res<Time>,
    mut brightness: ResMut<GlobalBrightness>,
    mut ambient_query: Query<&mut bevy_light_2d::light::AmbientLight2d>,
    mut text: Query<&mut Text>,
) {
    let mut ambient_light = ambient_query
        .get_single_mut()
        .expect("Expected exactly 1 AmbientLight2d");

    brightness.transition_timer.tick(time.delta());
    if brightness.transition_timer.just_finished() {
        brightness.transition_direction *= -1.0;
    }
    if brightness.transition_timer.elapsed_secs() < 1.0
        || brightness.transition_timer.just_finished()
    {
        brightness.value += brightness.transition_direction * time.delta_seconds();
        brightness.value = brightness.value.clamp(0.0001, 0.9999);
        ambient_light.brightness = brightness.value;
    }

    let mut text_component = text.single_mut();
    text_component.sections[0].value = format!(
        "Ambient Brightness: {:.3}, Until Switch: {:.3}",
        ambient_light.brightness,
        brightness.transition_timer.remaining_secs()
    );
}

Device details:

2024-09-05T15:12:26.104731Z  INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Linux rolling Arch Linux", kernel: "6.6.47-1-lts", cpu: "AMD Ryzen 9 5950X 16-Core Processor", core_count: "16", memory: "125.7 GiB" }
2024-09-05T15:12:26.335365Z  INFO bevy_render::renderer: AdapterInfo { name: "NVIDIA GeForce RTX 3090 Ti", vendor: 4318, device: 8707, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "555.58.02", backend: Vulkan }
2024-09-05T15:12:27.053781Z  INFO winit::platform_impl::linux::x11::window: Guessed window scale factor: 2
@jgayfer
Copy link
Owner

jgayfer commented Sep 5, 2024

What colours are expected when there's no ambient light?

I agree it does look off, but it might also be the nature of using a light the same colour as the sprite. A white light would provide more even illumination.

But probably worth investigating further.

@jgayfer jgayfer added the T-Bug label Sep 5, 2024
@victorb
Copy link
Author

victorb commented Sep 5, 2024

What colours are expected when there's no ambient light?

I guess I'm expecting them to not be 100% black, but some shade of a color.

For comparison, I put together a similar scene in Blender, renderer with EEVEE (Blender's rasterised renderer) and without any ambient light (only three point rights):

blender_rgbs

The row of green circles still look slightly green, even under the blue and red light. Red under blue and blue under red looks almost fully black, but both blue and red under green leaves some hints of the colors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants