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

Specular from area lights is disproportionately bright #13327

Open
DGriffin91 opened this issue May 11, 2024 · 2 comments
Open

Specular from area lights is disproportionately bright #13327

DGriffin91 opened this issue May 11, 2024 · 2 comments
Labels
A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior

Comments

@DGriffin91
Copy link
Contributor

DGriffin91 commented May 11, 2024

Bevy version Main dcb8a13, 0.13

This isn't a new issue. Not sure how far it goes back, or if there's exists a previous version without it.

Specular reflections from spot/point area lights are disproportionately bright relative to the diffuse response. This often results in extremely bright specular reflections given sufficiently large area lights.

image
This image also displays other specular-related issues in bevy that are not relevant to this issue, let's keep this issue focused, please refer to the blender comparison images below.

Test setup: I disabled Tonemapping in both blender and bevy. I visually matched the light brightness using just diffuse. The diffuse falloff in bevy doesn't exactly match blender, but it's close. In blender I'm rendering using Cycles with direct light only (no GI).

I apologize in advance for the amount of comparison images needed. Note that bevy 0 radius is very similar to blender 0 radius across the board, and bevy 1 radius diffuse is similar to blender 1 radius diffuse (though blender wraps around a bit more here). But bevy 1 radius specular is dramatically brighter than blender 1 radius specular.

Bevy 0 radius, diffuse only:
bevy_0r_diff

Blender 0 radius, diffuse only:
blender_0r_diff

Bevy 0 radius, specular only:
bevy_0r_spec

Blender 0 radius, specular only:
blender_0r_spec

Bevy 0 radius, both specular and diffuse:
bevy_0r

Blender 0 radius, both specular and diffuse:
blender_0r

Bevy 1 radius, diffuse only:
bevy_1r_diff

Blender 1 radius, diffuse only:
blender_1r_diff

Bevy 1 radius, specular only:
bevy_1r_spec

Blender 1 radius, specular only:
blender_1r_spec

Bevy 1 radius, both specular and diffuse:
bevy_1r

Blender 1 radius, both specular and diffuse:
blender_1r

Bevy 1 radius, both specular and diffuse, sharp:
bevy_1r_sharp

Blender 1 radius, both specular and diffuse, sharp:
blender_1r_sharp

Blender Test Scene (Blender 4.1): bevy_spec_ref.zip
Bevy test scene (Bevy Main dcb8a13):

fn main() {
    App::new()
        .insert_resource(ClearColor(Color::BLACK))
        .insert_resource(AmbientLight::NONE)
        .add_plugins(DefaultPlugins)
        .add_systems(Startup, setup)
        .add_systems(Update, screenshot_on_spacebar)
        .run();
}
fn setup(
    mut commands: Commands,
    mut meshes: ResMut<Assets<Mesh>>,
    mut materials: ResMut<Assets<StandardMaterial>>,
) {
    let sphere_mesh = meshes.add(Sphere::new(1.0).mesh().uv(128, 64));
    let surface_material = materials.add(StandardMaterial {
        // Set RGB to 0 to disable diffuse, otherwise use 0.5
        base_color: Color::linear_rgba(0.5, 0.5, 0.5, 1.0),
        // Set reflectance to 0 to disable specular, otherwise use 0.5
        reflectance: 0.5,
        perceptual_roughness: 0.5, // use 0.089 or 0.5
        ..default()
    });
    commands.spawn(PbrBundle {
        mesh: meshes.add(Plane3d::default().mesh().size(100.0, 100.0)),
        material: surface_material.clone(),
        ..default()
    });
    commands.spawn(PbrBundle {
        transform: Transform::from_xyz(-2.5, 1.0, 3.0),
        mesh: sphere_mesh.clone(),
        material: surface_material.clone(),
        ..default()
    });
    commands.spawn(PbrBundle {
        transform: Transform::from_xyz(0.0, 2.5, 3.0),
        mesh: sphere_mesh.clone(),
        material: surface_material.clone(),
        ..default()
    });
    commands.spawn(PointLightBundle {
        point_light: PointLight {
            intensity: 80000.0,
            radius: 1.0,
            ..default()
        },
        transform: Transform::from_xyz(0.0, 1.0, 0.0),
        ..default()
    });
    commands.spawn(Camera3dBundle {
        projection: Projection::Perspective(PerspectiveProjection {
            fov: 45.2f32.to_radians(),
            ..default()
        }),
        tonemapping: Tonemapping::None,
        transform: Transform::from_xyz(0.0, 1.0, 7.0).looking_at(Vec3::ZERO, Vec3::Y),
        ..default()
    });
}
fn screenshot_on_spacebar(
    input: Res<ButtonInput<KeyCode>>,
    main_window: Query<Entity, With<PrimaryWindow>>,
    mut screenshot_manager: ResMut<ScreenshotManager>,
    mut counter: Local<u32>,
) {
    if input.just_pressed(KeyCode::Space) {
        let path = format!("./screenshot-{}.png", *counter);
        *counter += 1;
        screenshot_manager
            .save_screenshot_to_disk(main_window.single(), path)
            .unwrap();
    }
}
@DGriffin91 DGriffin91 added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels May 11, 2024
@IceSentry IceSentry added A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior and removed C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels May 11, 2024
@geckoxx
Copy link
Contributor

geckoxx commented May 18, 2024

You mentioned a "Soft Falloff" Settung in Blender in #13318. Is it enabled in the comparison images?

@DGriffin91
Copy link
Contributor Author

@geckoxx It is not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior
Projects
None yet
Development

No branches or pull requests

3 participants