separate global (light) and per-object (position) parameters
This commit is contained in:
parent
82638f7ad3
commit
be3ef2e4bd
37
src/lib.rs
37
src/lib.rs
|
|
@ -3,7 +3,7 @@ use std::{
|
||||||
f32::consts::{FRAC_PI_2, PI},
|
f32::consts::{FRAC_PI_2, PI},
|
||||||
};
|
};
|
||||||
|
|
||||||
use glam::{Affine3A, FloatExt, Mat4, Quat, UVec2, Vec3, Vec4, vec3, vec4};
|
use glam::{FloatExt, Mat4, Quat, UVec2, Vec3, Vec4, vec3, vec4};
|
||||||
|
|
||||||
use crate::render::mesh::GpuParams;
|
use crate::render::mesh::GpuParams;
|
||||||
|
|
||||||
|
|
@ -188,37 +188,42 @@ impl Core {
|
||||||
.to_mat4();
|
.to_mat4();
|
||||||
let view = Mat4::from_mat3(camera::rotation(-args.cam_yaw, -args.cam_pitch));
|
let view = Mat4::from_mat3(camera::rotation(-args.cam_yaw, -args.cam_pitch));
|
||||||
let light = vec3(0.7, 0.5, 1.0).normalize();
|
let light = vec3(0.7, 0.5, 1.0).normalize();
|
||||||
let set_params = |target: &GpuParams, color, tfm| {
|
|
||||||
target.set(
|
self.mesh_pipeline.set_params(
|
||||||
&self.queue,
|
&self.queue,
|
||||||
render::mesh::Params {
|
render::mesh::SceneParams {
|
||||||
mvp: proj * view * tfm,
|
projection: proj * view,
|
||||||
light,
|
light,
|
||||||
_zero: 0.,
|
_zero: 0.,
|
||||||
color: srgba_to_linear(color),
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
};
|
|
||||||
|
|
||||||
let turn_teeth = self.t;
|
let turn_teeth = self.t;
|
||||||
let bevel_turns = turn_teeth / self.bevel_gear_desc.teeth as f32;
|
let bevel_turns = -turn_teeth / self.bevel_gear_desc.teeth as f32;
|
||||||
let crown_skip_teeth = self.crown_gear_desc.pitch_radius.floor();
|
let crown_skip_teeth = self.crown_gear_desc.pitch_radius.floor();
|
||||||
let crown_turns =
|
let crown_turns =
|
||||||
(turn_teeth.fract_gl() + crown_skip_teeth) / (2. * self.crown_gear_desc.pitch_radius);
|
(turn_teeth.fract_gl() + crown_skip_teeth) / (2. * self.crown_gear_desc.pitch_radius);
|
||||||
|
|
||||||
set_params(
|
self.params_gear.set(
|
||||||
&self.params_gear,
|
&self.queue,
|
||||||
vec4(0.2, 0.8, 0.1, 1.0),
|
render::mesh::ObjectParams {
|
||||||
Affine3A::IDENTITY,
|
transform: Mat4::from_rotation_translation(
|
||||||
|
Quat::from_rotation_z(2. * PI * bevel_turns),
|
||||||
|
Vec3::ZERO,
|
||||||
|
),
|
||||||
|
color: srgba_to_linear(vec4(0.2, 0.8, 0.1, 1.0)),
|
||||||
|
},
|
||||||
);
|
);
|
||||||
set_params(
|
self.params_cutter.set(
|
||||||
&self.params_cutter,
|
&self.queue,
|
||||||
vec4(0.8, 0.2, 0.1, 1.0),
|
render::mesh::ObjectParams {
|
||||||
Affine3A::from_rotation_translation(
|
transform: Mat4::from_rotation_translation(
|
||||||
Quat::from_rotation_y(FRAC_PI_2 + self.bevel_gear_desc.cone_halfangle)
|
Quat::from_rotation_y(FRAC_PI_2 + self.bevel_gear_desc.cone_halfangle)
|
||||||
* Quat::from_rotation_z(2. * PI * crown_turns),
|
* Quat::from_rotation_z(2. * PI * crown_turns),
|
||||||
vec3(0., 0., self.bevel_gear_desc.pitch_distance()),
|
vec3(0., 0., self.bevel_gear_desc.pitch_distance()),
|
||||||
),
|
),
|
||||||
|
color: srgba_to_linear(vec4(0.8, 0.2, 0.1, 1.0)),
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
let view = output.create_view(&wgpu::TextureViewDescriptor::default());
|
let view = output.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,23 @@ pub struct Vertex {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
|
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct Params {
|
pub struct SceneParams {
|
||||||
pub mvp: Mat4,
|
pub projection: Mat4,
|
||||||
pub light: Vec3,
|
pub light: Vec3,
|
||||||
pub _zero: f32,
|
pub _zero: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct ObjectParams {
|
||||||
|
pub transform: Mat4,
|
||||||
pub color: Vec4,
|
pub color: Vec4,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Pipeline {
|
pub struct Pipeline {
|
||||||
pipeline: wgpu::RenderPipeline,
|
pipeline: wgpu::RenderPipeline,
|
||||||
|
params: wgpu::Buffer,
|
||||||
|
bindings: wgpu::BindGroup,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GpuMesh {
|
pub struct GpuMesh {
|
||||||
|
|
@ -153,7 +161,29 @@ impl Pipeline {
|
||||||
multiview: None,
|
multiview: None,
|
||||||
cache: None,
|
cache: None,
|
||||||
});
|
});
|
||||||
Self { pipeline }
|
let params = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
|
label: None,
|
||||||
|
size: size_of::<SceneParams>() as u64,
|
||||||
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
|
mapped_at_creation: false,
|
||||||
|
});
|
||||||
|
let bindings = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: None,
|
||||||
|
layout: &pipeline.get_bind_group_layout(0),
|
||||||
|
entries: &[wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: params.as_entire_binding(),
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
Self {
|
||||||
|
params,
|
||||||
|
bindings,
|
||||||
|
pipeline,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_params(&self, queue: &wgpu::Queue, params: SceneParams) {
|
||||||
|
queue.write_buffer(&self.params, 0, bytes_of(¶ms));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -161,13 +191,13 @@ impl GpuParams {
|
||||||
pub fn new(device: &wgpu::Device, pipeline: &Pipeline) -> Self {
|
pub fn new(device: &wgpu::Device, pipeline: &Pipeline) -> Self {
|
||||||
let params = device.create_buffer(&wgpu::BufferDescriptor {
|
let params = device.create_buffer(&wgpu::BufferDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
size: size_of::<Params>() as u64,
|
size: size_of::<ObjectParams>() as u64,
|
||||||
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
mapped_at_creation: false,
|
mapped_at_creation: false,
|
||||||
});
|
});
|
||||||
let bindings = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let bindings = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
label: None,
|
label: None,
|
||||||
layout: &pipeline.pipeline.get_bind_group_layout(0),
|
layout: &pipeline.pipeline.get_bind_group_layout(1),
|
||||||
entries: &[wgpu::BindGroupEntry {
|
entries: &[wgpu::BindGroupEntry {
|
||||||
binding: 0,
|
binding: 0,
|
||||||
resource: params.as_entire_binding(),
|
resource: params.as_entire_binding(),
|
||||||
|
|
@ -176,7 +206,7 @@ impl GpuParams {
|
||||||
Self { params, bindings }
|
Self { params, bindings }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set(&self, queue: &wgpu::Queue, params: Params) {
|
pub fn set(&self, queue: &wgpu::Queue, params: ObjectParams) {
|
||||||
queue.write_buffer(&self.params, 0, bytes_of(¶ms));
|
queue.write_buffer(&self.params, 0, bytes_of(¶ms));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -184,7 +214,8 @@ impl GpuParams {
|
||||||
impl GpuMesh {
|
impl GpuMesh {
|
||||||
pub fn render(&self, pass: &mut wgpu::RenderPass, pipeline: &Pipeline, params: &GpuParams) {
|
pub fn render(&self, pass: &mut wgpu::RenderPass, pipeline: &Pipeline, params: &GpuParams) {
|
||||||
pass.set_pipeline(&pipeline.pipeline);
|
pass.set_pipeline(&pipeline.pipeline);
|
||||||
pass.set_bind_group(0, ¶ms.bindings, &[]);
|
pass.set_bind_group(0, &pipeline.bindings, &[]);
|
||||||
|
pass.set_bind_group(1, ¶ms.bindings, &[]);
|
||||||
pass.set_vertex_buffer(0, self.vertices.slice(..));
|
pass.set_vertex_buffer(0, self.vertices.slice(..));
|
||||||
pass.draw(0..self.vertex_count, 0..1);
|
pass.draw(0..self.vertex_count, 0..1);
|
||||||
}
|
}
|
||||||
|
|
@ -193,7 +224,8 @@ impl GpuMesh {
|
||||||
impl GpuMeshIndexed {
|
impl GpuMeshIndexed {
|
||||||
pub fn render(&self, pass: &mut wgpu::RenderPass, pipeline: &Pipeline, params: &GpuParams) {
|
pub fn render(&self, pass: &mut wgpu::RenderPass, pipeline: &Pipeline, params: &GpuParams) {
|
||||||
pass.set_pipeline(&pipeline.pipeline);
|
pass.set_pipeline(&pipeline.pipeline);
|
||||||
pass.set_bind_group(0, ¶ms.bindings, &[]);
|
pass.set_bind_group(0, &pipeline.bindings, &[]);
|
||||||
|
pass.set_bind_group(1, ¶ms.bindings, &[]);
|
||||||
pass.set_vertex_buffer(0, self.vertices.slice(..));
|
pass.set_vertex_buffer(0, self.vertices.slice(..));
|
||||||
pass.set_index_buffer(self.indices.slice(..), wgpu::IndexFormat::Uint16);
|
pass.set_index_buffer(self.indices.slice(..), wgpu::IndexFormat::Uint16);
|
||||||
pass.draw_indexed(0..self.index_count, 0, 0..1);
|
pass.draw_indexed(0..self.index_count, 0, 0..1);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,11 @@
|
||||||
struct Params {
|
struct SceneParams {
|
||||||
mvp: mat4x4f,
|
projection: mat4x4f,
|
||||||
light: vec3f,
|
light: vec3f,
|
||||||
_zero: f32,
|
_zero: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ObjectParams {
|
||||||
|
transform: mat4x4f,
|
||||||
color: vec4f,
|
color: vec4f,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -15,20 +19,21 @@ struct Varying {
|
||||||
@location(0) normal: vec3f,
|
@location(0) normal: vec3f,
|
||||||
}
|
}
|
||||||
|
|
||||||
@group(0) @binding(0) var<uniform> params: Params;
|
@group(0) @binding(0) var<uniform> scene_params: SceneParams;
|
||||||
|
@group(1) @binding(0) var<uniform> object_params: ObjectParams;
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
fn on_vertex(in: Vertex) -> Varying {
|
fn on_vertex(in: Vertex) -> Varying {
|
||||||
let position = params.mvp * vec4f(in.position, 1.0);
|
let position = scene_params.projection * object_params.transform * vec4f(in.position, 1.0);
|
||||||
let normal = in.normal;
|
let normal = normalize((object_params.transform * vec4(in.normal, 0.0)).xyz);
|
||||||
return Varying(position, normal);
|
return Varying(position, normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn on_fragment(in: Varying) -> @location(0) vec4f {
|
fn on_fragment(in: Varying) -> @location(0) vec4f {
|
||||||
let normal = normalize(in.normal);
|
let normal = normalize(in.normal);
|
||||||
let light = dot(params.light, normal);
|
let light = dot(scene_params.light, normal);
|
||||||
let u = 0.5 + 0.5 * light;
|
let u = 0.5 + 0.5 * light;
|
||||||
let color = vec4f(u * params.color.xyz, params.color.w);
|
let color = vec4f(u * object_params.color.xyz, object_params.color.w);
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user