Dont duplicate model verts for flat shading
This commit is contained in:
@@ -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],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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 {
|
||||
|
@@ -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();
|
||||
|
||||
|
@@ -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,
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user