Fix issues with the normal matrix
This commit is contained in:
parent
6826d43c8b
commit
039e99281a
|
@ -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"
|
||||
|
|
|
@ -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::<ResourceManager>().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/cube-texture-bin.glb").unwrap();
|
||||
let cube_model = resman.request::<Model>("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::<DeltaTime>().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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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<f32>,
|
||||
color: vec4<f32>,
|
||||
|
||||
|
||||
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<uniform> u_model_transform: mat4x4<f32>;
|
||||
@group(1) @binding(1)
|
||||
var<uniform> u_model_normal_matrix: mat3x3<f32>;
|
||||
var<uniform> u_model_normal_matrix: mat4x4<f32>;
|
||||
|
||||
@group(2) @binding(0)
|
||||
var<uniform> 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<f32>(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<f32> = u_model_transform * vec4<f32>(model.position, 1.0);
|
||||
out.world_position = world_position.xyz;
|
||||
|
||||
|
@ -76,9 +84,17 @@ struct Material {
|
|||
shininess: f32,
|
||||
}
|
||||
|
||||
struct Material {
|
||||
ambient: vec4<f32>,
|
||||
diffuse: vec4<f32>,
|
||||
specular: vec4<f32>,
|
||||
shininess: f32,
|
||||
}
|
||||
|
||||
@group(0) @binding(0)
|
||||
var t_diffuse: texture_2d<f32>;
|
||||
@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<f32> {
|
|||
var light_res = vec3<f32>(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<f32>(light_object_res, object_color.a);
|
||||
}
|
||||
|
@ -105,31 +122,40 @@ fn blinn_phong_point_light(world_pos: vec3<f32>, world_norm: vec3<f32>, 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;
|
||||
}
|
|
@ -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::<glam::Mat4>() + mem::size_of::<glam::Mat3>()),
|
||||
max_transform_count: limits.max_uniform_buffer_binding_size as usize / (mem::size_of::<glam::Mat4>() * 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::<glam::Mat4>() as u64 + mem::size_of::<glam::Mat3>() as u64; */
|
||||
let tran_stride = limits.min_uniform_buffer_offset_alignment as u64
|
||||
+ mem::size_of::<glam::Mat4>() as u64;
|
||||
let norm_stride = limits.min_uniform_buffer_offset_alignment as u64
|
||||
+ mem::size_of::<glam::Mat3>() as u64;
|
||||
let tran_stride = mem::size_of::<glam::Mat4>();
|
||||
// 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::<glam::Mat4>();
|
||||
|
||||
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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue