mirror of
https://github.com/bevyengine/bevy
synced 2024-11-25 14:10:19 +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::*,
|
||||
input::Input,
|
||||
math::{Quat, Vec3},
|
||||
pbr2::{OmniLight, OmniLightBundle, PbrBundle, StandardMaterial},
|
||||
pbr2::{PbrBundle, PointLight, PointLightBundle, StandardMaterial},
|
||||
prelude::{App, Assets, BuildChildren, KeyCode, Transform},
|
||||
render2::{
|
||||
camera::PerspectiveCameraBundle,
|
||||
|
@ -98,10 +98,10 @@ fn setup(
|
|||
|
||||
// light
|
||||
commands
|
||||
.spawn_bundle(OmniLightBundle {
|
||||
.spawn_bundle(PointLightBundle {
|
||||
// transform: Transform::from_xyz(5.0, 8.0, 2.0),
|
||||
transform: Transform::from_xyz(1.0, 2.0, 0.0),
|
||||
omni_light: OmniLight {
|
||||
point_light: PointLight {
|
||||
color: Color::RED,
|
||||
..Default::default()
|
||||
},
|
||||
|
@ -124,10 +124,10 @@ fn setup(
|
|||
|
||||
// light
|
||||
commands
|
||||
.spawn_bundle(OmniLightBundle {
|
||||
.spawn_bundle(PointLightBundle {
|
||||
// transform: Transform::from_xyz(5.0, 8.0, 2.0),
|
||||
transform: Transform::from_xyz(-1.0, 2.0, 0.0),
|
||||
omni_light: OmniLight {
|
||||
point_light: PointLight {
|
||||
color: Color::GREEN,
|
||||
..Default::default()
|
||||
},
|
||||
|
@ -150,10 +150,10 @@ fn setup(
|
|||
|
||||
// light
|
||||
commands
|
||||
.spawn_bundle(OmniLightBundle {
|
||||
.spawn_bundle(PointLightBundle {
|
||||
// transform: Transform::from_xyz(5.0, 8.0, 2.0),
|
||||
transform: Transform::from_xyz(0.0, 4.0, 0.0),
|
||||
omni_light: OmniLight {
|
||||
point_light: PointLight {
|
||||
color: Color::BLUE,
|
||||
..Default::default()
|
||||
},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use bevy::{
|
||||
ecs::prelude::*,
|
||||
math::Vec3,
|
||||
pbr2::{OmniLight, OmniLightBundle, PbrBundle, StandardMaterial},
|
||||
pbr2::{PbrBundle, PointLight, PointLightBundle, StandardMaterial},
|
||||
prelude::{App, Assets, Transform},
|
||||
render2::{
|
||||
camera::{OrthographicCameraBundle, OrthographicProjection},
|
||||
|
@ -64,9 +64,9 @@ fn setup(
|
|||
..Default::default()
|
||||
});
|
||||
// light
|
||||
commands.spawn_bundle(OmniLightBundle {
|
||||
commands.spawn_bundle(PointLightBundle {
|
||||
transform: Transform::from_translation(Vec3::new(50.0, 50.0, 50.0)),
|
||||
omni_light: OmniLight {
|
||||
point_light: PointLight {
|
||||
intensity: 50000.,
|
||||
range: 100.,
|
||||
..Default::default()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{OmniLight, StandardMaterial};
|
||||
use crate::{PointLight, StandardMaterial};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_ecs::bundle::Bundle;
|
||||
use bevy_render2::mesh::Mesh;
|
||||
|
@ -25,8 +25,8 @@ impl Default for PbrBundle {
|
|||
|
||||
/// A component bundle for "light" entities
|
||||
#[derive(Debug, Bundle, Default)]
|
||||
pub struct OmniLightBundle {
|
||||
pub omni_light: OmniLight,
|
||||
pub struct PointLightBundle {
|
||||
pub point_light: PointLight,
|
||||
pub transform: Transform,
|
||||
pub global_transform: GlobalTransform,
|
||||
}
|
||||
|
|
|
@ -2,19 +2,19 @@ use bevy_ecs::reflect::ReflectComponent;
|
|||
use bevy_reflect::Reflect;
|
||||
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)]
|
||||
#[reflect(Component)]
|
||||
pub struct OmniLight {
|
||||
pub struct PointLight {
|
||||
pub color: Color,
|
||||
pub intensity: f32,
|
||||
pub range: f32,
|
||||
pub radius: f32,
|
||||
}
|
||||
|
||||
impl Default for OmniLight {
|
||||
impl Default for PointLight {
|
||||
fn default() -> Self {
|
||||
OmniLight {
|
||||
PointLight {
|
||||
color: Color::rgb(1.0, 1.0, 1.0),
|
||||
intensity: 200.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_math::{const_vec3, Mat4, Vec3, Vec4};
|
||||
use bevy_render2::{
|
||||
|
@ -11,7 +11,7 @@ use bevy_render2::{
|
|||
render_resource::*,
|
||||
renderer::{RenderContext, RenderDevice},
|
||||
texture::*,
|
||||
view::{ExtractedView, ViewUniform, ViewUniformOffset},
|
||||
view::{ExtractedView, ViewUniformOffset},
|
||||
};
|
||||
use bevy_transform::components::GlobalTransform;
|
||||
use crevice::std140::AsStd140;
|
||||
|
@ -46,17 +46,17 @@ pub struct GpuLight {
|
|||
#[derive(Copy, Clone, Debug, AsStd140)]
|
||||
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
|
||||
lights: [GpuLight; MAX_OMNI_LIGHTS],
|
||||
lights: [GpuLight; MAX_POINT_LIGHTS],
|
||||
ambient_color: Vec4,
|
||||
len: u32,
|
||||
}
|
||||
|
||||
// NOTE: this must be kept in sync MAX_OMNI_LIGHTS in pbr.frag
|
||||
pub const MAX_OMNI_LIGHTS: usize = 10;
|
||||
// NOTE: this must be kept in sync MAX_POINT_LIGHTS in pbr.frag
|
||||
pub const MAX_POINT_LIGHTS: usize = 10;
|
||||
pub const SHADOW_SIZE: Extent3d = Extent3d {
|
||||
width: 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;
|
||||
|
||||
|
@ -178,7 +178,7 @@ impl FromWorld for ShadowShaders {
|
|||
pub fn extract_lights(
|
||||
mut commands: Commands,
|
||||
ambient_light: Res<AmbientLight>,
|
||||
lights: Query<(Entity, &OmniLight, &GlobalTransform)>,
|
||||
lights: Query<(Entity, &PointLight, &GlobalTransform)>,
|
||||
) {
|
||||
commands.insert_resource(ExtractedAmbientLight {
|
||||
color: ambient_light.color,
|
||||
|
@ -290,11 +290,11 @@ pub fn prepare_lights(
|
|||
let mut gpu_lights = GpuLights {
|
||||
ambient_color: ambient_color.into(),
|
||||
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
|
||||
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 =
|
||||
Mat4::perspective_rh(std::f32::consts::FRAC_PI_2, 1.0, 0.1, light.range);
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ struct StandardMaterial {
|
|||
flags: u32;
|
||||
};
|
||||
|
||||
struct OmniLight {
|
||||
struct PointLight {
|
||||
color: vec4<f32>;
|
||||
// projection: mat4x4<f32>;
|
||||
position: vec3<f32>;
|
||||
|
@ -101,7 +101,7 @@ struct OmniLight {
|
|||
struct Lights {
|
||||
// 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
|
||||
omni_lights: array<OmniLight, 10>;
|
||||
point_lights: array<PointLight, 10>;
|
||||
ambient_color: vec4<f32>;
|
||||
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);
|
||||
}
|
||||
|
||||
fn omni_light(
|
||||
world_position: vec3<f32>, light: OmniLight, roughness: f32, NdotV: f32, N: vec3<f32>, V: vec3<f32>,
|
||||
fn point_light(
|
||||
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>
|
||||
) -> vec3<f32> {
|
||||
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 {
|
||||
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
|
||||
// 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
|
||||
var light_accum: vec3<f32> = vec3<f32>(0.0);
|
||||
for (var i: i32 = 0; i < i32(lights.num_lights); i = i + 1) {
|
||||
let light = lights.omni_lights[i];
|
||||
let light_contrib = omni_light(in.world_position.xyz, light, roughness, NdotV, N, V, R, F0, diffuse_color);
|
||||
let light = lights.point_lights[i];
|
||||
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);
|
||||
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));
|
||||
|
||||
let frame = match swap_chain.get_current_frame() {
|
||||
Ok(swap_chain_frame) => {
|
||||
swap_chain_frame
|
||||
},
|
||||
Ok(swap_chain_frame) => swap_chain_frame,
|
||||
Err(wgpu::SwapChainError::Outdated) => {
|
||||
let new_swap_chain = render_device.create_swap_chain(surface, &swap_chain_descriptor);
|
||||
let frame = new_swap_chain.get_current_frame().expect("Error recreating swap chain");
|
||||
window_surfaces.swap_chains.insert(
|
||||
window.id,
|
||||
new_swap_chain
|
||||
);
|
||||
let new_swap_chain =
|
||||
render_device.create_swap_chain(surface, &swap_chain_descriptor);
|
||||
let frame = new_swap_chain
|
||||
.get_current_frame()
|
||||
.expect("Error recreating swap chain");
|
||||
window_surfaces
|
||||
.swap_chains
|
||||
.insert(window.id, new_swap_chain);
|
||||
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));
|
||||
|
|
Loading…
Reference in a new issue