mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
omni light -> point light
This commit is contained in:
parent
4099ef6aa2
commit
bc769d9641
7 changed files with 43 additions and 45 deletions
|
@ -4,7 +4,7 @@ use bevy::{
|
||||||
ecs::prelude::*,
|
ecs::prelude::*,
|
||||||
input::Input,
|
input::Input,
|
||||||
math::{Quat, Vec3},
|
math::{Quat, Vec3},
|
||||||
pbr2::{OmniLight, OmniLightBundle, PbrBundle, StandardMaterial},
|
pbr2::{PbrBundle, PointLight, PointLightBundle, StandardMaterial},
|
||||||
prelude::{App, Assets, BuildChildren, KeyCode, Transform},
|
prelude::{App, Assets, BuildChildren, KeyCode, Transform},
|
||||||
render2::{
|
render2::{
|
||||||
camera::PerspectiveCameraBundle,
|
camera::PerspectiveCameraBundle,
|
||||||
|
@ -98,10 +98,10 @@ fn setup(
|
||||||
|
|
||||||
// light
|
// light
|
||||||
commands
|
commands
|
||||||
.spawn_bundle(OmniLightBundle {
|
.spawn_bundle(PointLightBundle {
|
||||||
// transform: Transform::from_xyz(5.0, 8.0, 2.0),
|
// transform: Transform::from_xyz(5.0, 8.0, 2.0),
|
||||||
transform: Transform::from_xyz(1.0, 2.0, 0.0),
|
transform: Transform::from_xyz(1.0, 2.0, 0.0),
|
||||||
omni_light: OmniLight {
|
point_light: PointLight {
|
||||||
color: Color::RED,
|
color: Color::RED,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
@ -124,10 +124,10 @@ fn setup(
|
||||||
|
|
||||||
// light
|
// light
|
||||||
commands
|
commands
|
||||||
.spawn_bundle(OmniLightBundle {
|
.spawn_bundle(PointLightBundle {
|
||||||
// transform: Transform::from_xyz(5.0, 8.0, 2.0),
|
// transform: Transform::from_xyz(5.0, 8.0, 2.0),
|
||||||
transform: Transform::from_xyz(-1.0, 2.0, 0.0),
|
transform: Transform::from_xyz(-1.0, 2.0, 0.0),
|
||||||
omni_light: OmniLight {
|
point_light: PointLight {
|
||||||
color: Color::GREEN,
|
color: Color::GREEN,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
@ -150,10 +150,10 @@ fn setup(
|
||||||
|
|
||||||
// light
|
// light
|
||||||
commands
|
commands
|
||||||
.spawn_bundle(OmniLightBundle {
|
.spawn_bundle(PointLightBundle {
|
||||||
// transform: Transform::from_xyz(5.0, 8.0, 2.0),
|
// transform: Transform::from_xyz(5.0, 8.0, 2.0),
|
||||||
transform: Transform::from_xyz(0.0, 4.0, 0.0),
|
transform: Transform::from_xyz(0.0, 4.0, 0.0),
|
||||||
omni_light: OmniLight {
|
point_light: PointLight {
|
||||||
color: Color::BLUE,
|
color: Color::BLUE,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use bevy::{
|
use bevy::{
|
||||||
ecs::prelude::*,
|
ecs::prelude::*,
|
||||||
math::Vec3,
|
math::Vec3,
|
||||||
pbr2::{OmniLight, OmniLightBundle, PbrBundle, StandardMaterial},
|
pbr2::{PbrBundle, PointLight, PointLightBundle, StandardMaterial},
|
||||||
prelude::{App, Assets, Transform},
|
prelude::{App, Assets, Transform},
|
||||||
render2::{
|
render2::{
|
||||||
camera::{OrthographicCameraBundle, OrthographicProjection},
|
camera::{OrthographicCameraBundle, OrthographicProjection},
|
||||||
|
@ -64,9 +64,9 @@ fn setup(
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
// light
|
// light
|
||||||
commands.spawn_bundle(OmniLightBundle {
|
commands.spawn_bundle(PointLightBundle {
|
||||||
transform: Transform::from_translation(Vec3::new(50.0, 50.0, 50.0)),
|
transform: Transform::from_translation(Vec3::new(50.0, 50.0, 50.0)),
|
||||||
omni_light: OmniLight {
|
point_light: PointLight {
|
||||||
intensity: 50000.,
|
intensity: 50000.,
|
||||||
range: 100.,
|
range: 100.,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{OmniLight, StandardMaterial};
|
use crate::{PointLight, StandardMaterial};
|
||||||
use bevy_asset::Handle;
|
use bevy_asset::Handle;
|
||||||
use bevy_ecs::bundle::Bundle;
|
use bevy_ecs::bundle::Bundle;
|
||||||
use bevy_render2::mesh::Mesh;
|
use bevy_render2::mesh::Mesh;
|
||||||
|
@ -25,8 +25,8 @@ impl Default for PbrBundle {
|
||||||
|
|
||||||
/// A component bundle for "light" entities
|
/// A component bundle for "light" entities
|
||||||
#[derive(Debug, Bundle, Default)]
|
#[derive(Debug, Bundle, Default)]
|
||||||
pub struct OmniLightBundle {
|
pub struct PointLightBundle {
|
||||||
pub omni_light: OmniLight,
|
pub point_light: PointLight,
|
||||||
pub transform: Transform,
|
pub transform: Transform,
|
||||||
pub global_transform: GlobalTransform,
|
pub global_transform: GlobalTransform,
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,19 @@ use bevy_ecs::reflect::ReflectComponent;
|
||||||
use bevy_reflect::Reflect;
|
use bevy_reflect::Reflect;
|
||||||
use bevy_render2::color::Color;
|
use bevy_render2::color::Color;
|
||||||
|
|
||||||
/// An omnidirectional light
|
/// A light that emits light in all directions from a central point.
|
||||||
#[derive(Debug, Clone, Copy, Reflect)]
|
#[derive(Debug, Clone, Copy, Reflect)]
|
||||||
#[reflect(Component)]
|
#[reflect(Component)]
|
||||||
pub struct OmniLight {
|
pub struct PointLight {
|
||||||
pub color: Color,
|
pub color: Color,
|
||||||
pub intensity: f32,
|
pub intensity: f32,
|
||||||
pub range: f32,
|
pub range: f32,
|
||||||
pub radius: f32,
|
pub radius: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for OmniLight {
|
impl Default for PointLight {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
OmniLight {
|
PointLight {
|
||||||
color: Color::rgb(1.0, 1.0, 1.0),
|
color: Color::rgb(1.0, 1.0, 1.0),
|
||||||
intensity: 200.0,
|
intensity: 200.0,
|
||||||
range: 20.0,
|
range: 20.0,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::{AmbientLight, ExtractedMeshes, MeshMeta, OmniLight, PbrShaders};
|
use crate::{AmbientLight, ExtractedMeshes, MeshMeta, PbrShaders, PointLight};
|
||||||
use bevy_ecs::{prelude::*, system::SystemState};
|
use bevy_ecs::{prelude::*, system::SystemState};
|
||||||
use bevy_math::{const_vec3, Mat4, Vec3, Vec4};
|
use bevy_math::{const_vec3, Mat4, Vec3, Vec4};
|
||||||
use bevy_render2::{
|
use bevy_render2::{
|
||||||
|
@ -11,7 +11,7 @@ use bevy_render2::{
|
||||||
render_resource::*,
|
render_resource::*,
|
||||||
renderer::{RenderContext, RenderDevice},
|
renderer::{RenderContext, RenderDevice},
|
||||||
texture::*,
|
texture::*,
|
||||||
view::{ExtractedView, ViewUniform, ViewUniformOffset},
|
view::{ExtractedView, ViewUniformOffset},
|
||||||
};
|
};
|
||||||
use bevy_transform::components::GlobalTransform;
|
use bevy_transform::components::GlobalTransform;
|
||||||
use crevice::std140::AsStd140;
|
use crevice::std140::AsStd140;
|
||||||
|
@ -46,17 +46,17 @@ pub struct GpuLight {
|
||||||
#[derive(Copy, Clone, Debug, AsStd140)]
|
#[derive(Copy, Clone, Debug, AsStd140)]
|
||||||
pub struct GpuLights {
|
pub struct GpuLights {
|
||||||
// TODO: this comes first to work around a WGSL alignment issue. We need to solve this issue before releasing the renderer rework
|
// TODO: this comes first to work around a WGSL alignment issue. We need to solve this issue before releasing the renderer rework
|
||||||
lights: [GpuLight; MAX_OMNI_LIGHTS],
|
lights: [GpuLight; MAX_POINT_LIGHTS],
|
||||||
ambient_color: Vec4,
|
ambient_color: Vec4,
|
||||||
len: u32,
|
len: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: this must be kept in sync MAX_OMNI_LIGHTS in pbr.frag
|
// NOTE: this must be kept in sync MAX_POINT_LIGHTS in pbr.frag
|
||||||
pub const MAX_OMNI_LIGHTS: usize = 10;
|
pub const MAX_POINT_LIGHTS: usize = 10;
|
||||||
pub const SHADOW_SIZE: Extent3d = Extent3d {
|
pub const SHADOW_SIZE: Extent3d = Extent3d {
|
||||||
width: 1024,
|
width: 1024,
|
||||||
height: 1024,
|
height: 1024,
|
||||||
depth_or_array_layers: 6 * MAX_OMNI_LIGHTS as u32,
|
depth_or_array_layers: 6 * MAX_POINT_LIGHTS as u32,
|
||||||
};
|
};
|
||||||
pub const SHADOW_FORMAT: TextureFormat = TextureFormat::Depth32Float;
|
pub const SHADOW_FORMAT: TextureFormat = TextureFormat::Depth32Float;
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ impl FromWorld for ShadowShaders {
|
||||||
pub fn extract_lights(
|
pub fn extract_lights(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
ambient_light: Res<AmbientLight>,
|
ambient_light: Res<AmbientLight>,
|
||||||
lights: Query<(Entity, &OmniLight, &GlobalTransform)>,
|
lights: Query<(Entity, &PointLight, &GlobalTransform)>,
|
||||||
) {
|
) {
|
||||||
commands.insert_resource(ExtractedAmbientLight {
|
commands.insert_resource(ExtractedAmbientLight {
|
||||||
color: ambient_light.color,
|
color: ambient_light.color,
|
||||||
|
@ -290,11 +290,11 @@ pub fn prepare_lights(
|
||||||
let mut gpu_lights = GpuLights {
|
let mut gpu_lights = GpuLights {
|
||||||
ambient_color: ambient_color.into(),
|
ambient_color: ambient_color.into(),
|
||||||
len: lights.iter().len() as u32,
|
len: lights.iter().len() as u32,
|
||||||
lights: [GpuLight::default(); MAX_OMNI_LIGHTS],
|
lights: [GpuLight::default(); MAX_POINT_LIGHTS],
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: this should select lights based on relevance to the view instead of the first ones that show up in a query
|
// TODO: this should select lights based on relevance to the view instead of the first ones that show up in a query
|
||||||
for (light_index, light) in lights.iter().enumerate().take(MAX_OMNI_LIGHTS) {
|
for (light_index, light) in lights.iter().enumerate().take(MAX_POINT_LIGHTS) {
|
||||||
let projection =
|
let projection =
|
||||||
Mat4::perspective_rh(std::f32::consts::FRAC_PI_2, 1.0, 0.1, light.range);
|
Mat4::perspective_rh(std::f32::consts::FRAC_PI_2, 1.0, 0.1, light.range);
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ struct StandardMaterial {
|
||||||
flags: u32;
|
flags: u32;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct OmniLight {
|
struct PointLight {
|
||||||
color: vec4<f32>;
|
color: vec4<f32>;
|
||||||
// projection: mat4x4<f32>;
|
// projection: mat4x4<f32>;
|
||||||
position: vec3<f32>;
|
position: vec3<f32>;
|
||||||
|
@ -101,7 +101,7 @@ struct OmniLight {
|
||||||
struct Lights {
|
struct Lights {
|
||||||
// NOTE: this array size must be kept in sync with the constants defined bevy_pbr2/src/render/light.rs
|
// NOTE: this array size must be kept in sync with the constants defined bevy_pbr2/src/render/light.rs
|
||||||
// TODO: this can be removed if we move to storage buffers for light arrays
|
// TODO: this can be removed if we move to storage buffers for light arrays
|
||||||
omni_lights: array<OmniLight, 10>;
|
point_lights: array<PointLight, 10>;
|
||||||
ambient_color: vec4<f32>;
|
ambient_color: vec4<f32>;
|
||||||
num_lights: u32;
|
num_lights: u32;
|
||||||
};
|
};
|
||||||
|
@ -296,8 +296,8 @@ fn reinhard_extended_luminance(color: vec3<f32>, max_white_l: f32) -> vec3<f32>
|
||||||
return change_luminance(color, l_new);
|
return change_luminance(color, l_new);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn omni_light(
|
fn point_light(
|
||||||
world_position: vec3<f32>, light: OmniLight, roughness: f32, NdotV: f32, N: vec3<f32>, V: vec3<f32>,
|
world_position: vec3<f32>, light: PointLight, roughness: f32, NdotV: f32, N: vec3<f32>, V: vec3<f32>,
|
||||||
R: vec3<f32>, F0: vec3<f32>, diffuseColor: vec3<f32>
|
R: vec3<f32>, F0: vec3<f32>, diffuseColor: vec3<f32>
|
||||||
) -> vec3<f32> {
|
) -> vec3<f32> {
|
||||||
let light_to_frag = light.position.xyz - world_position.xyz;
|
let light_to_frag = light.position.xyz - world_position.xyz;
|
||||||
|
@ -349,7 +349,7 @@ fn omni_light(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_shadow(light_id: i32, frag_position: vec4<f32>) -> f32 {
|
fn fetch_shadow(light_id: i32, frag_position: vec4<f32>) -> f32 {
|
||||||
let light = lights.omni_lights[light_id];
|
let light = lights.point_lights[light_id];
|
||||||
|
|
||||||
// because the shadow maps align with the axes and the frustum planes are at 45 degrees
|
// because the shadow maps align with the axes and the frustum planes are at 45 degrees
|
||||||
// we can get the worldspace depth by taking the largest absolute axis
|
// we can get the worldspace depth by taking the largest absolute axis
|
||||||
|
@ -472,8 +472,8 @@ fn fragment(in: FragmentInput) -> [[location(0)]] vec4<f32> {
|
||||||
// accumulate color
|
// accumulate color
|
||||||
var light_accum: vec3<f32> = vec3<f32>(0.0);
|
var light_accum: vec3<f32> = vec3<f32>(0.0);
|
||||||
for (var i: i32 = 0; i < i32(lights.num_lights); i = i + 1) {
|
for (var i: i32 = 0; i < i32(lights.num_lights); i = i + 1) {
|
||||||
let light = lights.omni_lights[i];
|
let light = lights.point_lights[i];
|
||||||
let light_contrib = omni_light(in.world_position.xyz, light, roughness, NdotV, N, V, R, F0, diffuse_color);
|
let light_contrib = point_light(in.world_position.xyz, light, roughness, NdotV, N, V, R, F0, diffuse_color);
|
||||||
let shadow = fetch_shadow(i, in.world_position);
|
let shadow = fetch_shadow(i, in.world_position);
|
||||||
light_accum = light_accum + light_contrib * shadow;
|
light_accum = light_accum + light_contrib * shadow;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,21 +118,19 @@ pub fn prepare_windows(
|
||||||
.or_insert_with(|| render_device.create_swap_chain(surface, &swap_chain_descriptor));
|
.or_insert_with(|| render_device.create_swap_chain(surface, &swap_chain_descriptor));
|
||||||
|
|
||||||
let frame = match swap_chain.get_current_frame() {
|
let frame = match swap_chain.get_current_frame() {
|
||||||
Ok(swap_chain_frame) => {
|
Ok(swap_chain_frame) => swap_chain_frame,
|
||||||
swap_chain_frame
|
|
||||||
},
|
|
||||||
Err(wgpu::SwapChainError::Outdated) => {
|
Err(wgpu::SwapChainError::Outdated) => {
|
||||||
let new_swap_chain = render_device.create_swap_chain(surface, &swap_chain_descriptor);
|
let new_swap_chain =
|
||||||
let frame = new_swap_chain.get_current_frame().expect("Error recreating swap chain");
|
render_device.create_swap_chain(surface, &swap_chain_descriptor);
|
||||||
window_surfaces.swap_chains.insert(
|
let frame = new_swap_chain
|
||||||
window.id,
|
.get_current_frame()
|
||||||
new_swap_chain
|
.expect("Error recreating swap chain");
|
||||||
);
|
window_surfaces
|
||||||
|
.swap_chains
|
||||||
|
.insert(window.id, new_swap_chain);
|
||||||
frame
|
frame
|
||||||
},
|
|
||||||
err => {
|
|
||||||
err.expect("Failed to acquire next swap chain texture!")
|
|
||||||
}
|
}
|
||||||
|
err => err.expect("Failed to acquire next swap chain texture!"),
|
||||||
};
|
};
|
||||||
|
|
||||||
window.swap_chain_frame = Some(TextureView::from(frame));
|
window.swap_chain_frame = Some(TextureView::from(frame));
|
||||||
|
|
Loading…
Reference in a new issue