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