Skip to content

Commit

Permalink
skinning WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
schell committed May 10, 2024
1 parent 2d85a45 commit 1a876e1
Show file tree
Hide file tree
Showing 11 changed files with 245 additions and 668 deletions.
438 changes: 9 additions & 429 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ gltf = { git = 'https://github.com/schell/gltf.git', branch ="feature/channel-sa
image = "0.24"
log = "0.4"
naga = { version = "0.19", features = ["spv-in", "wgsl-out", "wgsl-in", "msl-out"] }
plotters = "0.3"
pretty_assertions = "1.4.0"
proc-macro2 = { version = "1.0", features = ["span-locations"] }
glam = { version = "0.24.2", default-features = false }
Expand Down
25 changes: 9 additions & 16 deletions crates/example/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use renderling::{
math::{Mat4, UVec2, Vec3, Vec4},
skybox::Skybox,
slab::Hybrid,
stage::{Animator, GltfDocument, Node, Stage},
stage::{Animator, GltfDocument, Stage},
transform::Transform,
Context,
};
Expand Down Expand Up @@ -68,7 +68,6 @@ pub struct App {
camera: Hybrid<Camera>,

document: Option<GltfDocument>,
nodes: Option<Vec<Node>>,
animators: Option<Vec<Animator>>,
animations_conflict: bool,

Expand Down Expand Up @@ -106,7 +105,6 @@ impl App {
camera,

document: None,
nodes: None,
animators: None,
animations_conflict: false,

Expand Down Expand Up @@ -162,11 +160,13 @@ impl App {
self.last_cursor_position = None;
self.stage.set_images(std::iter::empty()).unwrap();
self.document = None;
self.nodes = None;
log::debug!("ticking stage to reclaim buffers");
self.stage.tick();

let mut doc = match self.stage.load_gltf_document_from_bytes(bytes) {
let doc = match self
.stage
.load_gltf_document_from_bytes(bytes, self.camera.id())
{
Err(e) => {
log::error!("gltf loading error: {e}");
return;
Expand Down Expand Up @@ -204,13 +204,7 @@ impl App {
}
}
}
let nodes = match self.stage.draw_gltf_scene(&doc, nodes, self.camera.id()) {
Err(e) => {
log::error!("could not draw scene: {e}");
vec![]
}
Ok(ns) => ns,
};

if doc.animations.is_empty() {
log::trace!(" animations: none");
} else {
Expand All @@ -219,8 +213,8 @@ impl App {
let mut animated_nodes = HashSet::default();
let mut has_conflicting_animations = false;
self.animators = Some(
std::mem::take(&mut doc.animations)
.into_iter()
doc.animations
.iter()
.enumerate()
.map(|(i, a)| {
let target_nodes = a.target_node_indices().collect::<HashSet<_>>();
Expand All @@ -236,15 +230,14 @@ impl App {
tween.properties.description()
);
}
Animator::new(&nodes, a)
Animator::new(doc.nodes.iter(), a.clone())
})
.collect(),
);
if has_conflicting_animations {
log::trace!(" and some animations conflict");
}
self.animations_conflict = has_conflicting_animations;
self.nodes = Some(nodes);
self.document = Some(doc);

let halfway_point = min + ((max - min).normalize() * ((max - min).length() / 2.0));
Expand Down
2 changes: 0 additions & 2 deletions crates/renderling/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -119,13 +119,11 @@ features = ["gltf", "raw-window-handle", "winit"]

[dev-dependencies]
assert_approx_eq = {workspace = true}
criterion = { version = "0.5", features = ["html_reports"] }
ctor = "0.2.2"
env_logger = {workspace = true}
icosahedron = "0.1"
img-diff = { path = "../img-diff" }
naga.workspace = true
plotters.workspace = true
pretty_assertions.workspace = true
ttf-parser = "0.20.0"

Expand Down
12 changes: 5 additions & 7 deletions crates/renderling/src/bloom/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -713,21 +713,19 @@ mod test {
let height = 128;
let ctx = Context::headless(width, height);
let mut stage = ctx.new_stage().with_bloom(false);
let doc = stage
.load_gltf_document_from_path("../../gltf/EmissiveStrengthTest.glb")
.unwrap();

let projection = crate::camera::perspective(width as f32, height as f32);
let view = crate::camera::look_at(Vec3::new(0.0, 2.0, 18.0), Vec3::ZERO, Vec3::Y);
let camera = stage.new_value(Camera::new(projection, view));
let skybox = stage
.new_skybox_from_path("../../img/hdr/night.hdr", camera.id())
.unwrap();
stage.set_skybox(skybox);
let scene_index = doc.default_scene.unwrap();
let nodes = doc.scenes.get(scene_index).unwrap();
let _scene = stage
.draw_gltf_scene(&doc, nodes.into_iter().copied(), camera.id())

let _doc = stage
.load_gltf_document_from_path("../../gltf/EmissiveStrengthTest.glb", camera.id())
.unwrap();

let frame = ctx.get_next_frame().unwrap();
stage.render(&frame.view());
let img = frame.read_image().unwrap();
Expand Down
Binary file modified crates/renderling/src/linkage/stage-renderlet_fragment.spv
Binary file not shown.
Binary file modified crates/renderling/src/linkage/stage-renderlet_vertex.spv
Binary file not shown.
Binary file not shown.
35 changes: 20 additions & 15 deletions crates/renderling/src/stage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pub use gltf_support::*;
/// For more info on vertex skinning, see
/// <https://github.khronos.org/glTF-Tutorials/gltfTutorial/gltfTutorial_019_SimpleSkin.html>
#[derive(Clone, Copy, Default, SlabItem)]
#[cfg_attr(not(target_arch = "spirv"), derive(Debug))]
pub struct Skin {
// Ids of the skeleton nodes' global transforms used as joints in this skin.
pub joints: Array<Id<Transform>>,
Expand All @@ -45,22 +46,27 @@ pub struct Skin {
}

impl Skin {
pub fn get_transform(&self, vertex: Vertex, slab: &[u32]) -> Transform {
pub fn get_transform(&self, vertex: Vertex, slab: &[u32]) -> Mat4 {
let mut mat = Mat4::ZERO;
for i in 0..vertex.joints.len() {
let joint_weight = vertex.weights[i];
if joint_weight == 0.0 {
continue;
}

let inverse_bind_matrix = slab.read(self.inverse_bind_matrices.at(i));

let joint_index = vertex.joints[i] as usize;
let joint_id = slab.read(self.joints.at(joint_index));
let inverse_bind_matrix = slab.read(self.inverse_bind_matrices.at(i));
let joint_matrix = Mat4::from(slab.read(joint_id)) * inverse_bind_matrix;
let joint_weight = vertex.weights[i];
mat += joint_weight * joint_matrix;

mat += joint_matrix * joint_weight;
}
let mat = if mat == Mat4::ZERO {
if mat == Mat4::ZERO {
Mat4::IDENTITY
} else {
mat
};
Transform::from(mat)
}
}
}

Expand Down Expand Up @@ -245,6 +251,8 @@ pub fn renderlet_vertex(
out_world_pos: &mut Vec3,
#[spirv(position)] out_clip_pos: &mut Vec4,
) {
use crate::math::IsMatrix;

let renderlet = slab.read_unchecked(renderlet_id);

let mut vertex_log = RenderletVertexLog::new(renderlet_id, renderlet.debug_index, vertex_index);
Expand All @@ -266,18 +274,15 @@ pub fn renderlet_vertex(
*out_uv0 = vertex.uv0;
*out_uv1 = vertex.uv1;

let transform = if renderlet.skin_id.is_some() {
let model_matrix = if renderlet.skin_id.is_some() {
let skin = slab.read(renderlet.skin_id);
skin.get_transform(vertex, slab)
} else {
slab.read(renderlet.transform_id)
let t = slab.read(renderlet.transform_id);
Mat4::from(t)
};
let model_matrix = Mat4::from_scale_rotation_translation(
transform.scale,
transform.rotation,
transform.translation,
);
let scale2 = transform.scale * transform.scale;
let (scale, _, _) = model_matrix.to_scale_rotation_translation_or_id();
let scale2 = scale * scale;
let normal = vertex.normal.alt_norm_or_zero();
let tangent = vertex.tangent.xyz().alt_norm_or_zero();
let normal_w: Vec3 = (model_matrix * (normal / scale2).extend(0.0))
Expand Down
Loading

0 comments on commit 1a876e1

Please sign in to comment.