Skip to content

Commit

Permalink
Fix point lights not despawning (#19)
Browse files Browse the repository at this point in the history
* Revert "Use custom point light preparation (#17)"

This reverts commit 2ae0336.

* Write "empty" point light to render world

GpuArrayBuffer won't write to the GPU if we have no point lights (an
empty array).

We first tried writing a more custom integration with the GPU, but ended
up running into a very similar problem.

For now lets use GPUArrayBuffer and all it does for us, writing an "empty"
point light to ensure we'll always have a binding.

* Update changelog
  • Loading branch information
jgayfer authored Jul 28, 2024
1 parent e0a5cfe commit faa6a9a
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 118 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- Point lights not despawning (#19).

## [0.2.1] - 2024-07-19

### Fixed
Expand Down
33 changes: 15 additions & 18 deletions src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use bevy::{
prelude::*,
render::{
extract_component::UniformComponentPlugin,
gpu_component_array_buffer::GpuComponentArrayBufferPlugin,
render_graph::{RenderGraphApp, ViewNodeRunner},
render_resource::SpecializedRenderPipelines,
renderer::RenderDevice,
view::{check_visibility, VisibilitySystems},
Render, RenderApp, RenderSet,
},
Expand All @@ -17,12 +17,14 @@ use bevy::{
use crate::{
light::{AmbientLight2d, PointLight2d},
render::{
extract::{extract_ambient_lights, extract_point_lights, ExtractedAmbientLight2d},
extract::{
extract_ambient_lights, extract_point_lights, ExtractedAmbientLight2d,
ExtractedPointLight2d,
},
lighting::{
prepare_lighting_pipelines, LightingNode, LightingPass, LightingPipeline,
LIGHTING_SHADER,
},
prepare::{prepare_point_lights, GpuPointLights},
},
};

Expand All @@ -38,13 +40,16 @@ impl Plugin for Light2dPlugin {
Shader::from_wgsl
);

app.add_plugins(UniformComponentPlugin::<ExtractedAmbientLight2d>::default())
.register_type::<AmbientLight2d>()
.register_type::<PointLight2d>()
.add_systems(
PostUpdate,
check_visibility::<With<PointLight2d>>.in_set(VisibilitySystems::CheckVisibility),
);
app.add_plugins((
UniformComponentPlugin::<ExtractedAmbientLight2d>::default(),
GpuComponentArrayBufferPlugin::<ExtractedPointLight2d>::default(),
))
.register_type::<AmbientLight2d>()
.register_type::<PointLight2d>()
.add_systems(
PostUpdate,
check_visibility::<With<PointLight2d>>.in_set(VisibilitySystems::CheckVisibility),
);

let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
Expand All @@ -60,10 +65,6 @@ impl Plugin for Light2dPlugin {
Render,
prepare_lighting_pipelines.in_set(RenderSet::Prepare),
)
.add_systems(
Render,
prepare_point_lights.in_set(RenderSet::PrepareResources),
)
.add_render_graph_node::<ViewNodeRunner<LightingNode>>(Core2d, LightingPass)
.add_render_graph_edge(Core2d, Node2d::EndMainPass, LightingPass);
}
Expand All @@ -74,9 +75,5 @@ impl Plugin for Light2dPlugin {
};

render_app.init_resource::<LightingPipeline>();

render_app.insert_resource(GpuPointLights::new(
render_app.world().resource::<RenderDevice>(),
));
}
}
12 changes: 11 additions & 1 deletion src/render/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use bevy::{

use crate::light::{AmbientLight2d, PointLight2d};

#[derive(Component, Default, Clone, ShaderType, Copy)]
#[derive(Component, Default, Clone, ShaderType)]
pub struct ExtractedPointLight2d {
pub transform: Vec2,
pub radius: f32,
Expand Down Expand Up @@ -35,6 +35,16 @@ pub fn extract_point_lights(
falloff: point_light.falloff,
});
}

// BufferVec won't write to the GPU if there aren't any point lights.
// For now we can spawn an empty point light to get around this.
commands.spawn(ExtractedPointLight2d {
transform: Vec2::ZERO,
intensity: 0.0,
radius: 0.0,
falloff: 0.0,
color: LinearRgba::BLACK,
});
}

pub fn extract_ambient_lights(
Expand Down
11 changes: 7 additions & 4 deletions src/render/lighting/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ use bevy::render::extract_component::{ComponentUniforms, DynamicUniformIndex};
use bevy::render::render_graph::ViewNode;

use bevy::render::render_resource::{
BindGroupEntries, Operations, PipelineCache, RenderPassColorAttachment, RenderPassDescriptor,
BindGroupEntries, GpuArrayBuffer, Operations, PipelineCache, RenderPassColorAttachment,
RenderPassDescriptor,
};
use bevy::render::renderer::RenderDevice;
use bevy::render::view::{ViewTarget, ViewUniformOffset, ViewUniforms};
use smallvec::{smallvec, SmallVec};

use crate::render::extract::ExtractedAmbientLight2d;
use crate::render::prepare::GpuPointLights;
use crate::render::extract::{ExtractedAmbientLight2d, ExtractedPointLight2d};

use super::{LightingPipeline, LightingPipelineId};

Expand Down Expand Up @@ -58,7 +58,10 @@ impl ViewNode for LightingNode {
return Ok(());
};

let Some(point_light_binding) = world.resource::<GpuPointLights>().binding() else {
let Some(point_light_binding) = world
.resource::<GpuArrayBuffer<ExtractedPointLight2d>>()
.binding()
else {
return Ok(());
};

Expand Down
1 change: 0 additions & 1 deletion src/render/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
pub mod extract;
pub mod lighting;
pub mod prepare;
94 changes: 0 additions & 94 deletions src/render/prepare.rs

This file was deleted.

0 comments on commit faa6a9a

Please sign in to comment.