diff --git a/Cargo.toml b/Cargo.toml index 73cf6fd..fb786f7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ tobj = { version = "3.2.1", features = [ ]} instant = "0.1" async-trait = "0.1.65" -glam = { version = "0.24.0", features = ["bytemuck"] } +glam = { version = "0.24.0", features = ["bytemuck", "debug-glam-assert"] } gilrs-core = "0.5.6" syn = "2.0.26" quote = "1.0.29" diff --git a/examples/testbed/src/main.rs b/examples/testbed/src/main.rs index 004a5ab..02f4698 100644 --- a/examples/testbed/src/main.rs +++ b/examples/testbed/src/main.rs @@ -57,6 +57,9 @@ impl Criteria for FixedTimestep { #[derive(Clone)] struct TpsAccumulator(f32); +#[derive(Component)] +struct CubeFlag; + #[async_std::main] async fn main() { let setup_sys = |world: &mut World| -> anyhow::Result<()> { @@ -68,7 +71,7 @@ async fn main() { let mut resman = world.get_resource_mut::().unwrap(); //let diffuse_texture = resman.request::("assets/happy-tree.png").unwrap(); - let antique_camera_model = resman.request::("assets/AntiqueCamera.glb").unwrap(); + //let antique_camera_model = resman.request::("assets/AntiqueCamera.glb").unwrap(); //let cube_model = resman.request::("assets/cube-texture-bin.glb").unwrap(); let cube_model = resman.request::("assets/texture-sep/texture-sep.gltf").unwrap(); drop(resman); @@ -103,17 +106,22 @@ async fn main() { }, */ TransformComponent::from(cube_tran), ModelComponent(cube_model.clone()), + CubeFlag, )); - let mut light_tran = Transform::from_xyz(3.5, 0.0, -7.0); + let mut light_tran = Transform::from_xyz(1.5, 2.5, -8.5); light_tran.scale = Vec3::new(0.5, 0.5, 0.5); world.spawn(( PointLight { - color: Vec3::new(0.361, 0.984, 0.0), + color: Vec3::new(1.0, 1.0, 1.0), //Vec3::new(0.361, 0.984, 0.0), intensity: 1.0, - constant: 1.0, + /* constant: 1.0, linear: 0.045, - quadratic: 0.0075, + quadratic: 0.0075, */ + + constant: 1.0, + linear: 0.09, + quadratic: 0.032, ambient: 0.2, diffuse: 0.5, @@ -147,10 +155,10 @@ async fn main() { }; let spin_system = |world: &mut World| -> anyhow::Result<()> { - const SPEED: f32 = 5.0; + const SPEED: f32 = 7.0; let delta_time = **world.get_resource::().unwrap(); - for transform in world.query_mut::<(&mut TransformComponent,)>().iter_mut() { + for (transform, _) in world.query_mut::<(&mut TransformComponent, &CubeFlag)>().iter_mut() { let t = &mut transform.transform; t.rotate_y(math::Angle::Degrees(SPEED * delta_time)); } @@ -164,7 +172,7 @@ async fn main() { let mut sys = BatchedSystem::new(); sys.with_criteria(FixedTimestep::new(45)); //sys.with_system(spin_system); - sys.with_system(fps_system); + //sys.with_system(fps_system); game.with_system("fixed", sys, &[]); fps_plugin(game); @@ -203,7 +211,7 @@ async fn main() { game.world().insert_resource(action_handler); game.with_plugin(InputActionPlugin); - game.with_system("test_actions", test_system, &[]); + //game.with_system("test_actions", test_system, &[]); }; Game::initialize().await diff --git a/src/math/transform.rs b/src/math/transform.rs index fef492a..8da8fae 100755 --- a/src/math/transform.rs +++ b/src/math/transform.rs @@ -92,11 +92,17 @@ impl Transform { /// will be equal to `rhs`. When `alpha` is outside of range `[0, 1]`, the result is linearly /// extrapolated. pub fn lerp(&self, rhs: Transform, alpha: f32) -> Self { - let mut res = self.clone(); - res.translation = self.translation.lerp(rhs.translation, alpha); - res.rotation = self.rotation.lerp(rhs.rotation, alpha); - res.scale = self.scale.lerp(rhs.scale, alpha); + + if alpha.is_finite() { + let mut res = self.clone(); + res.translation = self.translation.lerp(rhs.translation, alpha); + res.rotation = self.rotation.lerp(rhs.rotation, alpha); + res.scale = self.scale.lerp(rhs.scale, alpha); + res + } else { + self.clone() + } + - res } } \ No newline at end of file diff --git a/src/render/material.rs b/src/render/material.rs index 71306d8..9d65a24 100755 --- a/src/render/material.rs +++ b/src/render/material.rs @@ -1,4 +1,5 @@ use super::texture::RenderTexture; +use super::texture::RenderTexture; #[derive(Clone)] pub struct Material { @@ -19,7 +20,8 @@ impl Material { shader_id: value.shader_uuid.unwrap_or(0), diffuse_texture, ambient: glam::Vec3::new(1.0, 0.5, 0.31), - diffuse: glam::Vec3::new(value.base_color.x, value.base_color.y, value.base_color.z), + //diffuse: glam::Vec3::new(value.base_color.x, value.base_color.y, value.base_color.z), + diffuse: glam::Vec3::new(1.0, 0.5, 0.31), specular: glam::Vec3::new(0.5, 0.5, 0.5), shininess: 32.0, } diff --git a/src/render/shaders/base.wgsl b/src/render/shaders/base.wgsl index d02a678..4512e3c 100755 --- a/src/render/shaders/base.wgsl +++ b/src/render/shaders/base.wgsl @@ -1,5 +1,6 @@ // Vertex shader +const max_light_count: u32 = 16u; const max_light_count: u32 = 16u; struct VertexInput { @@ -24,6 +25,7 @@ struct PointLight { position: vec4, color: vec4, + intensity: f32, constant: f32, linear: f32, @@ -32,6 +34,10 @@ struct PointLight { ambient: f32, diffuse: f32, specular: f32, + + ambient: f32, + diffuse: f32, + specular: f32, }; struct Lights { @@ -42,7 +48,7 @@ struct Lights { @group(1) @binding(0) var u_model_transform: mat4x4; @group(1) @binding(1) -var u_model_normal_matrix: mat3x3; +var u_model_normal_matrix: mat4x4; @group(2) @binding(0) var u_camera: CameraUniform; @@ -59,8 +65,10 @@ fn vs_main( out.tex_coords = model.tex_coords; out.clip_position = u_camera.view_proj * u_model_transform * vec4(model.position, 1.0); - out.world_normal = u_model_normal_matrix * model.normal; - + // the normal mat is actually only a mat3x3, but there's a bug in wgpu: https://github.com/gfx-rs/wgpu-rs/issues/36 + let normal_mat = mat3x3(u_model_normal_matrix[0].xyz, u_model_normal_matrix[1].xyz, u_model_normal_matrix[2].xyz); + out.world_normal = normalize(normal_mat * model.normal, ); + var world_position: vec4 = u_model_transform * vec4(model.position, 1.0); out.world_position = world_position.xyz; @@ -76,9 +84,17 @@ struct Material { shininess: f32, } +struct Material { + ambient: vec4, + diffuse: vec4, + specular: vec4, + shininess: f32, +} + @group(0) @binding(0) var t_diffuse: texture_2d; @group(0) @binding(1) +@group(0) @binding(1) var s_diffuse: sampler; @group(4) @binding(0) @@ -91,8 +107,9 @@ fn fs_main(in: VertexOutput) -> @location(0) vec4 { var light_res = vec3(0.0); for (var i = 0u; i < u_lights.point_light_count; i++) { light_res += blinn_phong_point_light(in.world_position, in.world_normal, u_lights.point_lights[i], u_material); + light_res += blinn_phong_point_light(in.world_position, in.world_normal, u_lights.point_lights[i], u_material); } - let light_object_res = light_res * object_color.xyz; + let light_object_res = light_res * (object_color.xyz/* * u_material.diffuse.xyz*/); return vec4(light_object_res, object_color.a); } @@ -105,31 +122,40 @@ fn blinn_phong_point_light(world_pos: vec3, world_norm: vec3, point_li // We don't need (or want) much ambient light, so 0.1 is fine //let ambient_strength = 0.1; var ambient_color = light_color * material.ambient.xyz; + //let ambient_strength = 0.1; + var ambient_color = light_color * material.ambient.xyz; //// diffuse //// let light_dir = normalize(light_pos - world_pos); let diffuse_strength = max(dot(world_norm, light_dir), 0.0); var diffuse_color = light_color * (diffuse_strength * material.diffuse.xyz); + var diffuse_color = light_color * (diffuse_strength * material.diffuse.xyz); //// end of diffuse //// //// specular //// let view_dir = normalize(camera_view_pos - world_pos); let half_dir = normalize(view_dir + light_dir); + let specular_strength = pow(max(dot(world_norm, half_dir), 0.0), material.shininess); + var specular_color = specular_strength * (light_color * material.specular.xyz); let specular_strength = pow(max(dot(world_norm, half_dir), 0.0), material.shininess); var specular_color = specular_strength * (light_color * material.specular.xyz); //// end of specular //// //// point light attenuation //// - let distance = length(light_pos - world_pos); + /*let distance = length(light_pos - world_pos); let attenuation = 1.0 / (point_light.constant + point_light.linear * distance + - point_light.quadratic * (distance * distance)); + point_light.quadratic * (distance * distance));*/ - ambient_color *= attenuation * point_light.intensity * point_light.ambient; - diffuse_color *= attenuation * point_light.intensity * point_light.diffuse; - specular_color *= attenuation * point_light.intensity * point_light.specular; + //ambient_color *= attenuation * point_light.intensity * point_light.ambient; + //diffuse_color *= attenuation * point_light.intensity * point_light.diffuse; + //specular_color *= attenuation * point_light.intensity * point_light.specular; //// end of point light attenuation //// + + ambient_color *= point_light.ambient; + diffuse_color *= point_light.diffuse; + specular_color *= point_light.specular; - return (ambient_color + diffuse_color + specular_color); + return (ambient_color + diffuse_color + specular_color) * /*attenuation * */ point_light.intensity; } \ No newline at end of file diff --git a/src/render/transform_buffer_storage.rs b/src/render/transform_buffer_storage.rs index ded1c2d..07cf7c0 100644 --- a/src/render/transform_buffer_storage.rs +++ b/src/render/transform_buffer_storage.rs @@ -1,6 +1,7 @@ use std::{collections::{VecDeque, HashMap}, num::NonZeroU64}; use edict::EntityId; +use tracing::debug; use wgpu::Limits; use std::mem; @@ -63,7 +64,7 @@ impl TransformBuffers { }); let mut s = Self { - max_transform_count: limits.max_uniform_buffer_binding_size as usize / (mem::size_of::() + mem::size_of::()), + max_transform_count: limits.max_uniform_buffer_binding_size as usize / (mem::size_of::() * 2), buffer_bindgroups: Vec::new(), bindgroup_layout, just_updated: HashMap::new(), @@ -85,6 +86,10 @@ impl TransformBuffers { .expect("Use 'insert_entity' for new entities"); self.just_updated.insert(entity, indices); + debug!("Normal: {normal_matrix:?}"); + + let normal_matrix = glam::Mat4::from_mat3(normal_matrix); + let buffer = self.buffer_bindgroups.get(indices.buffer_index).unwrap(); let offset = Self::index_offset(limits, indices); queue.write_buffer(&buffer.transform_buf, offset, bytemuck::bytes_of(&transform)); @@ -173,7 +178,7 @@ impl TransformBuffers { let transform_buffer = device.create_buffer( &wgpu::BufferDescriptor { - label: Some(&format!("Transform Buffer {}", self.buffer_bindgroups.len())), + label: Some(&format!("B_Transform_{}", self.buffer_bindgroups.len())), usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, size: max_buffer_sizes, mapped_at_creation: false, @@ -182,19 +187,17 @@ impl TransformBuffers { let normal_mat_buffer = device.create_buffer( &wgpu::BufferDescriptor { - label: Some(&format!("Normal Matrix Buffer {}", self.buffer_bindgroups.len())), + label: Some(&format!("B_NormalMatrix_{}", self.buffer_bindgroups.len())), usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, size: max_buffer_sizes, mapped_at_creation: false, } ); - /* let stride = limits.min_uniform_buffer_offset_alignment as u64 - + mem::size_of::() as u64 + mem::size_of::() as u64; */ - let tran_stride = limits.min_uniform_buffer_offset_alignment as u64 - + mem::size_of::() as u64; - let norm_stride = limits.min_uniform_buffer_offset_alignment as u64 - + mem::size_of::() as u64; + let tran_stride = mem::size_of::(); + // although a normal matrix only needs to be a mat3, there's a weird issue with + // misalignment from wgpu or spirv-cross: https://github.com/gfx-rs/wgpu-rs/issues/36 + let norm_stride = mem::size_of::(); let transform_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { layout: &self.bindgroup_layout, @@ -205,7 +208,7 @@ impl TransformBuffers { wgpu::BufferBinding { buffer: &transform_buffer, offset: 0, - size: Some(NonZeroU64::new(tran_stride).unwrap()) + size: Some(NonZeroU64::new(tran_stride as u64).unwrap()) } ) }, @@ -215,12 +218,12 @@ impl TransformBuffers { wgpu::BufferBinding { buffer: &normal_mat_buffer, offset: 0, - size: Some(NonZeroU64::new(norm_stride).unwrap()) + size: Some(NonZeroU64::new(norm_stride as u64).unwrap()) } ) } ], - label: Some("transform_bind_group"), + label: Some("BG_Transforms"), }); let entry = TransformBufferEntry { diff --git a/src/render/vertex.rs b/src/render/vertex.rs index 346fa6d..57a7432 100755 --- a/src/render/vertex.rs +++ b/src/render/vertex.rs @@ -34,7 +34,7 @@ impl DescVertexBufferLayout for Vertex { format: wgpu::VertexFormat::Float32x2, // Vec2 }, wgpu::VertexAttribute { - offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, + offset: std::mem::size_of::<[f32; 5]>() as wgpu::BufferAddress, shader_location: 2, format: wgpu::VertexFormat::Float32x3, // Vec3 }