From 306a983d14211e3e8b14c105dc516f704b90a016 Mon Sep 17 00:00:00 2001 From: marceline-cramer Date: Wed, 2 Feb 2022 13:15:58 -0700 Subject: [PATCH] Surface normals --- src/main.rs | 5 +++++ src/mesh.rs | 6 ++++++ src/renderer.rs | 2 +- src/shader.wgsl | 14 ++++++++++---- 4 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index 8278897..ebf2962 100644 --- a/src/main.rs +++ b/src/main.rs @@ -46,6 +46,11 @@ fn load_model() -> (MeshData, TextureData) { m.mesh.positions[t + 2], -m.mesh.positions[t + 1], ], + normal: [ + m.mesh.normals[t], + m.mesh.normals[t + 2], + -m.mesh.normals[t + 1], + ], tex_coords: [m.mesh.texcoords[i * 2], 1.0 - m.mesh.texcoords[i * 2 + 1]], }); } diff --git a/src/mesh.rs b/src/mesh.rs index 1fccd7b..5a264ab 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -2,6 +2,7 @@ #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] pub struct Vertex { pub position: [f32; 3], + pub normal: [f32; 3], pub tex_coords: [f32; 2], } @@ -19,6 +20,11 @@ impl Vertex { wgpu::VertexAttribute { offset: std::mem::size_of::<[f32; 3]>() as wgpu::BufferAddress, shader_location: 1, + format: wgpu::VertexFormat::Float32x3, + }, + wgpu::VertexAttribute { + offset: std::mem::size_of::<[f32; 6]>() as wgpu::BufferAddress, + shader_location: 2, format: wgpu::VertexFormat::Float32x2, }, ], diff --git a/src/renderer.rs b/src/renderer.rs index 3f229e9..afcda33 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -159,7 +159,7 @@ impl Renderer { topology: wgpu::PrimitiveTopology::TriangleList, strip_index_format: None, front_face: wgpu::FrontFace::Ccw, - cull_mode: None, + cull_mode: Some(wgpu::Face::Back), polygon_mode: wgpu::PolygonMode::Fill, unclipped_depth: false, conservative: false, diff --git a/src/shader.wgsl b/src/shader.wgsl index a714970..b11e1a8 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -22,13 +22,15 @@ struct PointLightData { struct VertexInput { [[location(0)]] position: vec3; - [[location(1)]] tex_coords: vec2; + [[location(1)]] normal: vec3; + [[location(2)]] tex_coords: vec2; }; struct VertexOutput { [[builtin(position)]] clip_position: vec4; [[location(0)]] position: vec3; - [[location(1)]] tex_coords: vec2; + [[location(1)]] normal: vec3; + [[location(2)]] tex_coords: vec2; }; [[group(0), binding(0)]] @@ -50,10 +52,12 @@ fn vs_main( ) -> VertexOutput { let transform = meshes.instances[mesh_idx].transform; let world_pos = transform * vec4(vertex.position, 1.0); + let world_normal = transform * vec4(vertex.normal, 0.0); var out: VertexOutput; out.clip_position = camera.vp * world_pos; out.position = world_pos.xyz; + out.normal = world_normal.xyz; out.tex_coords = vertex.tex_coords; return out; } @@ -63,12 +67,14 @@ fn fs_main( frag: VertexOutput, ) -> [[location(0)]] vec4 { let albedo = textureSample(t_albedo, s_albedo, frag.tex_coords).rgb; + let normal = normalize(frag.normal); var lum = vec3(0.0); for(var i = 0; i < 4; i = i + 1) { let light = point_lights.lights[i]; - let light_relative = frag.position - light.center.xyz; - let diffuse = albedo / dot(light_relative, light_relative); + let light_relative = light.center.xyz - frag.position; + let received = dot(normal, normalize(light_relative)); + let diffuse = (albedo * received) / dot(light_relative, light_relative); lum = lum + (diffuse * light.intensity.rgb); }