omni light -> point light

This commit is contained in:
Carter Anderson 2021-07-01 16:54:58 -07:00
parent 4099ef6aa2
commit bc769d9641
7 changed files with 43 additions and 45 deletions

View file

@ -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()
},

View file

@ -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()

View file

@ -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,
}

View file

@ -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,

View file

@ -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);

View file

@ -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;
}

View file

@ -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));