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

[Merged by Bors] - Spotlights #4715

Closed
wants to merge 53 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
63b91a8
spotlights
robtfm May 4, 2022
fc0a685
update demos
robtfm May 6, 2022
d85cfa2
spotlight cluster culling
robtfm May 10, 2022
19aa631
vary angle in example
robtfm May 10, 2022
61120b5
optimise
robtfm May 10, 2022
f300809
format
robtfm May 10, 2022
c2db39b
use const Vec2 in lights cluster and bounding box when possible (#4602)
mockersf May 6, 2022
2756a8c
spotlight cluster culling
robtfm May 10, 2022
585d101
optimise
robtfm May 10, 2022
c0c5437
format
robtfm May 10, 2022
0cb0544
format
robtfm May 10, 2022
cadcad0
remove debug output
robtfm May 10, 2022
55fb290
fix rebase
robtfm May 10, 2022
91ec7ff
add front_cull test
robtfm May 12, 2022
47fe2ea
shadow maps
robtfm May 13, 2022
8464d7b
fix frustum for culling light entities
robtfm May 13, 2022
87ffc6f
fix spot map offset
robtfm May 14, 2022
6c39cd1
format
robtfm May 14, 2022
5f97f1e
reduce pointlight struct size
robtfm May 16, 2022
2d8a8ed
ci
robtfm May 16, 2022
6f8c9f9
ci?
robtfm May 16, 2022
3de7c9a
clean up maths
robtfm May 17, 2022
f562869
fmt
robtfm May 17, 2022
9357a5e
Merge branch 'main' into spotlight
robtfm May 17, 2022
5f66f57
remove near/far
robtfm May 17, 2022
695bdc5
compress light direction
robtfm Jun 6, 2022
00d3cc2
filament
robtfm Jun 6, 2022
eccfa1b
apply suggestions from code review
robtfm Jun 6, 2022
fb28014
add SpotlightBundle
robtfm Jun 6, 2022
d9b20f4
use xz for direction, revert sign() change
robtfm Jun 7, 2022
e241daa
format
robtfm Jun 7, 2022
109077e
lift condition
robtfm Jun 17, 2022
d3ccb12
fix webgl mipmap sample
robtfm Jun 17, 2022
5968759
remove println
robtfm Jun 21, 2022
b0f651f
Squashed commit of the following:
robtfm Jun 21, 2022
e8e6f1b
reapply to main
robtfm Jun 21, 2022
b1a82d3
Merge branch 'main' into spotlight
robtfm Jun 22, 2022
970a3cc
Merge branch 'main' into spotlight
robtfm Jun 22, 2022
8fd40b2
fmt
robtfm Jun 22, 2022
612813a
fix point light sort order comment
robtfm Jun 25, 2022
d8c362c
add comment on spotlight intensity divisor
robtfm Jun 26, 2022
42cb994
Merge branch 'main' into spotlight
robtfm Jun 26, 2022
68b8ebb
Update Cargo.toml
robtfm Jun 26, 2022
6c8ec1c
build-example-pages
robtfm Jun 26, 2022
723bfeb
spotlight / Spotlight -> spot_light / SpotLight
robtfm Jun 26, 2022
a3809f7
bevy_gltf: Support loading spotlights
superdump Jun 26, 2022
ea909d0
spotlight / Spotlight -> spot_light / SpotLight
robtfm Jun 26, 2022
974fd52
remove unused SPOT_LIGHT flag
robtfm Jun 27, 2022
32a72f2
separate using-facing SpotLight struct
robtfm Jul 8, 2022
8a81014
Merge branch 'main' into spotlight
robtfm Jul 8, 2022
1617119
doc comment
robtfm Jul 8, 2022
45f68ad
ci
robtfm Jul 8, 2022
ab4d91c
ci ci
robtfm Jul 8, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
spotlight / Spotlight -> spot_light / SpotLight
  • Loading branch information
robtfm committed Jun 26, 2022
commit 723bfeb16f06c83904f7754cf2873421e9ad6042
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ path = "examples/3d/spotlight.rs"

robtfm marked this conversation as resolved.
Show resolved Hide resolved
[package.metadata.example.spotlight]
name = "Spotlight"
description = "Illustrates spotlights"
description = "Illustrates spot lights"
category = "3D Rendering"
wasm = true

Expand Down
8 changes: 4 additions & 4 deletions crates/bevy_pbr/src/bundle.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{DirectionalLight, PointLight, SpecializedMaterial, SpotlightAngles, StandardMaterial};
use crate::{DirectionalLight, PointLight, SpecializedMaterial, SpotLightAngles, StandardMaterial};
use bevy_asset::Handle;
use bevy_ecs::{bundle::Bundle, component::Component, reflect::ReflectComponent};
use bevy_reflect::Reflect;
Expand Down Expand Up @@ -75,11 +75,11 @@ pub struct PointLightBundle {
pub visibility: Visibility,
}

/// A component bundle for spotlight entities
/// A component bundle for spot light entities
#[derive(Debug, Bundle, Default)]
pub struct SpotlightBundle {
pub struct SpotLightBundle {
pub point_light: PointLight,
cart marked this conversation as resolved.
Show resolved Hide resolved
pub spotlight_angles: SpotlightAngles,
pub spot_light_angles: SpotLightAngles,
pub visible_entities: VisibleEntities,
pub frustum: Frustum,
pub transform: Transform,
Expand Down
6 changes: 3 additions & 3 deletions crates/bevy_pbr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ pub mod prelude {
alpha::AlphaMode,
bundle::{
DirectionalLightBundle, MaterialMeshBundle, PbrBundle, PointLightBundle,
SpotlightBundle,
SpotLightBundle,
},
light::{AmbientLight, DirectionalLight, PointLight, SpotlightAngles},
light::{AmbientLight, DirectionalLight, PointLight, SpotLightAngles},
material::{Material, MaterialPlugin},
pbr_material::StandardMaterial,
};
Expand Down Expand Up @@ -164,7 +164,7 @@ impl Plugin for PbrPlugin {
)
.add_system_to_stage(
CoreStage::PostUpdate,
update_spotlight_frusta
update_spot_light_frusta
.label(SimulationLightSystems::UpdateLightFrusta)
.after(TransformSystem::TransformPropagate)
.after(SimulationLightSystems::AssignLightsToClusters),
Expand Down
74 changes: 37 additions & 37 deletions crates/bevy_pbr/src/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use bevy_transform::components::GlobalTransform;
use bevy_utils::tracing::warn;

use crate::{
calculate_cluster_factors, spotlight_projection_matrix, spotlight_view_matrix, CubeMapFace,
calculate_cluster_factors, spot_light_projection_matrix, spot_light_view_matrix, CubeMapFace,
CubemapVisibleEntities, ViewClusterBindings, CLUSTERED_FORWARD_STORAGE_BUFFER_COUNT,
CUBE_MAP_FACES, MAX_UNIFORM_BUFFER_POINT_LIGHTS, POINT_LIGHT_NEAR_Z,
};
Expand Down Expand Up @@ -86,19 +86,19 @@ impl Default for PointLightShadowMap {
}
}

/// Angles defining the distance from the spotlight direction to the inner and outer limits
/// Angles defining the distance from the spot light direction to the inner and outer limits
/// of the light's cone of effect.
/// `inner` should be <= `outer`, and `outer` should be < PI / 2.0.
/// PI / 2.0 defines a hemispherical spot light, but shadows become very blocky as the angle
/// approaches this limit.
#[derive(Component, Debug, Clone, Copy, Reflect)]
#[reflect(Component, Default)]
pub struct SpotlightAngles {
pub struct SpotLightAngles {
pub inner: f32,
pub outer: f32,
}

impl Default for SpotlightAngles {
impl Default for SpotLightAngles {
fn default() -> Self {
// a quarter arc attenuating from the centre
Self {
Expand Down Expand Up @@ -440,7 +440,7 @@ pub fn add_clusters(
pub struct VisiblePointLights {
pub(crate) entities: Vec<Entity>,
pub point_light_count: usize,
pub spotlight_count: usize,
pub spot_light_count: usize,
}

impl VisiblePointLights {
Expand Down Expand Up @@ -705,16 +705,16 @@ fn compute_aabb_for_cluster(
}

// Sort lights by
// - point-light vs spot-light, so that we can iterate point lights and spotlights in contiguous blocks in the fragment shader,
// - point-light vs spot-light, so that we can iterate point lights and spot lights in contiguous blocks in the fragment shader,
// - then those with shadows enabled first, so that the index can be used to render at most `point_light_shadow_maps_count`
// point light shadows and `spot_shadow_maps_count` spotlight shadow maps,
// point light shadows and `spot_light_shadow_maps_count` spot light shadow maps,
// - then by entity as a stable key to ensure that a consistent set of lights are chosen if the light count limit is exceeded.
pub(crate) fn point_light_order(
(entity_1, shadows_enabled_1, is_spotlight_1): (&Entity, &bool, &bool),
(entity_2, shadows_enabled_2, is_spotlight_2): (&Entity, &bool, &bool),
(entity_1, shadows_enabled_1, is_spot_light_1): (&Entity, &bool, &bool),
(entity_2, shadows_enabled_2, is_spot_light_2): (&Entity, &bool, &bool),
) -> std::cmp::Ordering {
is_spotlight_1
.cmp(is_spotlight_2) // pointlights before spotlights
is_spot_light_1
.cmp(is_spot_light_2) // pointlights before spot lights
.then_with(|| shadows_enabled_2.cmp(shadows_enabled_1)) // shadow casters before non-casters
.then_with(|| entity_1.cmp(entity_2)) // stable
}
Expand All @@ -727,7 +727,7 @@ pub(crate) struct PointLightAssignmentData {
rotation: Quat,
range: f32,
shadows_enabled: bool,
spotlight_angle: Option<f32>,
spot_light_angle: Option<f32>,
}

#[derive(Default)]
Expand Down Expand Up @@ -765,7 +765,7 @@ pub(crate) fn assign_lights_to_clusters(
Entity,
&GlobalTransform,
&PointLight,
Option<&SpotlightAngles>,
Option<&SpotLightAngles>,
&Visibility,
)>,
mut lights: Local<Vec<PointLightAssignmentData>>,
Expand All @@ -786,14 +786,14 @@ pub(crate) fn assign_lights_to_clusters(
.iter()
.filter(|(.., visibility)| visibility.is_visible)
.map(
|(entity, transform, light, maybe_spotlight_angles, _visibility)| {
|(entity, transform, light, maybe_spot_light_angles, _visibility)| {
PointLightAssignmentData {
entity,
translation: transform.translation,
rotation: transform.rotation,
shadows_enabled: light.shadows_enabled,
range: light.range,
spotlight_angle: maybe_spotlight_angles.map(|angles| angles.outer),
spot_light_angle: maybe_spot_light_angles.map(|angles| angles.outer),
}
},
),
Expand All @@ -811,12 +811,12 @@ pub(crate) fn assign_lights_to_clusters(
(
&light_1.entity,
&light_1.shadows_enabled,
&light_1.spotlight_angle.is_some(),
&light_1.spot_light_angle.is_some(),
),
(
&light_2.entity,
&light_2.shadows_enabled,
&light_2.spotlight_angle.is_some(),
&light_2.spot_light_angle.is_some(),
),
)
});
Expand Down Expand Up @@ -1013,7 +1013,7 @@ pub(crate) fn assign_lights_to_clusters(
for lights in &mut clusters.lights {
lights.entities.clear();
lights.point_light_count = 0;
lights.spotlight_count = 0;
lights.spot_light_count = 0;
}
let cluster_count =
(clusters.dimensions.x * clusters.dimensions.y * clusters.dimensions.z) as usize;
Expand Down Expand Up @@ -1134,7 +1134,7 @@ 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| {
let spot_light_dir_sin_cos = light.spot_light_angle.map(|angle| {
let (angle_sin, angle_cos) = angle.sin_cos();
(
(inverse_view_transform * (light.rotation * Vec3::Z).extend(0.0))
Expand Down Expand Up @@ -1238,10 +1238,10 @@ pub(crate) fn assign_lights_to_clusters(
+ z) as usize;

if let Some((view_light_direction, angle_sin, angle_cos)) =
spotlight_dir_sin_cos
spot_light_dir_sin_cos
{
for x in min_x..=max_x {
// further culling for spotlights
// further culling for spot lights
// 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
Expand All @@ -1267,14 +1267,14 @@ pub(crate) fn assign_lights_to_clusters(
};

// test -- based on https://bartwronski.com/2017/04/13/cull-that-cone/
let spotlight_offset = Vec3::from(
let spot_light_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 spot_light_dist_sq = spot_light_offset.length_squared();
let v1_len = spot_light_offset.dot(view_light_direction);

let distance_closest_point = (angle_cos
* (spotlight_dist_sq - v1_len * v1_len).sqrt())
* (spot_light_dist_sq - v1_len * v1_len).sqrt())
- v1_len * angle_sin;
let angle_cull =
distance_closest_point > cluster_aabb_sphere.radius;
Expand All @@ -1283,9 +1283,9 @@ pub(crate) fn assign_lights_to_clusters(
let back_cull = v1_len < -cluster_aabb_sphere.radius;

if !angle_cull && !front_cull && !back_cull {
// this cluster is affected by the spotlight
// this cluster is affected by the spot light
clusters.lights[cluster_index].entities.push(light.entity);
clusters.lights[cluster_index].spotlight_count += 1;
clusters.lights[cluster_index].spot_light_count += 1;
}
cluster_index += clusters.dimensions.z as usize;
}
Expand Down Expand Up @@ -1444,24 +1444,24 @@ pub fn update_point_light_frusta(
}
}

pub fn update_spotlight_frusta(
pub fn update_spot_light_frusta(
global_lights: Res<GlobalVisiblePointLights>,
mut views: Query<
(
Entity,
&GlobalTransform,
&PointLight,
&SpotlightAngles,
&SpotLightAngles,
&mut Frustum,
),
Or<(
Changed<GlobalTransform>,
Changed<PointLight>,
Changed<SpotlightAngles>,
Changed<SpotLightAngles>,
)>,
>,
) {
for (entity, transform, point_light, spotlight_angles, mut frustum) in views.iter_mut() {
for (entity, transform, point_light, spot_light_angles, mut frustum) in views.iter_mut() {
// The frusta are used for culling meshes to the light for shadow mapping
// so if shadow mapping is disabled for this light, then the frusta are
// not needed.
Expand All @@ -1476,8 +1476,8 @@ pub fn update_spotlight_frusta(
let view_translation = GlobalTransform::from_translation(transform.translation);
let view_backward = transform.back();

let spot_view = spotlight_view_matrix(transform);
let spot_projection = spotlight_projection_matrix(spotlight_angles.outer);
let spot_view = spot_light_view_matrix(transform);
let spot_projection = spot_light_projection_matrix(spot_light_angles.outer);
let view_projection = spot_projection * spot_view.inverse();

*frustum = Frustum::from_view_projection(
Expand All @@ -1498,15 +1498,15 @@ pub fn check_light_mesh_visibility(
&mut CubemapVisibleEntities,
Option<&RenderLayers>,
)>,
mut spotlights: Query<
mut spot_lights: Query<
(
&PointLight,
&GlobalTransform,
&Frustum,
&mut VisibleEntities,
Option<&RenderLayers>,
),
With<SpotlightAngles>,
With<SpotLightAngles>,
>,
mut directional_lights: Query<
(
Expand Down Expand Up @@ -1649,9 +1649,9 @@ pub fn check_light_mesh_visibility(
// to prevent holding unneeded memory
}

// spotlights
// spot lights
if let Ok((point_light, transform, frustum, mut visible_entities, maybe_view_mask)) =
spotlights.get_mut(light_entity)
spot_lights.get_mut(light_entity)
{
visible_entities.entities.clear();

Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_pbr/src/render/clustered_forward.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ let CLUSTER_COUNT_SIZE = 9u;
fn unpack_offset_and_counts(cluster_index: u32) -> vec3<u32> {
#ifdef NO_STORAGE_BUFFERS_SUPPORT
let offset_and_counts = cluster_offsets_and_counts.data[cluster_index >> 2u][cluster_index & ((1u << 2u) - 1u)];
// [ 31 .. 18 | 17 .. 9 | 8 .. 0 ]
// [ offset | point light count | spotlight count ]
// [ 31 .. 18 | 17 .. 9 | 8 .. 0 ]
// [ offset | point light count | spot light count ]
return vec3<u32>(
(offset_and_counts >> (CLUSTER_COUNT_SIZE * 2u)) & ((1u << (32u - (CLUSTER_COUNT_SIZE * 2u))) - 1u),
(offset_and_counts >> CLUSTER_COUNT_SIZE) & ((1u << CLUSTER_COUNT_SIZE) - 1u),
Expand Down
Loading