diff --git a/shaders/triangle.frag b/shaders/triangle.frag index 597469c..e872c19 100644 --- a/shaders/triangle.frag +++ b/shaders/triangle.frag @@ -1,18 +1,25 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable +layout(binding = 0) uniform ObjectUniformData { + mat4 view; + mat4 projection; + float time; + vec3 light_position; + vec3 camera_position; +} ubo; + layout(binding = 1) uniform sampler2D tex; layout(location = 0) in vec2 tex_coords; -layout(location = 1) in vec3 normal_cam; -layout(location = 2) in vec3 position_cam; -layout(location = 3) in vec3 light_direction_cam; +layout(location = 1) in vec3 normal_wld; +layout(location = 2) in vec3 position_wld; layout(location = 0) out vec4 out_color; void main() { - vec3 normal_cam_u = normalize(normal_cam); - vec3 light_direction_cam_u = normalize(light_direction_cam); + vec3 normal_cam_u = normalize(normal_wld); + vec3 light_direction_cam_u = normalize(ubo.light_position - position_wld); float ambient_strength = 0.1; vec3 light_color = vec3(1.0, 1.0, 1.0); @@ -21,11 +28,11 @@ void main() { float diffuse_strength = max(0.0, dot(normal_cam_u, light_direction_cam_u)); vec3 diffuse_color = diffuse_strength * light_color; -// float specular_value = 1.0; -// vec3 view_direction = normalize(position_cam); -// vec3 reflect_direction = reflect(-light_direction_cam_nm, normal_cam_nm); -// float specular_strength = pow(max(dot(view_direction, reflect_direction), 0.0), 32); -// vec3 specular_color = specular_value * specular_strength * light_color; + float specular_value = 1.0; + vec3 view_direction = normalize(ubo.camera_position - position_wld); + vec3 reflect_direction = reflect(-light_direction_cam_u, normal_cam_u); + float specular_strength = pow(max(dot(view_direction, reflect_direction), 0.0), 64); + vec3 specular_color = specular_value * specular_strength * light_color; - out_color = vec4(ambient_color + diffuse_color, 1.0) * texture(tex, tex_coords); + out_color = vec4(ambient_color + diffuse_color + specular_color, 1.0) * texture(tex, tex_coords); } \ No newline at end of file diff --git a/shaders/triangle.vert b/shaders/triangle.vert index d4ec7ec..9089c8f 100644 --- a/shaders/triangle.vert +++ b/shaders/triangle.vert @@ -10,6 +10,7 @@ layout(binding = 0) uniform ObjectUniformData { mat4 projection; float time; vec3 light_position; + vec3 camera_position; } ubo; layout(location = 0) in vec3 position; @@ -17,9 +18,8 @@ layout(location = 1) in vec2 uv; layout(location = 2) in vec3 normal; layout(location = 0) out vec2 tex_coords; -layout(location = 1) out vec3 normal_cam; -layout(location = 2) out vec3 position_cam; -layout(location = 3) out vec3 light_direction_cam; +layout(location = 1) out vec3 normal_wld; +layout(location = 2) out vec3 position_wld; out gl_PerVertex { vec4 gl_Position; @@ -29,10 +29,6 @@ void main() { gl_Position = ubo.projection * ubo.view * push.model * vec4(position, 1.0); tex_coords = uv; - position_cam = vec3(ubo.view * push.model * vec4(position, 1.0)); - // TODO: use inverse transpose so this doesn't break when scaling - normal_cam = vec3(ubo.view * push.model * vec4(normal, 1.0)); - - vec3 light_position_cam = vec3(ubo.view * vec4(ubo.light_position, 1.0)); - light_direction_cam = light_position_cam - position_cam; + position_wld = vec3(push.model * vec4(position, 1.0)); + normal_wld = vec3(mat3(transpose(inverse(push.model))) * normal); } \ No newline at end of file diff --git a/src/gameobject.rs b/src/gameobject.rs index 136f5ad..4b7ad5b 100644 --- a/src/gameobject.rs +++ b/src/gameobject.rs @@ -19,10 +19,20 @@ impl GameObject { self.model_matrix.w.z = pos.2; } - pub fn get_position(&self) -> Vector3 { + pub fn _get_position(&self) -> Vector3 { vec3(self.model_matrix.w.x, self.model_matrix.w.y, self.model_matrix.w.z) } + pub fn set_scale(&mut self, scale: (f32, f32, f32)) { + self.model_matrix.x.x = scale.0; + self.model_matrix.y.y = scale.1; + self.model_matrix.z.z = scale.2; + } + + pub fn _get_scale(&mut self) -> Vector3 { + vec3(self.model_matrix.x.x, self.model_matrix.y.y, self.model_matrix.z.z) + } + pub fn translate(&mut self, x: f32, y: f32, z: f32) { self.model_matrix.w.x += x; self.model_matrix.w.y += y; diff --git a/src/main.rs b/src/main.rs index 9b596ab..8cb5bee 100644 --- a/src/main.rs +++ b/src/main.rs @@ -53,8 +53,9 @@ impl Game for TestGame { println!("{:.0} ms / {:.0} FPS", frame_time * 1000.0, 1.0 / frame_time); } - let light_pos = vec3(f32::sin(time) * 10.0, f32::cos(time) * 10.0, 0.0); - self.game_objects[0].get_game_object(renderer).unwrap().set_position(light_pos.into()); + let light_pos = vec3(f32::sin(time) * 2.0 + 2.0, f32::cos(time) * 2.0 + 2.0, 2.0); + self.game_objects[2].get_game_object(renderer).unwrap().set_position(light_pos.into()); + self.cam_rotation = self.cam_rotation * Quaternion::from_angle_y(Deg(self.input.get_axis("look_horizontal") * 0.05)); self.cam_rotation = Quaternion::from_angle_x(Deg(self.input.get_axis("look_vertical") * 0.05)) * self.cam_rotation; @@ -63,7 +64,6 @@ impl Game for TestGame { 0.0, self.input.get_axis("move_forward") * 0.05)); - // Move game objects let view = Matrix4::from(self.cam_rotation) * Matrix4::from_translation(self.cam_position); let mut proj = cgmath::perspective( @@ -72,7 +72,6 @@ impl Game for TestGame { 0.1, 100.0 ); - proj.y.y *= -1.0; renderer.game_data.line_push_constants.view = view.into(); @@ -86,12 +85,14 @@ impl Game for TestGame { projection: proj.into(), time, light_position: light_pos.into(), + camera_position: self.cam_position.into(), _dummy0: [0; 12], + _dummy1: [0; 4], } } } -fn matrix_vector_mul(matrix: &Matrix4, vector: &Vector3) -> Vector3 { +fn _matrix_vector_mul(matrix: &Matrix4, vector: &Vector3) -> Vector3 { let v4 = Vector4::new(vector.x, vector.y, vector.z, 1.0); let out = matrix * v4; Vector3::new(out.x, out.y, out.z) @@ -99,17 +100,20 @@ fn matrix_vector_mul(matrix: &Matrix4, vector: &Vector3) -> Vector3 Vec { + let mut mesh_handles = Vec::new(); let (meshes, textures) = mesh::load_mesh(gltf_path, self.log_config.mesh_load_info).unwrap(); for cpu_mesh in meshes.into_iter() { let id = match cpu_mesh.texture_index { @@ -117,9 +121,12 @@ impl TestGame { None => 0, }; self.texture_index_counter += 1; - self.meshes.push((renderer.upload_mesh(cpu_mesh), id)); + let mesh_handle = renderer.upload_mesh(cpu_mesh); + self.meshes.push((mesh_handle, id)); + mesh_handles.push(mesh_handle); } textures.iter().for_each(|tex| renderer.upload_texture(tex)); + mesh_handles } fn add_game_object(&mut self, renderer: &mut VulkanRenderer, mesh: MeshHandle, texture_index: usize) -> &mut GameObjectHandle { diff --git a/src/vulkan.rs b/src/vulkan.rs index 9b44dcd..4a6a10c 100644 --- a/src/vulkan.rs +++ b/src/vulkan.rs @@ -1,7 +1,7 @@ use std::sync::Arc; use std::time::SystemTime; -use cgmath::{Matrix4, SquareMatrix, vec3}; +use cgmath::{Matrix4, SquareMatrix}; use image::{ImageBuffer, ImageFormat, Rgb, Rgba}; use image::buffer::ConvertBuffer; use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer}; @@ -280,8 +280,10 @@ impl VulkanRenderer { view: Matrix4::identity().into(), projection: Matrix4::identity().into(), time: 0.0, - light_position: vec3(0.0, 0.0, 0.0).into(), + light_position: [0.0, 0.0, 0.0], + camera_position: [0.0, 0.0, 0.0], _dummy0: [0; 12], + _dummy1: [0; 4], }; for _ in 0..swapchain.num_images() { @@ -434,7 +436,7 @@ impl VulkanRenderer { }; } - pub fn upload_mesh(self: &mut Self, mesh: CPUMesh) -> usize { + pub fn upload_mesh(self: &mut Self, mesh: CPUMesh) -> MeshHandle { let vertex_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::vertex_buffer(), false, mesh.vertices.into_iter()).unwrap(); let index_buffer = CpuAccessibleBuffer::from_iter(self.device.clone(), BufferUsage::index_buffer(), false, mesh.indices.into_iter()).unwrap(); self.game_data.meshes.push(Mesh { vertex_buffer, index_buffer });