Skip to content

Commit

Permalink
format
Browse files Browse the repository at this point in the history
  • Loading branch information
robtfm committed May 10, 2022
1 parent d206512 commit 9384b73
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 43 deletions.
61 changes: 44 additions & 17 deletions crates/bevy_pbr/src/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashSet;

use bevy_asset::Assets;
use bevy_ecs::prelude::*;
use bevy_math::{Mat4, UVec2, UVec3, Vec2, Vec3, Vec3A, Vec3Swizzles, Vec4, Vec4Swizzles, Quat};
use bevy_math::{Mat4, Quat, UVec2, UVec3, Vec2, Vec3, Vec3A, Vec3Swizzles, Vec4, Vec4Swizzles};
use bevy_reflect::prelude::*;
use bevy_render::{
camera::{Camera, CameraProjection, OrthographicProjection},
Expand All @@ -13,7 +13,7 @@ use bevy_render::{
renderer::RenderDevice,
view::{ComputedVisibility, RenderLayers, Visibility, VisibleEntities},
};
use bevy_transform::{components::GlobalTransform};
use bevy_transform::components::GlobalTransform;
use bevy_utils::tracing::warn;
use bevy_window::Windows;

Expand Down Expand Up @@ -972,11 +972,11 @@ pub(crate) fn assign_lights_to_clusters(
for lights in clusters.lights.iter_mut() {
lights.entities.clear();
}
let cluster_count = (clusters.dimensions.x * clusters.dimensions.y * clusters.dimensions.z) as usize;
clusters.lights.resize_with(
cluster_count,
VisiblePointLights::default,
);
let cluster_count =
(clusters.dimensions.x * clusters.dimensions.y * clusters.dimensions.z) as usize;
clusters
.lights
.resize_with(cluster_count, VisiblePointLights::default);

// initialize empty cluster bounding spheres
cluster_aabb_spheres.clear();
Expand Down Expand Up @@ -1091,7 +1091,14 @@ pub(crate) fn assign_lights_to_clusters(
center: Vec3A::from(inverse_view_transform * light_sphere.center.extend(1.0)),
radius: light_sphere.radius,
};
let spotlight_dir_sin_cos = light.spotlight_angle.map(|angle| ((inverse_view_transform * (light.rotation * Vec3::Z).extend(0.0)).truncate(), angle.sin(), angle.cos()));
let spotlight_dir_sin_cos = light.spotlight_angle.map(|angle| {
(
(inverse_view_transform * (light.rotation * Vec3::Z).extend(0.0))
.truncate(),
angle.sin(),
angle.cos(),
)
});
let light_center_clip =
camera.projection_matrix * view_light_sphere.center.extend(1.0);
let light_center_ndc = light_center_clip.xyz() / light_center_clip.w;
Expand Down Expand Up @@ -1188,26 +1195,46 @@ pub(crate) fn assign_lights_to_clusters(

for x in min_x..=max_x {
// further culling for spotlights
if let Some((view_light_direction, angle_sin, angle_cos)) = spotlight_dir_sin_cos {
if let Some((view_light_direction, angle_sin, angle_cos)) =
spotlight_dir_sin_cos
{
// get or initialize cluster bounding sphere
let cluster_aabb_sphere = &mut cluster_aabb_spheres[cluster_index];
let cluster_aabb_sphere = if let Some(sphere) = cluster_aabb_sphere {
let cluster_aabb_sphere = if let Some(sphere) = cluster_aabb_sphere
{
&*sphere
} else {
let aabb = compute_aabb_for_cluster(first_slice_depth, far_z, clusters.tile_size.as_vec2(), screen_size.as_vec2(), inverse_projection, is_orthographic, clusters.dimensions, UVec3::new(x, y, z));
let sphere = Sphere { center: aabb.center, radius: aabb.half_extents.length() };
let aabb = compute_aabb_for_cluster(
first_slice_depth,
far_z,
clusters.tile_size.as_vec2(),
screen_size.as_vec2(),
inverse_projection,
is_orthographic,
clusters.dimensions,
UVec3::new(x, y, z),
);
let sphere = Sphere {
center: aabb.center,
radius: aabb.half_extents.length(),
};
*cluster_aabb_sphere = Some(sphere);
cluster_aabb_sphere.as_ref().unwrap()
};

// test -- based on https://bartwronski.com/2017/04/13/cull-that-cone/
// we omit the front_cull test as we have already used point light sphere / plane testing to bound the tested clusters
let spotlight_offset = Vec3::from(view_light_sphere.center - cluster_aabb_sphere.center);
let spotlight_offset = Vec3::from(
view_light_sphere.center - cluster_aabb_sphere.center,
);
let spotlight_dist_sq = spotlight_offset.length_squared();
let v1_len = spotlight_offset.dot(view_light_direction);

let distance_closest_point = (angle_cos * (spotlight_dist_sq - v1_len * v1_len).sqrt()) - v1_len * angle_sin;
let angle_cull = distance_closest_point > cluster_aabb_sphere.radius;
let distance_closest_point = (angle_cos
* (spotlight_dist_sq - v1_len * v1_len).sqrt())
- v1_len * angle_sin;
let angle_cull =
distance_closest_point > cluster_aabb_sphere.radius;

let back_cull = v1_len < -cluster_aabb_sphere.radius;

Expand All @@ -1219,7 +1246,7 @@ pub(crate) fn assign_lights_to_clusters(
// all clusters within range are affected by point lights
clusters.lights[cluster_index].entities.push(light.entity);
}

cluster_index += clusters.dimensions.z as usize;
}
}
Expand Down
6 changes: 2 additions & 4 deletions crates/bevy_pbr/src/render/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ pub fn extract_lights(
shadow_normal_bias: point_light.shadow_normal_bias
* point_light_texel_size
* std::f32::consts::SQRT_2,
spotlight_angles: point_light.spotlight_angles
spotlight_angles: point_light.spotlight_angles,
},
render_cubemap_visible_entities,
),
Expand Down Expand Up @@ -734,9 +734,7 @@ pub fn prepare_lights(
}

let (spot_dir, spot_angle_inner, spot_angle_outer) = match light.spotlight_angles {
Some((inner, outer)) => {
(light.transform.rotation * Vec3::Z, inner, outer)
},
Some((inner, outer)) => (light.transform.rotation * Vec3::Z, inner, outer),
None => (Vec3::ZERO, 0.0, 0.0),
};

Expand Down
7 changes: 5 additions & 2 deletions examples/3d/lighting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ fn setup(
// green spot light
commands
.spawn_bundle(PointLightBundle {
transform: Transform::from_xyz(-1.0, 2.0, 0.0).looking_at(Vec3::new(-1.0, 0.0, 0.0), Vec3::Z),
transform: Transform::from_xyz(-1.0, 2.0, 0.0)
.looking_at(Vec3::new(-1.0, 0.0, 0.0), Vec3::Z),
point_light: PointLight {
intensity: 1600.0, // lumens - roughly a 100W non-halogen incandescent bulb
color: Color::GREEN,
Expand All @@ -133,7 +134,9 @@ fn setup(
})
.with_children(|builder| {
builder.spawn_bundle(PbrBundle {
transform: Transform::from_rotation(Quat::from_rotation_x(std::f32::consts::PI / 2.0)),
transform: Transform::from_rotation(Quat::from_rotation_x(
std::f32::consts::PI / 2.0,
)),
mesh: meshes.add(Mesh::from(shape::Capsule {
depth: 0.125,
radius: 0.1,
Expand Down
48 changes: 28 additions & 20 deletions examples/3d/spotlight.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use bevy::{prelude::*, pbr::NotShadowCaster};
use bevy::{pbr::NotShadowCaster, prelude::*};

fn main() {
App::new()
Expand Down Expand Up @@ -56,7 +56,10 @@ fn setup(
intensity: 200.0, // lumens
color: Color::WHITE,
shadows_enabled: true,
spotlight_angles: Some((std::f32::consts::PI / 4.0 * 0.85, std::f32::consts::PI / 4.0)),
spotlight_angles: Some((
std::f32::consts::PI / 4.0 * 0.85,
std::f32::consts::PI / 4.0,
)),
..default()
},
..default()
Expand All @@ -74,19 +77,21 @@ fn setup(
}),
..default()
});
builder.spawn_bundle(PbrBundle {
transform: Transform::from_translation(Vec3::Z * -0.1),
mesh: meshes.add(Mesh::from(shape::UVSphere {
radius: 0.1,
builder
.spawn_bundle(PbrBundle {
transform: Transform::from_translation(Vec3::Z * -0.1),
mesh: meshes.add(Mesh::from(shape::UVSphere {
radius: 0.1,
..default()
})),
material: materials.add(StandardMaterial {
base_color: Color::RED,
emissive: Color::rgba_linear(100.0, 0.0, 0.0, 0.0),
..default()
}),
..default()
})),
material: materials.add(StandardMaterial {
base_color: Color::RED,
emissive: Color::rgba_linear(100.0, 0.0, 0.0, 0.0),
..default()
}),
..default()
}).insert(NotShadowCaster);
})
.insert(NotShadowCaster);
});

// camera
Expand All @@ -96,13 +101,16 @@ fn setup(
});
}

fn light_sway(
time: Res<Time>,
mut query: Query<(&mut Transform, &mut PointLight)>,
) {
fn light_sway(time: Res<Time>, mut query: Query<(&mut Transform, &mut PointLight)>) {
for (mut transform, mut light) in query.iter_mut() {
transform.rotation = Quat::from_euler(EulerRot::XYZ, -std::f32::consts::FRAC_PI_2, time.seconds_since_startup().sin() as f32 * 0.75, 0.0);
let angle = ((time.seconds_since_startup() * 1.2).sin() as f32 + 1.0) * std::f32::consts::FRAC_PI_4;
transform.rotation = Quat::from_euler(
EulerRot::XYZ,
-std::f32::consts::FRAC_PI_2,
time.seconds_since_startup().sin() as f32 * 0.75,
0.0,
);
let angle =
((time.seconds_since_startup() * 1.2).sin() as f32 + 1.0) * std::f32::consts::FRAC_PI_4;
light.spotlight_angles = Some((angle * 0.8, angle));
dbg!(angle);
}
Expand Down

0 comments on commit 9384b73

Please sign in to comment.