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},
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
|
|
@ -188,37 +188,42 @@ impl Core {
|
|||
.to_mat4();
|
||||
let view = Mat4::from_mat3(camera::rotation(-args.cam_yaw, -args.cam_pitch));
|
||||
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,
|
||||
render::mesh::Params {
|
||||
mvp: proj * view * tfm,
|
||||
render::mesh::SceneParams {
|
||||
projection: proj * view,
|
||||
light,
|
||||
_zero: 0.,
|
||||
color: srgba_to_linear(color),
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
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_turns =
|
||||
(turn_teeth.fract_gl() + crown_skip_teeth) / (2. * self.crown_gear_desc.pitch_radius);
|
||||
|
||||
set_params(
|
||||
&self.params_gear,
|
||||
vec4(0.2, 0.8, 0.1, 1.0),
|
||||
Affine3A::IDENTITY,
|
||||
self.params_gear.set(
|
||||
&self.queue,
|
||||
render::mesh::ObjectParams {
|
||||
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,
|
||||
vec4(0.8, 0.2, 0.1, 1.0),
|
||||
Affine3A::from_rotation_translation(
|
||||
self.params_cutter.set(
|
||||
&self.queue,
|
||||
render::mesh::ObjectParams {
|
||||
transform: Mat4::from_rotation_translation(
|
||||
Quat::from_rotation_y(FRAC_PI_2 + self.bevel_gear_desc.cone_halfangle)
|
||||
* Quat::from_rotation_z(2. * PI * crown_turns),
|
||||
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());
|
||||
|
|
|
|||
|
|
@ -19,15 +19,23 @@ pub struct Vertex {
|
|||
|
||||
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
|
||||
#[repr(C)]
|
||||
pub struct Params {
|
||||
pub mvp: Mat4,
|
||||
pub struct SceneParams {
|
||||
pub projection: Mat4,
|
||||
pub light: Vec3,
|
||||
pub _zero: f32,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Zeroable, Pod)]
|
||||
#[repr(C)]
|
||||
pub struct ObjectParams {
|
||||
pub transform: Mat4,
|
||||
pub color: Vec4,
|
||||
}
|
||||
|
||||
pub struct Pipeline {
|
||||
pipeline: wgpu::RenderPipeline,
|
||||
params: wgpu::Buffer,
|
||||
bindings: wgpu::BindGroup,
|
||||
}
|
||||
|
||||
pub struct GpuMesh {
|
||||
|
|
@ -153,7 +161,29 @@ impl Pipeline {
|
|||
multiview: 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 {
|
||||
let params = device.create_buffer(&wgpu::BufferDescriptor {
|
||||
label: None,
|
||||
size: size_of::<Params>() as u64,
|
||||
size: size_of::<ObjectParams>() 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.pipeline.get_bind_group_layout(0),
|
||||
layout: &pipeline.pipeline.get_bind_group_layout(1),
|
||||
entries: &[wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: params.as_entire_binding(),
|
||||
|
|
@ -176,7 +206,7 @@ impl GpuParams {
|
|||
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));
|
||||
}
|
||||
}
|
||||
|
|
@ -184,7 +214,8 @@ impl GpuParams {
|
|||
impl GpuMesh {
|
||||
pub fn render(&self, pass: &mut wgpu::RenderPass, pipeline: &Pipeline, params: &GpuParams) {
|
||||
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.draw(0..self.vertex_count, 0..1);
|
||||
}
|
||||
|
|
@ -193,7 +224,8 @@ impl GpuMesh {
|
|||
impl GpuMeshIndexed {
|
||||
pub fn render(&self, pass: &mut wgpu::RenderPass, pipeline: &Pipeline, params: &GpuParams) {
|
||||
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_index_buffer(self.indices.slice(..), wgpu::IndexFormat::Uint16);
|
||||
pass.draw_indexed(0..self.index_count, 0, 0..1);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
struct Params {
|
||||
mvp: mat4x4f,
|
||||
struct SceneParams {
|
||||
projection: mat4x4f,
|
||||
light: vec3f,
|
||||
_zero: f32,
|
||||
}
|
||||
|
||||
struct ObjectParams {
|
||||
transform: mat4x4f,
|
||||
color: vec4f,
|
||||
}
|
||||
|
||||
|
|
@ -15,20 +19,21 @@ struct Varying {
|
|||
@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
|
||||
fn on_vertex(in: Vertex) -> Varying {
|
||||
let position = params.mvp * vec4f(in.position, 1.0);
|
||||
let normal = in.normal;
|
||||
let position = scene_params.projection * object_params.transform * vec4f(in.position, 1.0);
|
||||
let normal = normalize((object_params.transform * vec4(in.normal, 0.0)).xyz);
|
||||
return Varying(position, normal);
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn on_fragment(in: Varying) -> @location(0) vec4f {
|
||||
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 color = vec4f(u * params.color.xyz, params.color.w);
|
||||
let color = vec4f(u * object_params.color.xyz, object_params.color.w);
|
||||
return color;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user