Dont duplicate model verts for flat shading

This commit is contained in:
Connor Slade
2025-02-09 11:17:28 -05:00
parent 738a22bce5
commit fc51037e82
7 changed files with 46 additions and 68 deletions

View File

@@ -2,6 +2,7 @@ use std::mem;
use dispatch::solid_line::SolidLineDispatch;
use eframe::CreationContext;
use nalgebra::Vector4;
use pipelines::{
model::ModelPipeline, slice_preview::SlicePreviewPipeline, target_point::TargetPointPipeline,
};
@@ -20,25 +21,17 @@ pub mod workspace;
pub const VERTEX_BUFFER_LAYOUT: VertexBufferLayout = VertexBufferLayout {
array_stride: mem::size_of::<ModelVertex>() as BufferAddress,
step_mode: VertexStepMode::Vertex,
attributes: &[
VertexAttribute {
format: VertexFormat::Float32x4,
offset: 0,
shader_location: 0,
},
VertexAttribute {
format: VertexFormat::Float32x3,
offset: 4 * 4,
shader_location: 1,
},
],
attributes: &[VertexAttribute {
format: VertexFormat::Float32x4,
offset: 0,
shader_location: 0,
}],
};
#[repr(C)]
#[derive(Default, Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
pub struct ModelVertex {
pub position: [f32; 4],
pub normal: [f32; 3],
}
pub fn init_wgpu(cc: &CreationContext) {
@@ -55,3 +48,11 @@ pub fn init_wgpu(cc: &CreationContext) {
slice_preview_pipeline: SlicePreviewPipeline::new(device),
});
}
impl ModelVertex {
pub fn new(pos: Vector4<f32>) -> Self {
Self {
position: [pos.x, pos.y, pos.z, pos.w],
}
}
}

View File

@@ -105,7 +105,6 @@ impl SlicePreviewPipeline {
.into_iter()
.map(|[x, y]| ModelVertex {
position: [x, y, 0.0, 1.0],
normal: [0.0, 0.0, 1.0],
})
.collect::<Vec<_>>();
let vertex_buffer = device.create_buffer_init(&BufferInitDescriptor {

View File

@@ -176,7 +176,6 @@ fn generate_sphere(precision: usize) -> (Vec<ModelVertex>, Vec<u32>) {
x.2.into_inner() as f32,
1.0,
],
normal: [0.0, 0.0, 0.0],
})
.collect();

View File

@@ -21,6 +21,7 @@ pub struct RenderedMesh {
pub locked_scale: bool,
vertices: Vec<ModelVertex>,
index: Vec<u32>,
buffers: Option<RenderedMeshBuffers>,
}
@@ -31,32 +32,13 @@ pub struct RenderedMeshBuffers {
impl RenderedMesh {
pub fn from_mesh(mesh: Mesh) -> Self {
let mut out = Vec::new();
let (vertices, faces) = (mesh.vertices(), mesh.faces());
let (vertices, normals) = (mesh.vertices(), mesh.normals());
for (i, face) in mesh.faces().iter().enumerate() {
let (a, b, c) = (
vertices[face[0] as usize],
vertices[face[1] as usize],
vertices[face[2] as usize],
);
let normal = normals[i];
out.extend_from_slice(&[
ModelVertex {
position: [a.x, a.y, a.z, 1.0],
normal: normal.into(),
},
ModelVertex {
position: [b.x, b.y, b.z, 1.0],
normal: normal.into(),
},
ModelVertex {
position: [c.x, c.y, c.z, 1.0],
normal: normal.into(),
},
]);
}
let index = faces.iter().flatten().copied().collect::<Vec<_>>();
let vertices = vertices
.iter()
.map(|vert| ModelVertex::new(vert.push(1.0)))
.collect();
Self {
name: String::new(),
@@ -65,7 +47,8 @@ impl RenderedMesh {
color: Color32::WHITE,
hidden: false,
locked_scale: true,
vertices: out,
index,
vertices,
buffers: None,
}
}
@@ -121,9 +104,7 @@ impl RenderedMesh {
let index_buffer = device.create_buffer_init(&BufferInitDescriptor {
label: None,
contents: bytemuck::cast_slice(
&(0..self.mesh.face_count() as u32 * 3).collect::<Vec<u32>>(),
),
contents: bytemuck::cast_slice(&self.index),
usage: BufferUsages::INDEX | BufferUsages::COPY_DST,
});
@@ -147,6 +128,7 @@ impl Clone for RenderedMesh {
hidden: self.hidden,
locked_scale: self.locked_scale,
vertices: self.vertices.clone(),
index: self.index.clone(),
buffers: None,
}
}

View File

@@ -9,37 +9,43 @@ struct Context {
render_style: u32,
}
struct VertexInput {
@location(0)
position: vec4<f32>
}
struct VertexOutput {
@builtin(position)
position: vec4<f32>,
@location(1)
normal: vec3<f32>,
world_position: vec3<f32>
};
@vertex
fn vert(
@location(0) position: vec4<f32>,
@location(1) normal: vec3<f32>,
) -> VertexOutput {
fn vert(in: VertexInput) -> VertexOutput {
var out: VertexOutput;
out.position = context.transform * position;
out.normal = normalize((context.model_transform * vec4(normal, 0.0)).xyz);
out.position = context.transform * in.position;
out.world_position = (context.model_transform * in.position).xyz;
return out;
}
@fragment
fn frag(in: VertexOutput) -> @location(0) vec4<f32> {
let dy = dpdy(in.world_position);
let dx = dpdx(in.world_position);
let normal = normalize(cross(dy, dx));
if context.render_style == 0 {
return vec4<f32>(in.normal, 1.0);
return vec4<f32>(normal, 1.0);
} else {
let camera_direction = normalize(context.camera_position + context.camera_target);
let diffuse = max(dot(in.normal, camera_direction), 0.0);
let diffuse = max(dot(normal, camera_direction), 0.0);
let reflect_dir = reflect(-camera_direction, in.normal);
let reflect_dir = reflect(-camera_direction, normal);
let specular = pow(max(dot(camera_direction, reflect_dir), 0.0), 32.0);
let intensity = (diffuse + specular + 0.1) * context.model_color.rgb;
return vec4<f32>(intensity, context.model_color.a);
}
}
}

View File

@@ -15,10 +15,7 @@ struct VertexOutput {
};
@vertex
fn vert(
@location(0) position: vec4<f32>,
@location(1) normal: vec3<f32>,
) -> VertexOutput {
fn vert(@location(0) position: vec4<f32>) -> VertexOutput {
var out: VertexOutput;
out.camera_position = position;
out.position = position;
@@ -42,4 +39,4 @@ fn frag(in: VertexOutput) -> @location(0) vec4<f32> {
u32(pos.y * f32(context.dimensions.y) + context.offset.y)
);
return vec4<f32>(value, value, value, 1.0);
}
}

View File

@@ -8,22 +8,16 @@ struct Context {
struct VertexOutput {
@builtin(position)
position: vec4<f32>,
@location(0)
normal: vec3<f32>,
};
@vertex
fn vert(
@location(0) position: vec4<f32>,
@location(1) normal: vec3<f32>,
) -> VertexOutput {
fn vert(@location(0) position: vec4<f32>) -> VertexOutput {
var out: VertexOutput;
out.position = context.transform * position;
out.normal = normal;
return out;
}
@fragment
fn frag(in: VertexOutput) -> @location(0) vec4<f32> {
return context.color;
}
}