wip: Added ShadowMesh component
parent
ca65416c73
commit
b13ee649be
|
|
@ -5,7 +5,7 @@ use bevy::render::camera::ScalingMode;
|
|||
use bevy::{input::mouse::MouseMotion, transform::TransformSystem};
|
||||
use bevy_ecs_ldtk::prelude::*;
|
||||
|
||||
use super::darkness::{PointLight2D, SpotLight2D};
|
||||
use super::darkness::{PointLight2D, ShadowMesh, SpotLight2D};
|
||||
|
||||
pub struct GameCameraPlugin;
|
||||
|
||||
|
|
@ -95,6 +95,7 @@ fn camera_setup(mut commands: Commands) {
|
|||
ComputedVisibility::default(),
|
||||
CameraRoomRestraint,
|
||||
PointLight2D { radius: 30.0 },
|
||||
ShadowMesh::default(),
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ impl Plugin for DarknessPlugin {
|
|||
fn build(&self, app: &mut App) {
|
||||
app.register_type::<PointLight2D>()
|
||||
.register_type::<SpotLight2D>()
|
||||
.register_type::<ShadowMesh>()
|
||||
.register_type::<VisibilityBlocker>()
|
||||
.register_asset_reflect::<DarknessMaterial>()
|
||||
.add_plugins(Material2dPlugin::<DarknessMaterial>::default())
|
||||
|
|
@ -86,6 +87,18 @@ pub(crate) struct GpuSpotLight2D {
|
|||
#[reflect(Component)]
|
||||
pub struct VisibilityBlocker;
|
||||
|
||||
#[derive(Reflect, Default, Debug, Clone, Copy)]
|
||||
pub struct ShadowVertex {
|
||||
pub point: Vec2,
|
||||
pub angle: f32,
|
||||
}
|
||||
|
||||
#[derive(Component, Reflect, Default, Debug, Clone)]
|
||||
#[reflect(Component)]
|
||||
pub struct ShadowMesh {
|
||||
pub vertices: Vec<ShadowVertex>,
|
||||
}
|
||||
|
||||
fn add_to_level(
|
||||
mut commands: Commands,
|
||||
mut level_events: EventReader<LevelEvent>,
|
||||
|
|
@ -150,9 +163,9 @@ fn add_to_level(
|
|||
DarknessMeshBundle {
|
||||
transform: Transform::from_xyz(0.0, 0.0, 100.0),
|
||||
mesh: Mesh2dHandle(meshes.add(plane)),
|
||||
material: materials.add(DarknessMaterial::new(
|
||||
Color::rgba(0.0, 0.0, 0.0, 0.75),
|
||||
Some(images.add(Image::new(
|
||||
material: materials.add(DarknessMaterial {
|
||||
color: Color::rgba(0.0, 0.0, 0.0, 0.75),
|
||||
shadowmap_texture: Some(images.add(Image::new(
|
||||
Extent3d {
|
||||
width: width as u32,
|
||||
height: height as u32,
|
||||
|
|
@ -162,7 +175,8 @@ fn add_to_level(
|
|||
vec![0; width * height * 4],
|
||||
bevy::render::render_resource::TextureFormat::R32Float,
|
||||
))),
|
||||
)),
|
||||
..default()
|
||||
}),
|
||||
..default()
|
||||
},
|
||||
));
|
||||
|
|
@ -175,6 +189,7 @@ fn add_to_level(
|
|||
}
|
||||
|
||||
fn prepare_lights(
|
||||
mut shadow_mesh_query: Query<&mut ShadowMesh>,
|
||||
mut materials: ResMut<Assets<DarknessMaterial>>,
|
||||
mut images: ResMut<Assets<Image>>,
|
||||
mut debug_draw: ResMut<DebugLines>,
|
||||
|
|
@ -184,11 +199,11 @@ fn prepare_lights(
|
|||
transform_query: Query<&GlobalTransform>,
|
||||
collider_query: Query<&Collider>,
|
||||
material_query: Query<&Handle<DarknessMaterial>>,
|
||||
point_light_query: Query<(&GlobalTransform, &PointLight2D)>,
|
||||
spot_light_query: Query<(&GlobalTransform, &SpotLight2D)>,
|
||||
point_light_query: Query<(&GlobalTransform, &PointLight2D, Entity)>,
|
||||
spot_light_query: Query<(&GlobalTransform, &SpotLight2D, Entity)>,
|
||||
) {
|
||||
let point_lights: Vec<(_, _)> = point_light_query.iter().collect();
|
||||
let spot_lights: Vec<(_, _)> = spot_light_query.iter().collect();
|
||||
let point_lights: Vec<(_, _, _)> = point_light_query.iter().collect();
|
||||
let spot_lights: Vec<(_, _, _)> = spot_light_query.iter().collect();
|
||||
for handle in &material_query {
|
||||
let material = match materials.get_mut(handle) {
|
||||
Some(material) => material,
|
||||
|
|
@ -207,7 +222,7 @@ fn prepare_lights(
|
|||
point_lights
|
||||
.iter()
|
||||
.enumerate()
|
||||
.for_each(|(i, (transform, light))| {
|
||||
.for_each(|(i, (transform, light, entity))| {
|
||||
let rect = light.aabb();
|
||||
let polygon = get_light_geometry(
|
||||
&rapier_context,
|
||||
|
|
@ -220,10 +235,23 @@ fn prepare_lights(
|
|||
),
|
||||
);
|
||||
|
||||
if let Ok(mut shadow_mesh) = shadow_mesh_query.get_mut(*entity) {
|
||||
shadow_mesh.vertices = polygon
|
||||
.iter()
|
||||
.map(|point| ShadowVertex {
|
||||
point: *point,
|
||||
angle: f32::atan2(
|
||||
point.y - transform.translation().y,
|
||||
point.x - transform.translation().x,
|
||||
),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
if debug_mode.enabled {
|
||||
for (i, arr) in polygon.iter().as_slice().windows(2).enumerate() {
|
||||
let p1 = arr[0];
|
||||
let p2 = arr[1];
|
||||
for i in 0..polygon.len() {
|
||||
let p1 = polygon[i];
|
||||
let p2 = polygon[(i + 1) % polygon.len()];
|
||||
let t1 = i as f32 / polygon.len() as f32;
|
||||
let t2 = (i + 1) as f32 / polygon.len() as f32;
|
||||
let color1 = Color::rgba(1.0 - t1, t1, 0.0, 1.0);
|
||||
|
|
@ -242,6 +270,7 @@ fn prepare_lights(
|
|||
position: transform.translation().truncate(),
|
||||
radius: light.radius,
|
||||
};
|
||||
// TODO: Remove when shadowmapping is done
|
||||
for x in 0..SHADOWMAP_RESOLUTION {
|
||||
let offset = (i * SHADOWMAP_RESOLUTION + x) * 4;
|
||||
let distance = light.radius;
|
||||
|
|
@ -257,7 +286,7 @@ fn prepare_lights(
|
|||
spot_lights
|
||||
.iter()
|
||||
.enumerate()
|
||||
.for_each(|(i, (transform, light))| {
|
||||
.for_each(|(i, (transform, light, entity))| {
|
||||
material.spot_lights[i] = GpuSpotLight2D {
|
||||
position: transform.translation().truncate(),
|
||||
radius: light.radius,
|
||||
|
|
@ -267,6 +296,7 @@ fn prepare_lights(
|
|||
padding2: 0,
|
||||
padding3: 0,
|
||||
};
|
||||
// TODO: Remove when shadowmapping is done
|
||||
for x in 0..SHADOWMAP_RESOLUTION {
|
||||
let offset = ((i + MAX_POINT_LIGHTS) * SHADOWMAP_RESOLUTION + x) * 4;
|
||||
let distance = x as f32 / SHADOWMAP_RESOLUTION as f32 * light.radius;
|
||||
|
|
@ -347,7 +377,6 @@ fn get_light_geometry(
|
|||
.for_each(|ray| polygon.push(aabb.center() + *ray));
|
||||
}
|
||||
|
||||
polygon.push(*polygon.first().unwrap());
|
||||
polygon
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue