Finished light diffusion

This commit is contained in:
Verox001 2025-01-16 13:05:57 +01:00
parent ce1773894f
commit d7378ab5ca
2 changed files with 65 additions and 18 deletions

View File

@ -179,22 +179,24 @@ struct Instance {
impl Instance { impl Instance {
fn to_raw(&self) -> InstanceRaw { fn to_raw(&self) -> InstanceRaw {
let model =
cgmath::Matrix4::from_translation(self.position) * cgmath::Matrix4::from(self.rotation);
InstanceRaw { InstanceRaw {
model: (cgmath::Matrix4::from_translation(self.position) model: model.into(),
* cgmath::Matrix4::from(self.rotation)) normal: cgmath::Matrix3::from(self.rotation).into(),
.into(),
} }
} }
} }
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] #[derive(Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
struct InstanceRaw {
#[allow(dead_code)] #[allow(dead_code)]
struct InstanceRaw {
model: [[f32; 4]; 4], model: [[f32; 4]; 4],
normal: [[f32; 3]; 3],
} }
impl InstanceRaw { impl model::Vertex for InstanceRaw {
fn desc() -> wgpu::VertexBufferLayout<'static> { fn desc() -> wgpu::VertexBufferLayout<'static> {
use std::mem; use std::mem;
wgpu::VertexBufferLayout { wgpu::VertexBufferLayout {
@ -206,11 +208,13 @@ impl InstanceRaw {
attributes: &[ attributes: &[
wgpu::VertexAttribute { wgpu::VertexAttribute {
offset: 0, offset: 0,
// While our vertex shader only uses locations 0, and 1 now, in later tutorials, we'll
// be using 2, 3, and 4 for Vertex. We'll start at slot 5 to not conflict with them later
shader_location: 5, shader_location: 5,
format: wgpu::VertexFormat::Float32x4, format: wgpu::VertexFormat::Float32x4,
}, },
// A mat4 takes up 4 vertex slots as it is technically 4 vec4s. We need to define a slot // A mat4 takes up 4 vertex slots as it is technically 4 vec4s. We need to define a slot
// for each vec4. We don't have to do this in code though. // for each vec4. We don't have to do this in code, though.
wgpu::VertexAttribute { wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress, offset: mem::size_of::<[f32; 4]>() as wgpu::BufferAddress,
shader_location: 6, shader_location: 6,
@ -226,6 +230,21 @@ impl InstanceRaw {
shader_location: 8, shader_location: 8,
format: wgpu::VertexFormat::Float32x4, format: wgpu::VertexFormat::Float32x4,
}, },
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 16]>() as wgpu::BufferAddress,
shader_location: 9,
format: wgpu::VertexFormat::Float32x3,
},
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 19]>() as wgpu::BufferAddress,
shader_location: 10,
format: wgpu::VertexFormat::Float32x3,
},
wgpu::VertexAttribute {
offset: mem::size_of::<[f32; 22]>() as wgpu::BufferAddress,
shader_location: 11,
format: wgpu::VertexFormat::Float32x3,
},
], ],
} }
} }
@ -430,14 +449,7 @@ impl<'a> State<'a> {
let position = cgmath::Vector3 { x, y: 0.0, z }; let position = cgmath::Vector3 { x, y: 0.0, z };
let rotation = if position.is_zero() { let rotation = cgmath::Quaternion::from_axis_angle((0.0, 1.0, 0.0).into(), cgmath::Deg(180.0));
cgmath::Quaternion::from_axis_angle(
cgmath::Vector3::unit_z(),
cgmath::Deg(0.0),
)
} else {
cgmath::Quaternion::from_axis_angle(position.normalize(), cgmath::Deg(45.0))
};
Instance { position, rotation } Instance { position, rotation }
}) })

View File

@ -1,5 +1,12 @@
// Vertex shader // Vertex shader
struct Light {
position: vec3<f32>,
color: vec3<f32>,
}
@group(2) @binding(0)
var<uniform> light: Light;
struct Camera { struct Camera {
view_proj: mat4x4<f32>, view_proj: mat4x4<f32>,
} }
@ -9,18 +16,24 @@ var<uniform> camera: Camera;
struct VertexInput { struct VertexInput {
@location(0) position: vec3<f32>, @location(0) position: vec3<f32>,
@location(1) tex_coords: vec2<f32>, @location(1) tex_coords: vec2<f32>,
} @location(2) normal: vec3<f32>,
};
struct InstanceInput { struct InstanceInput {
@location(5) model_matrix_0: vec4<f32>, @location(5) model_matrix_0: vec4<f32>,
@location(6) model_matrix_1: vec4<f32>, @location(6) model_matrix_1: vec4<f32>,
@location(7) model_matrix_2: vec4<f32>, @location(7) model_matrix_2: vec4<f32>,
@location(8) model_matrix_3: vec4<f32>, @location(8) model_matrix_3: vec4<f32>,
@location(9) normal_matrix_0: vec3<f32>,
@location(10) normal_matrix_1: vec3<f32>,
@location(11) normal_matrix_2: vec3<f32>,
} }
struct VertexOutput { struct VertexOutput {
@builtin(position) clip_position: vec4<f32>, @builtin(position) clip_position: vec4<f32>,
@location(0) tex_coords: vec2<f32>, @location(0) tex_coords: vec2<f32>,
} @location(1) world_normal: vec3<f32>,
@location(2) world_position: vec3<f32>,
};
@vertex @vertex
fn vs_main( fn vs_main(
@ -33,9 +46,18 @@ fn vs_main(
instance.model_matrix_2, instance.model_matrix_2,
instance.model_matrix_3, instance.model_matrix_3,
); );
let normal_matrix = mat3x3<f32>(
instance.normal_matrix_0,
instance.normal_matrix_1,
instance.normal_matrix_2,
);
var out: VertexOutput; var out: VertexOutput;
out.tex_coords = model.tex_coords; out.tex_coords = model.tex_coords;
out.clip_position = camera.view_proj * model_matrix * vec4<f32>(model.position, 1.0); out.world_normal = normal_matrix * model.normal;
var world_position: vec4<f32> = model_matrix * vec4<f32>(model.position, 1.0);
out.world_position = world_position.xyz;
out.clip_position = camera.view_proj * world_position;
return out; return out;
} }
@ -48,5 +70,18 @@ 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 object_color: vec4<f32> = textureSample(t_diffuse, s_diffuse, in.tex_coords);
let light_dir = normalize(light.position - in.world_position);
let diffuse_strength = max(dot(in.world_normal, light_dir), 0.0);
let diffuse_color = light.color * diffuse_strength;
// We don't need (or want) much ambient light, so 0.1 is fine
let ambient_strength = 0.1;
let ambient_color = light.color * ambient_strength;
let result = (ambient_color + diffuse_color) * object_color.xyz;
return vec4<f32>(result, object_color.a);
} }