Create a PointLight component for light position
ci/woodpecker/push/build Pipeline was successful
Details
ci/woodpecker/push/build Pipeline was successful
Details
This commit is contained in:
parent
e95a45fd53
commit
d26e1ccfb4
|
@ -1,4 +1,4 @@
|
||||||
use lyra_engine::{math::{self, Vec3}, ecs::{World, components::{transform::TransformComponent, camera::CameraComponent, model::ModelComponent, DeltaTime}, EventQueue, SimpleSystem, Component, Criteria, CriteriaSchedule, BatchedSystem}, math::Transform, input::{KeyCode, InputButtons, MouseMotion, ActionHandler, Layout, Action, ActionKind, LayoutId, ActionMapping, Binding, ActionSource, ActionMappingId, InputActionPlugin, ActionState}, game::Game, plugin::Plugin, render::window::{CursorGrabMode, WindowOptions}, change_tracker::Ct};
|
use lyra_engine::{math::{self, Vec3}, ecs::{World, components::{transform::TransformComponent, camera::CameraComponent, model::ModelComponent, DeltaTime}, EventQueue, SimpleSystem, Component, Criteria, CriteriaSchedule, BatchedSystem}, math::Transform, input::{KeyCode, InputButtons, MouseMotion, ActionHandler, Layout, Action, ActionKind, LayoutId, ActionMapping, Binding, ActionSource, ActionMappingId, InputActionPlugin, ActionState}, game::Game, plugin::Plugin, render::{window::{CursorGrabMode, WindowOptions}, light::PointLight}, change_tracker::Ct};
|
||||||
use lyra_engine::assets::{ResourceManager, Model};
|
use lyra_engine::assets::{ResourceManager, Model};
|
||||||
|
|
||||||
mod free_fly_camera;
|
mod free_fly_camera;
|
||||||
|
@ -69,7 +69,7 @@ async fn main() {
|
||||||
let mut resman = world.get_resource_mut::<ResourceManager>().unwrap();
|
let mut resman = world.get_resource_mut::<ResourceManager>().unwrap();
|
||||||
//let diffuse_texture = resman.request::<Texture>("assets/happy-tree.png").unwrap();
|
//let diffuse_texture = resman.request::<Texture>("assets/happy-tree.png").unwrap();
|
||||||
let antique_camera_model = resman.request::<Model>("assets/AntiqueCamera.glb").unwrap();
|
let antique_camera_model = resman.request::<Model>("assets/AntiqueCamera.glb").unwrap();
|
||||||
//let cube_model = resman.request::<Model>("assets/texture-sep/texture-sep.gltf").unwrap();
|
let cube_model = resman.request::<Model>("assets/cube-texture-bin.glb").unwrap();
|
||||||
drop(resman);
|
drop(resman);
|
||||||
|
|
||||||
/* world.spawn((
|
/* world.spawn((
|
||||||
|
@ -82,6 +82,27 @@ async fn main() {
|
||||||
TransformComponent::from(Transform::from_xyz(0.0, -5.0, -10.0)),
|
TransformComponent::from(Transform::from_xyz(0.0, -5.0, -10.0)),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
/* let light = PointLight {
|
||||||
|
color: Vec3::new(1.0, 1.0, 1.0),
|
||||||
|
position: Vec3::new(0.0, -5.0, -8.0),
|
||||||
|
constant: 1.0,
|
||||||
|
linear: 0.09,
|
||||||
|
quadratic: 0.032,
|
||||||
|
};
|
||||||
|
world.spawn((light,)); */
|
||||||
|
let pos = Vec3::new(0.0, 0.0, -10.0);
|
||||||
|
world.spawn((
|
||||||
|
PointLight {
|
||||||
|
color: Vec3::new(1.0, 1.0, 1.0),
|
||||||
|
intensity: 2.0,
|
||||||
|
constant: 1.0,
|
||||||
|
linear: 0.045,
|
||||||
|
quadratic: 0.0075,
|
||||||
|
},
|
||||||
|
TransformComponent::from(Transform::from_xyz(pos.x, pos.y, pos.z)),
|
||||||
|
ModelComponent(cube_model),
|
||||||
|
));
|
||||||
|
|
||||||
let mut camera = CameraComponent::new_3d();
|
let mut camera = CameraComponent::new_3d();
|
||||||
camera.transform.translation += math::Vec3::new(0.0, 0.0, 7.5);
|
camera.transform.translation += math::Vec3::new(0.0, 0.0, 7.5);
|
||||||
//camera.transform.rotate_y(Angle::Degrees(-25.0));
|
//camera.transform.rotate_y(Angle::Degrees(-25.0));
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
pub mod point;
|
pub mod point;
|
||||||
pub use point::*;
|
pub use point::*;
|
||||||
|
|
||||||
|
use crate::math::Transform;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||||
pub struct LightUniform {
|
pub struct LightUniform {
|
||||||
|
@ -11,3 +13,40 @@ pub struct LightUniform {
|
||||||
// Due to uniforms requiring 16 byte (4 float) spacing, we need to use a padding field here
|
// Due to uniforms requiring 16 byte (4 float) spacing, we need to use a padding field here
|
||||||
pub(crate) _padding2: u32,
|
pub(crate) _padding2: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Default, Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
||||||
|
pub struct PointLightUniform {
|
||||||
|
/// The position of the light
|
||||||
|
/// vec4 is used here for gpu padding, w is ignored in the shader
|
||||||
|
pub position: glam::Vec4,
|
||||||
|
/// The color of the light
|
||||||
|
/// vec4 is used here for gpu padding, w is ignored in the shader
|
||||||
|
pub color: glam::Vec4,
|
||||||
|
/// The intensity of the light
|
||||||
|
/// This works by just multiplying the result of the lighting
|
||||||
|
/// calculations by this scalar
|
||||||
|
pub intensity: f32,
|
||||||
|
/// The constant used in the quadratic attenuation calculation. Its best to leave this at 1.0
|
||||||
|
pub constant: f32,
|
||||||
|
/// The linear factor used in the quadratic attenuation calculation.
|
||||||
|
pub linear: f32,
|
||||||
|
/// The quadratic factor used in the quadratic attenuation calculation.
|
||||||
|
pub quadratic: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PointLightUniform {
|
||||||
|
/// Create the PointLightUniform from an ECS bundle
|
||||||
|
pub fn from_bundle(light: &PointLight, transform: &Transform) -> Self {
|
||||||
|
Self {
|
||||||
|
position: glam::Vec4::new(transform.translation.x, transform.translation.y, transform.translation.z, 0.0),
|
||||||
|
//_padding: 0,
|
||||||
|
color: glam::Vec4::new(light.color.x, light.color.y, light.color.z, 0.0),
|
||||||
|
//_padding2: 0,
|
||||||
|
intensity: light.intensity,
|
||||||
|
constant: light.constant,
|
||||||
|
linear: light.linear,
|
||||||
|
quadratic: light.quadratic,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,9 @@
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
|
#[derive(Default, Debug, Copy, Clone, edict::Component)]
|
||||||
pub struct PointLight {
|
pub struct PointLight {
|
||||||
position: glam::Vec3,
|
pub color: glam::Vec3,
|
||||||
color: glam::Vec3,
|
pub intensity: f32,
|
||||||
|
pub constant: f32,
|
||||||
|
pub linear: f32,
|
||||||
|
pub quadratic: f32,
|
||||||
}
|
}
|
|
@ -18,10 +18,11 @@ use crate::ecs::components::camera::CameraComponent;
|
||||||
use crate::ecs::components::model::ModelComponent;
|
use crate::ecs::components::model::ModelComponent;
|
||||||
use crate::ecs::components::transform::TransformComponent;
|
use crate::ecs::components::transform::TransformComponent;
|
||||||
use crate::math::{Transform, self};
|
use crate::math::{Transform, self};
|
||||||
|
use crate::render::light::PointLightUniform;
|
||||||
|
|
||||||
use super::camera::{RenderCamera, CameraUniform};
|
use super::camera::{RenderCamera, CameraUniform};
|
||||||
use super::desc_buf_lay::DescVertexBufferLayout;
|
use super::desc_buf_lay::DescVertexBufferLayout;
|
||||||
use super::light::LightUniform;
|
use super::light::{LightUniform, PointLight};
|
||||||
use super::texture::RenderTexture;
|
use super::texture::RenderTexture;
|
||||||
use super::transform_buffer_storage::{TransformBufferIndices, TransformBuffers};
|
use super::transform_buffer_storage::{TransformBufferIndices, TransformBuffers};
|
||||||
use super::vertex::Vertex;
|
use super::vertex::Vertex;
|
||||||
|
@ -90,7 +91,6 @@ pub struct BasicRenderer {
|
||||||
default_texture_bind_group: BindGroup,
|
default_texture_bind_group: BindGroup,
|
||||||
depth_buffer_texture: RenderTexture,
|
depth_buffer_texture: RenderTexture,
|
||||||
|
|
||||||
point_light_uniform: LightUniform,
|
|
||||||
point_light_buffer: wgpu::Buffer,
|
point_light_buffer: wgpu::Buffer,
|
||||||
point_light_bind_group_layout: BindGroupLayout,
|
point_light_bind_group_layout: BindGroupLayout,
|
||||||
point_light_bind_group: BindGroup,
|
point_light_bind_group: BindGroup,
|
||||||
|
@ -243,16 +243,10 @@ impl BasicRenderer {
|
||||||
next_indices: TransformBufferIndices { buffer_index: 0, transform_index: 0 },
|
next_indices: TransformBufferIndices { buffer_index: 0, transform_index: 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
let point_light_uniform = LightUniform {
|
|
||||||
position: glam::Vec3::new(0.0, -2.0, -13.0),
|
|
||||||
_padding: 0,
|
|
||||||
color: glam::Vec3::new(1.0, 1.0, 1.0),
|
|
||||||
_padding2: 0,
|
|
||||||
};
|
|
||||||
let point_light_buffer = device.create_buffer_init(
|
let point_light_buffer = device.create_buffer_init(
|
||||||
&wgpu::util::BufferInitDescriptor {
|
&wgpu::util::BufferInitDescriptor {
|
||||||
label: Some("Point Light Buffer"),
|
label: Some("Point Light Buffer"),
|
||||||
contents: bytemuck::cast_slice(&[glam::Mat4::IDENTITY]),
|
contents: bytemuck::cast_slice(&[PointLightUniform::default()]),
|
||||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -372,7 +366,6 @@ impl BasicRenderer {
|
||||||
depth_buffer_texture: depth_texture,
|
depth_buffer_texture: depth_texture,
|
||||||
entity_last_transforms: HashMap::new(),
|
entity_last_transforms: HashMap::new(),
|
||||||
|
|
||||||
point_light_uniform,
|
|
||||||
point_light_buffer,
|
point_light_buffer,
|
||||||
point_light_bind_group_layout,
|
point_light_bind_group_layout,
|
||||||
point_light_bind_group,
|
point_light_bind_group,
|
||||||
|
@ -654,11 +647,9 @@ impl Renderer for BasicRenderer {
|
||||||
warn!("Missing camera!");
|
warn!("Missing camera!");
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
for (point_light, transform) in main_world.query::<(&PointLight, &TransformComponent)>().iter() {
|
||||||
let old_pos = self.point_light_uniform.position;
|
let uniform = PointLightUniform::from_bundle(point_light, &transform.transform);
|
||||||
self.point_light_uniform.position = glam::Quat::from_axis_angle(glam::Vec3::Z,
|
self.queue.write_buffer(&self.point_light_buffer, 0, bytemuck::cast_slice(&[uniform]));
|
||||||
math::Angle::Degrees(1.0).to_radians()) * old_pos;
|
|
||||||
self.queue.write_buffer(&self.point_light_buffer, 0, bytemuck::cast_slice(&[self.point_light_uniform]));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,12 @@ struct CameraUniform {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PointLight {
|
struct PointLight {
|
||||||
position: vec3<f32>,
|
position: vec4<f32>,
|
||||||
color: vec3<f32>,
|
color: vec4<f32>,
|
||||||
|
intensity: f32,
|
||||||
|
constant: f32,
|
||||||
|
linear: f32,
|
||||||
|
quadratic: f32,
|
||||||
};
|
};
|
||||||
|
|
||||||
@group(1) @binding(0)
|
@group(1) @binding(0)
|
||||||
|
@ -32,7 +36,6 @@ var<uniform> camera: CameraUniform;
|
||||||
@group(3) @binding(0)
|
@group(3) @binding(0)
|
||||||
var<uniform> point_light: PointLight;
|
var<uniform> point_light: PointLight;
|
||||||
|
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vs_main(
|
fn vs_main(
|
||||||
model: VertexInput,
|
model: VertexInput,
|
||||||
|
@ -63,29 +66,41 @@ var s_diffuse: sampler;
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
//return textureSample(t_diffuse, s_diffuse, in.tex_coords);
|
let light_color = point_light.color.xyz;
|
||||||
|
let light_pos = point_light.position.xyz;
|
||||||
|
let camera_view_pos = camera.view_pos.xyz;
|
||||||
|
|
||||||
let object_color: vec4<f32> = textureSample(t_diffuse, s_diffuse, in.tex_coords);
|
let object_color: vec4<f32> = textureSample(t_diffuse, s_diffuse, in.tex_coords);
|
||||||
|
|
||||||
// We don't need (or want) much ambient light, so 0.1 is fine
|
// We don't need (or want) much ambient light, so 0.1 is fine
|
||||||
let ambient_strength = 0.1;
|
let ambient_strength = 0.1;
|
||||||
let ambient_color = point_light.color * ambient_strength;
|
var ambient_color = light_color * ambient_strength;
|
||||||
|
|
||||||
//// diffuse ////
|
//// diffuse ////
|
||||||
let light_dir = normalize(point_light.position - in.world_position);
|
let light_dir = normalize(light_pos - in.world_position);
|
||||||
|
|
||||||
let diffuse_strength = max(dot(in.world_normal, light_dir), 0.0);
|
let diffuse_strength = max(dot(in.world_normal, light_dir), 0.0);
|
||||||
let diffuse_color = point_light.color * diffuse_strength;
|
var diffuse_color = light_color * diffuse_strength;
|
||||||
//// end of diffuse ////
|
//// end of diffuse ////
|
||||||
|
|
||||||
//// specular ////
|
//// specular ////
|
||||||
let view_dir = normalize(camera.view_pos.xyz - in.world_position);
|
let view_dir = normalize(camera_view_pos - in.world_position);
|
||||||
let half_dir = normalize(view_dir + light_dir);
|
let half_dir = normalize(view_dir + light_dir);
|
||||||
|
|
||||||
let specular_strength = pow(max(dot(in.world_normal, half_dir), 0.0), 32.0);
|
let specular_strength = pow(max(dot(in.world_normal, half_dir), 0.0), 32.0);
|
||||||
let specular_color = specular_strength * point_light.color;
|
var specular_color = specular_strength * light_color;
|
||||||
//// end of specular ////
|
//// end of specular ////
|
||||||
|
|
||||||
|
//// point light attenuation ////
|
||||||
|
let distance = length(light_pos - in.world_position);
|
||||||
|
let attenuation = 1.0 / (point_light.constant + point_light.linear * distance +
|
||||||
|
point_light.quadratic * (distance * distance));
|
||||||
|
|
||||||
|
ambient_color *= attenuation * point_light.intensity;
|
||||||
|
diffuse_color *= attenuation * point_light.intensity;
|
||||||
|
specular_color *= attenuation * point_light.intensity;
|
||||||
|
//// end of point light attenuation ////
|
||||||
|
|
||||||
let result = (ambient_color + diffuse_color + specular_color) * object_color.xyz;
|
let result = (ambient_color + diffuse_color + specular_color) * object_color.xyz;
|
||||||
|
|
||||||
return vec4<f32>(result, object_color.a);
|
return vec4<f32>(result, object_color.a);
|
||||||
|
|
Loading…
Reference in New Issue