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 dispatch::solid_line::SolidLineDispatch;
|
||||||
use eframe::CreationContext;
|
use eframe::CreationContext;
|
||||||
|
use nalgebra::Vector4;
|
||||||
use pipelines::{
|
use pipelines::{
|
||||||
model::ModelPipeline, slice_preview::SlicePreviewPipeline, target_point::TargetPointPipeline,
|
model::ModelPipeline, slice_preview::SlicePreviewPipeline, target_point::TargetPointPipeline,
|
||||||
};
|
};
|
||||||
@@ -20,25 +21,17 @@ pub mod workspace;
|
|||||||
pub const VERTEX_BUFFER_LAYOUT: VertexBufferLayout = VertexBufferLayout {
|
pub const VERTEX_BUFFER_LAYOUT: VertexBufferLayout = VertexBufferLayout {
|
||||||
array_stride: mem::size_of::<ModelVertex>() as BufferAddress,
|
array_stride: mem::size_of::<ModelVertex>() as BufferAddress,
|
||||||
step_mode: VertexStepMode::Vertex,
|
step_mode: VertexStepMode::Vertex,
|
||||||
attributes: &[
|
attributes: &[VertexAttribute {
|
||||||
VertexAttribute {
|
format: VertexFormat::Float32x4,
|
||||||
format: VertexFormat::Float32x4,
|
offset: 0,
|
||||||
offset: 0,
|
shader_location: 0,
|
||||||
shader_location: 0,
|
}],
|
||||||
},
|
|
||||||
VertexAttribute {
|
|
||||||
format: VertexFormat::Float32x3,
|
|
||||||
offset: 4 * 4,
|
|
||||||
shader_location: 1,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Default, Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
#[derive(Default, Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
||||||
pub struct ModelVertex {
|
pub struct ModelVertex {
|
||||||
pub position: [f32; 4],
|
pub position: [f32; 4],
|
||||||
pub normal: [f32; 3],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_wgpu(cc: &CreationContext) {
|
pub fn init_wgpu(cc: &CreationContext) {
|
||||||
@@ -55,3 +48,11 @@ pub fn init_wgpu(cc: &CreationContext) {
|
|||||||
slice_preview_pipeline: SlicePreviewPipeline::new(device),
|
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()
|
.into_iter()
|
||||||
.map(|[x, y]| ModelVertex {
|
.map(|[x, y]| ModelVertex {
|
||||||
position: [x, y, 0.0, 1.0],
|
position: [x, y, 0.0, 1.0],
|
||||||
normal: [0.0, 0.0, 1.0],
|
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let vertex_buffer = device.create_buffer_init(&BufferInitDescriptor {
|
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,
|
x.2.into_inner() as f32,
|
||||||
1.0,
|
1.0,
|
||||||
],
|
],
|
||||||
normal: [0.0, 0.0, 0.0],
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
@@ -21,6 +21,7 @@ pub struct RenderedMesh {
|
|||||||
pub locked_scale: bool,
|
pub locked_scale: bool,
|
||||||
|
|
||||||
vertices: Vec<ModelVertex>,
|
vertices: Vec<ModelVertex>,
|
||||||
|
index: Vec<u32>,
|
||||||
buffers: Option<RenderedMeshBuffers>,
|
buffers: Option<RenderedMeshBuffers>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,32 +32,13 @@ pub struct RenderedMeshBuffers {
|
|||||||
|
|
||||||
impl RenderedMesh {
|
impl RenderedMesh {
|
||||||
pub fn from_mesh(mesh: Mesh) -> Self {
|
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());
|
let index = faces.iter().flatten().copied().collect::<Vec<_>>();
|
||||||
for (i, face) in mesh.faces().iter().enumerate() {
|
let vertices = vertices
|
||||||
let (a, b, c) = (
|
.iter()
|
||||||
vertices[face[0] as usize],
|
.map(|vert| ModelVertex::new(vert.push(1.0)))
|
||||||
vertices[face[1] as usize],
|
.collect();
|
||||||
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(),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
name: String::new(),
|
name: String::new(),
|
||||||
@@ -65,7 +47,8 @@ impl RenderedMesh {
|
|||||||
color: Color32::WHITE,
|
color: Color32::WHITE,
|
||||||
hidden: false,
|
hidden: false,
|
||||||
locked_scale: true,
|
locked_scale: true,
|
||||||
vertices: out,
|
index,
|
||||||
|
vertices,
|
||||||
buffers: None,
|
buffers: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,9 +104,7 @@ impl RenderedMesh {
|
|||||||
|
|
||||||
let index_buffer = device.create_buffer_init(&BufferInitDescriptor {
|
let index_buffer = device.create_buffer_init(&BufferInitDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
contents: bytemuck::cast_slice(
|
contents: bytemuck::cast_slice(&self.index),
|
||||||
&(0..self.mesh.face_count() as u32 * 3).collect::<Vec<u32>>(),
|
|
||||||
),
|
|
||||||
usage: BufferUsages::INDEX | BufferUsages::COPY_DST,
|
usage: BufferUsages::INDEX | BufferUsages::COPY_DST,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -147,6 +128,7 @@ impl Clone for RenderedMesh {
|
|||||||
hidden: self.hidden,
|
hidden: self.hidden,
|
||||||
locked_scale: self.locked_scale,
|
locked_scale: self.locked_scale,
|
||||||
vertices: self.vertices.clone(),
|
vertices: self.vertices.clone(),
|
||||||
|
index: self.index.clone(),
|
||||||
buffers: None,
|
buffers: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,37 +9,43 @@ struct Context {
|
|||||||
render_style: u32,
|
render_style: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct VertexInput {
|
||||||
|
@location(0)
|
||||||
|
position: vec4<f32>
|
||||||
|
}
|
||||||
|
|
||||||
struct VertexOutput {
|
struct VertexOutput {
|
||||||
@builtin(position)
|
@builtin(position)
|
||||||
position: vec4<f32>,
|
position: vec4<f32>,
|
||||||
@location(1)
|
@location(1)
|
||||||
normal: vec3<f32>,
|
world_position: vec3<f32>
|
||||||
};
|
};
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vert(
|
fn vert(in: VertexInput) -> VertexOutput {
|
||||||
@location(0) position: vec4<f32>,
|
|
||||||
@location(1) normal: vec3<f32>,
|
|
||||||
) -> VertexOutput {
|
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
out.position = context.transform * position;
|
out.position = context.transform * in.position;
|
||||||
out.normal = normalize((context.model_transform * vec4(normal, 0.0)).xyz);
|
out.world_position = (context.model_transform * in.position).xyz;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn frag(in: VertexOutput) -> @location(0) vec4<f32> {
|
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 {
|
if context.render_style == 0 {
|
||||||
return vec4<f32>(in.normal, 1.0);
|
return vec4<f32>(normal, 1.0);
|
||||||
} else {
|
} else {
|
||||||
let camera_direction = normalize(context.camera_position + context.camera_target);
|
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 specular = pow(max(dot(camera_direction, reflect_dir), 0.0), 32.0);
|
||||||
|
|
||||||
let intensity = (diffuse + specular + 0.1) * context.model_color.rgb;
|
let intensity = (diffuse + specular + 0.1) * context.model_color.rgb;
|
||||||
return vec4<f32>(intensity, context.model_color.a);
|
return vec4<f32>(intensity, context.model_color.a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,10 +15,7 @@ struct VertexOutput {
|
|||||||
};
|
};
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vert(
|
fn vert(@location(0) position: vec4<f32>) -> VertexOutput {
|
||||||
@location(0) position: vec4<f32>,
|
|
||||||
@location(1) normal: vec3<f32>,
|
|
||||||
) -> VertexOutput {
|
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
out.camera_position = position;
|
out.camera_position = position;
|
||||||
out.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)
|
u32(pos.y * f32(context.dimensions.y) + context.offset.y)
|
||||||
);
|
);
|
||||||
return vec4<f32>(value, value, value, 1.0);
|
return vec4<f32>(value, value, value, 1.0);
|
||||||
}
|
}
|
||||||
|
@@ -8,22 +8,16 @@ struct Context {
|
|||||||
struct VertexOutput {
|
struct VertexOutput {
|
||||||
@builtin(position)
|
@builtin(position)
|
||||||
position: vec4<f32>,
|
position: vec4<f32>,
|
||||||
@location(0)
|
|
||||||
normal: vec3<f32>,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn vert(
|
fn vert(@location(0) position: vec4<f32>) -> VertexOutput {
|
||||||
@location(0) position: vec4<f32>,
|
|
||||||
@location(1) normal: vec3<f32>,
|
|
||||||
) -> VertexOutput {
|
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
out.position = context.transform * position;
|
out.position = context.transform * position;
|
||||||
out.normal = normal;
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn frag(in: VertexOutput) -> @location(0) vec4<f32> {
|
fn frag(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
return context.color;
|
return context.color;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user