diff --git a/app/src/main/rust/cargo.toml b/app/src/main/rust/cargo.toml index 54b6246..7a4594b 100644 --- a/app/src/main/rust/cargo.toml +++ b/app/src/main/rust/cargo.toml @@ -21,7 +21,7 @@ bytemuck = { version = "1.25", features = ["derive"] } glam = { version = "0.33", features = ["bytemuck", "mint"] } mint = "0.5" openxr = { git = "https://github.com/Ralith/openxrs.git", rev = "294809e4fe7f6f9729c80526f5320d7d70408984", default-features = false, features = ["mint"] } -vk-graph = { version = "0.14.5" } +vk-graph = { git = "https://github.com/attackgoat/vk-graph.git", branch = "descriptor-set" } egui = { version = "0.35.0", features = [ "bytemuck" ] } gltf = { version = "1.4", features = [ "extras", "names" ] } diff --git a/app/src/main/rust/src/app.rs b/app/src/main/rust/src/app.rs index 3cea0e4..7dc98a7 100644 --- a/app/src/main/rust/src/app.rs +++ b/app/src/main/rust/src/app.rs @@ -1,3 +1,7 @@ +use log::warn; +use vk_graph::driver::ash::vk::DeviceSize; +use vk_graph::driver::buffer::BufferInfo; +use vk_graph::pool::Pool; use { std::{ time::{Instant, Duration}, @@ -35,6 +39,7 @@ use { }, log::info, }; +use crate::render::renderer::{RenderingError, XrCameraUBO}; pub struct XrSession { pub(crate) running: bool, @@ -163,7 +168,20 @@ pub fn main_loop(env: &mut Env<'_>, ctx: Arc, raw_asset_manager: *mu let mut context = XrContext::new(Arc::clone(&ctx)); let mut renderer = Renderer::new(&context, internal_files_directory.as_path()); let input = InputState::new(&context.instance, &context.session.session); - let mut scene = Scene::load(&context.instance.device, &asset_manager); + + let mut mapped_camera_buffers = Vec::new(); + let mut camera_buffers = Vec::new(); + (0..context.swapchain.enumerate_images().unwrap().len()).for_each(|_| { + let mut buffer = Buffer::create(&context.instance.device, BufferInfo::builder() + .host_writable(true) + .size(size_of::() as DeviceSize) + .usage(BufferUsageFlags::UNIFORM_BUFFER)) + .expect("Failed to allocate camera buffer"); + mapped_camera_buffers.push(buffer.mapped_slice_mut().as_mut_ptr() as *mut XrCameraUBO); + camera_buffers.push(Arc::new(buffer)); + }); + + let mut scene = Scene::load(&context.instance.device, &camera_buffers, &asset_manager); // if you're looking how to load assets n shit, it's in the scene ^^ let names: Vec<&str> = scene.assets.animated_asset.animation_names().collect(); @@ -202,7 +220,7 @@ pub fn main_loop(env: &mut Env<'_>, ctx: Arc, raw_asset_manager: *mu Ok(frame) => frame, Err(err) => { match err { - renderer::RenderingError::Sleeping => { + RenderingError::Sleeping => { sleep(Duration::from_millis(100)); log::trace!("sleeping...") }, @@ -275,6 +293,15 @@ pub fn main_loop(env: &mut Env<'_>, ctx: Arc, raw_asset_manager: *mu } Err(err) => log::error!("Bad skin supplied from java-side: {:?}", err) } + + + if let Some(ref skin) = *scene.assets.skin.read().unwrap() { + scene.assets.animated_instance.override_textures(&skin.texture, &camera_buffers); + scene.assets.left_controller_scene_instance.override_textures(&skin.texture, &camera_buffers); + scene.assets.slim_left_controller_scene_instance.override_textures(&skin.texture, &camera_buffers); + scene.assets.right_controller_scene_instance.override_textures(&skin.texture, &camera_buffers); + scene.assets.slim_right_controller_scene_instance.override_textures(&skin.texture, &camera_buffers); + } } animator.advance(delta_time, &scene.assets.animated_asset.animations[animator.clip_index]); @@ -333,23 +360,26 @@ pub fn main_loop(env: &mut Env<'_>, ctx: Arc, raw_asset_manager: *mu } } - let payload = renderer::FramePayload { - view_matrices: [ + unsafe { + let mapped_camera_buffer = mapped_camera_buffers[renderer.frame_in_flight]; + (*mapped_camera_buffer).view_matrices = [ renderer::view_transform(views[0]) * world_to_stage, renderer::view_transform(views[1]) * world_to_stage, - ], - projection_matrices: [ + ]; + (*mapped_camera_buffer).projection_matrices = [ renderer::projection_transform(views[0]), renderer::projection_transform(views[1]), - ], + ]; + } + + let payload = renderer::FramePayload { + camera_buffer: &camera_buffers[renderer.frame_in_flight], xr_views: &views, }; let result = renderer.draw(&mut context, active_frame, payload, |graph, draw_payload| { scene.record(graph, draw_payload); - if let Some(ref skin) = *scene.assets.skin.read().unwrap() { - scene.assets.animated_instance.record_with_transform_override_texture(graph, draw_payload, &Mat4::IDENTITY, skin.texture.clone()); - } + scene.assets.animated_instance.record_with_transform(graph, draw_payload, &Mat4::IDENTITY); if let Some(ref last_surface_texture) = last_surface_texture { surface_manager.record_with_transform(graph, last_surface_texture.image.clone(), draw_payload, surface_transform); } diff --git a/app/src/main/rust/src/input.rs b/app/src/main/rust/src/input.rs index 11e1858..551ce1c 100644 --- a/app/src/main/rust/src/input.rs +++ b/app/src/main/rust/src/input.rs @@ -129,7 +129,8 @@ impl InputState { } if let Ok(state) = self.actions.left_thumbstick.state(session, xr::Path::NULL) { - movement[1] = -state.current_state.y; // for some reason down on the thumbstick makes y positive? idk + // my stick drift is actually so bad I can't test with this enabled + // movement[1] = -state.current_state.y; // for some reason down on the thumbstick makes y positive? idk } let mut right_click_state = false; diff --git a/app/src/main/rust/src/render/renderer.rs b/app/src/main/rust/src/render/renderer.rs index 4e26c88..5c925a6 100644 --- a/app/src/main/rust/src/render/renderer.rs +++ b/app/src/main/rust/src/render/renderer.rs @@ -1,4 +1,7 @@ use std::path::Path; +use std::sync::Arc; +use vk_graph::driver::buffer::Buffer; +use vk_graph::node::{AnyBufferNode, AnyImageNode}; use { crate::{ app::XrContext, @@ -16,8 +19,7 @@ use { vk_graph::{ cmd::ClearColorValue, driver::{ - ash::vk::{self, BufferUsageFlags, DeviceSize}, - buffer::BufferInfo, + ash::vk::{self}, device::Device, fence::Fence, image::{ImageInfo, SampleCount}, @@ -38,9 +40,11 @@ pub enum RenderingError { } pub struct Renderer<'a> { - resolution: vk::Extent2D, + pub resolution: vk::Extent2D, - pool: LazyPool, + pub pool: LazyPool, + pub frame_in_flight: usize, + max_frames_in_flight: usize, swapchain_queues: Box<[Option]>, swapchain_rect: xr::Rect2Di, fixture_path: &'a Path, @@ -73,15 +77,15 @@ pub struct ActiveFrame { } pub struct FramePayload<'a> { - pub view_matrices: [Mat4; 2], - pub projection_matrices: [Mat4; 2], + pub camera_buffer: &'a Arc, pub xr_views: &'a [openxr::View], } pub struct DrawPayload<'a> { - pub camera_ubo: &'a vk_graph::node::AnyBufferNode, - pub color_target: &'a vk_graph::node::AnyImageNode, - pub depth_target: &'a vk_graph::node::AnyImageNode, + pub frame_in_flight: usize, + pub camera_ubo: &'a AnyBufferNode, + pub color_target: &'a AnyImageNode, + pub depth_target: &'a AnyImageNode, } pub const VIEW_MASK: u32 = !(!0 << 2); @@ -123,22 +127,13 @@ impl<'a> Renderer<'a> { ).into_builder().sample_count(MSAA_COUNT)).unwrap().with_debug_name("main depth image") ); - let camera_data = XrCameraUBO { - view_matrices: payload.view_matrices, - projection_matrices: payload.projection_matrices, - }; - let mut ubo_buffer = self.pool.resource(BufferInfo::builder() - .host_writable(true) - .size(size_of::() as DeviceSize) - .usage(BufferUsageFlags::UNIFORM_BUFFER) - ).map_err(|_| RenderingError::DriverError)?; - ubo_buffer.copy_from_slice(0, bytemuck::bytes_of(&camera_data)); - let camera_ubo_node = graph.bind_resource(ubo_buffer); + let camera_ubo_node = graph.bind_resource(payload.camera_buffer); graph.clear_color_image(swapchain_image, ClearColorValue::WHITE_ALPHA_ONE); graph.clear_depth_stencil_image(depth_target, 1.0, 0); let draw_payload = DrawPayload { + frame_in_flight: self.frame_in_flight, camera_ubo: &camera_ubo_node.into(), color_target: &swapchain_image.into(), depth_target: &depth_target.into(), @@ -172,6 +167,7 @@ impl<'a> Renderer<'a> { ]) ] ).map_err(|_| FailedToEndStream)?; + self.frame_in_flight = (self.frame_in_flight + 1) % self.max_frames_in_flight; #[cfg(feature = "profiled")] profiling::finish_frame!(); @@ -197,6 +193,8 @@ impl<'a> Renderer<'a> { Renderer { resolution, pool, + frame_in_flight: 0, + max_frames_in_flight: swapchain_image_count, swapchain_queues, swapchain_rect, fixture_path, diff --git a/app/src/main/rust/src/scene/gltf_model.rs b/app/src/main/rust/src/scene/gltf_model.rs index 12e3d6b..672c784 100644 --- a/app/src/main/rust/src/scene/gltf_model.rs +++ b/app/src/main/rust/src/scene/gltf_model.rs @@ -1,3 +1,4 @@ +use vk_graph::driver::descriptor_set::{DescriptorSet, DescriptorSetBinding, DescriptorSetInfo, DescriptorSetUpdateInfo}; use { std::{collections::HashMap, sync::Arc}, bytemuck::{bytes_of, Pod, Zeroable}, @@ -815,13 +816,15 @@ pub struct GltfInstance { pub asset: Arc, pub nodes: Vec, + descriptor_sets: Vec, + instance_data: Vec, instance_buffer: Arc, joint_matrix_buffer: Arc, } impl GltfInstance { - pub fn new(asset: Arc, device: &Device) -> Self { + pub fn new(asset: Arc, device: &Device, camera_buffers: &Vec>) -> Self { let nodes = asset.bind_pose_nodes.clone(); let instance_data = asset.base_instance_data.clone(); @@ -838,14 +841,81 @@ impl GltfInstance { bytemuck::cast_slice(&joint_matrix_seed), ).expect("Failed to create joint matrix buffer")); + let mut descriptor_sets = Vec::new(); + + for camera_buffer in camera_buffers { + let mut descriptors = Vec::new(); + descriptors.push(DescriptorSetUpdateInfo::buffer(0, camera_buffer)); + descriptors.push(DescriptorSetUpdateInfo::buffer(1, &instance_buffer)); + descriptors.push(DescriptorSetUpdateInfo::buffer(2, &joint_matrix_buffer)); + + for (idx, texture) in asset.textures.iter().enumerate() { + descriptors.push(DescriptorSetUpdateInfo::image(DescriptorSetBinding { binding: 3, array_element: idx as u32 }, texture)); + } + + descriptor_sets.push(DescriptorSet::alloc_and_update( + &*asset.culled_pipeline, + DescriptorSetInfo::builder().set(0).build(), + descriptors + ).expect("Failed to allocate and update descriptor set 0")); + } + GltfInstance { asset, nodes, + descriptor_sets, instance_data, instance_buffer, joint_matrix_buffer, } } + + pub fn override_textures(&mut self, texture: &Arc, camera_buffers: &Vec>) { + let mut descriptor_sets = Vec::new(); + + for camera_buffer in camera_buffers { + let mut descriptors = Vec::new(); + descriptors.push(DescriptorSetUpdateInfo::buffer(0, camera_buffer)); + descriptors.push(DescriptorSetUpdateInfo::buffer(1, &self.instance_buffer)); + descriptors.push(DescriptorSetUpdateInfo::buffer(2, &self.joint_matrix_buffer)); + + for (idx, _) in self.asset.textures.iter().enumerate() { + descriptors.push(DescriptorSetUpdateInfo::image(DescriptorSetBinding { binding: 3, array_element: idx as u32 }, texture)); + } + + descriptor_sets.push(DescriptorSet::alloc_and_update( + &*self.asset.culled_pipeline, + DescriptorSetInfo::builder().set(0).build(), + descriptors + ).expect("Failed to allocate and update descriptor set 0")); + } + + self.descriptor_sets = descriptor_sets; + } + + // note: this isn't really normally necessary to use but it's here in case we'd ever want to reset the textures for whatever reason. + pub fn recreate_descriptor_sets(&mut self, camera_buffers: &Vec>) { + let mut descriptor_sets = Vec::new(); + + for camera_buffer in camera_buffers { + let mut descriptors = Vec::new(); + descriptors.push(DescriptorSetUpdateInfo::buffer(0, camera_buffer)); + descriptors.push(DescriptorSetUpdateInfo::buffer(1, &self.instance_buffer)); + descriptors.push(DescriptorSetUpdateInfo::buffer(2, &self.joint_matrix_buffer)); + + for (idx, texture) in self.asset.textures.iter().enumerate() { + descriptors.push(DescriptorSetUpdateInfo::image(DescriptorSetBinding { binding: 3, array_element: idx as u32 }, texture)); + } + + descriptor_sets.push(DescriptorSet::alloc_and_update( + &*self.asset.culled_pipeline, + DescriptorSetInfo::builder().set(0).build(), + descriptors + ).expect("Failed to allocate and update descriptor set 0")); + } + + self.descriptor_sets = descriptor_sets; + } pub fn create_animation_player(&self, clip_name: &str, looping: bool) -> Option { self.asset.find_animation(clip_name).map(|idx| AnimationPlayer::new(idx, looping)) @@ -918,10 +988,11 @@ impl GltfInstance { .begin_cmd() .debug_name(format!("Scene {} (culled)", asset.identifier)) .bind_pipeline(&*asset.culled_pipeline) + .bind_descriptor_set(&self.descriptor_sets[draw_payload.frame_in_flight]) .multiview(crate::render::renderer::VIEW_MASK, 0) - .shader_resource_access(0, *draw_payload.camera_ubo, AccessType::VertexShaderReadUniformBuffer) - .shader_resource_access(1, instance_node, AccessType::VertexShaderReadOther) - .shader_resource_access(2, joint_node, AccessType::VertexShaderReadOther) + .resource_access(*draw_payload.camera_ubo, AccessType::VertexShaderReadUniformBuffer) + .resource_access(instance_node, AccessType::VertexShaderReadOther) + .resource_access(joint_node, AccessType::VertexShaderReadOther) .color_attachment_image(0, *draw_payload.color_target, LoadOp::Load, StoreOp::Store) .depth_stencil(DepthStencilInfo::DEPTH_WRITE_LESS) .depth_stencil_attachment_image(*draw_payload.depth_target, LoadOp::Load, StoreOp::Store) @@ -929,10 +1000,9 @@ impl GltfInstance { .resource_access(v_node, AccessType::VertexBuffer) .resource_access(indirect_node, AccessType::IndirectBuffer); - for (idx, texture) in asset.textures.iter().enumerate() { + for texture in &asset.textures { let image_node = cmd_builder.bind_resource(texture); - cmd_builder.set_shader_resource_access( - (3, [idx as u32]), + cmd_builder.set_resource_access( image_node, AccessType::FragmentShaderReadSampledImageOrUniformTexelBuffer, ); @@ -952,10 +1022,11 @@ impl GltfInstance { .begin_cmd() .debug_name(format!("Scene {} (no-cull)", asset.identifier)) .bind_pipeline(&*asset.no_cull_pipeline) + .bind_descriptor_set(&self.descriptor_sets[draw_payload.frame_in_flight]) .multiview(crate::render::renderer::VIEW_MASK, 0) - .shader_resource_access(0, *draw_payload.camera_ubo, AccessType::VertexShaderReadUniformBuffer) - .shader_resource_access(1, instance_node, AccessType::VertexShaderReadOther) - .shader_resource_access(2, joint_node, AccessType::VertexShaderReadOther) + .resource_access(*draw_payload.camera_ubo, AccessType::VertexShaderReadUniformBuffer) + .resource_access(instance_node, AccessType::VertexShaderReadOther) + .resource_access(joint_node, AccessType::VertexShaderReadOther) .color_attachment_image(0, *draw_payload.color_target, LoadOp::Load, StoreOp::Store) .depth_stencil(DepthStencilInfo::DEPTH_WRITE_LESS) .depth_stencil_attachment_image(*draw_payload.depth_target, LoadOp::Load, StoreOp::Store) @@ -963,94 +1034,9 @@ impl GltfInstance { .resource_access(v_node, AccessType::VertexBuffer) .resource_access(indirect_node, AccessType::IndirectBuffer); - for (idx, texture) in asset.textures.iter().enumerate() { + for texture in &asset.textures { let image_node = cmd_builder.bind_resource(texture); - cmd_builder.set_shader_resource_access( - (3, [idx as u32]), - image_node, - AccessType::FragmentShaderReadSampledImageOrUniformTexelBuffer, - ); - } - - let draw_count = asset.no_cull_draw_count; - cmd_builder.record_cmd(move |cmd| { - cmd.bind_index_buffer(i_node, 0, IndexType::UINT32) - .bind_vertex_buffer(0, v_node, 0) - .push_constants(0, bytes_of(&scene_transform)) - .draw_indexed_indirect(indirect_node, no_cull_offset, draw_count, stride as u32); - }).end_cmd(); - } - } - - pub fn record_with_transform_override_texture(&self, graph: &mut Graph, draw_payload: &DrawPayload, transform: &Mat4, texture: Arc) { - #[cfg(feature = "profiled")] - profiling::function_scope!(); - - let asset = &self.asset; - let v_node = graph.bind_resource(asset.vertex_buffer.clone()); - let i_node = graph.bind_resource(asset.index_buffer.clone()); - let instance_node = graph.bind_resource(self.instance_buffer.clone()); - let indirect_node = graph.bind_resource(asset.indirect_buffer.clone()); - let joint_node = graph.bind_resource(self.joint_matrix_buffer.clone()); - - let scene_transform = *transform; - let stride = size_of::() as vk::DeviceSize; - let no_cull_offset = stride * asset.culled_draw_count as vk::DeviceSize; - - if asset.culled_draw_count > 0 { - let mut cmd_builder = graph - .begin_cmd() - .debug_name(format!("Scene {} (culled)", asset.identifier)) - .bind_pipeline(&*asset.culled_pipeline) - .multiview(crate::render::renderer::VIEW_MASK, 0) - .shader_resource_access(0, *draw_payload.camera_ubo, AccessType::VertexShaderReadUniformBuffer) - .shader_resource_access(1, instance_node, AccessType::VertexShaderReadOther) - .shader_resource_access(2, joint_node, AccessType::VertexShaderReadOther) - .color_attachment_image(0, *draw_payload.color_target, LoadOp::Load, StoreOp::Store) - .depth_stencil(DepthStencilInfo::DEPTH_WRITE_LESS) - .depth_stencil_attachment_image(*draw_payload.depth_target, LoadOp::Load, StoreOp::Store) - .resource_access(i_node, AccessType::IndexBuffer) - .resource_access(v_node, AccessType::VertexBuffer) - .resource_access(indirect_node, AccessType::IndirectBuffer); - - let image_node = cmd_builder.bind_resource(&texture); - for (idx, _) in asset.textures.iter().enumerate() { - cmd_builder.set_shader_resource_access( - (3, [idx as u32]), - image_node, - AccessType::FragmentShaderReadSampledImageOrUniformTexelBuffer, - ); - } - - let draw_count = asset.culled_draw_count; - cmd_builder.record_cmd(move |cmd| { - cmd.bind_index_buffer(i_node, 0, IndexType::UINT32) - .bind_vertex_buffer(0, v_node, 0) - .push_constants(0, bytes_of(&scene_transform)) - .draw_indexed_indirect(indirect_node, 0, draw_count, stride as u32); - }).end_cmd(); - } - - if asset.no_cull_draw_count > 0 { - let mut cmd_builder = graph - .begin_cmd() - .debug_name(format!("Scene {} (no-cull)", asset.identifier)) - .bind_pipeline(&*asset.no_cull_pipeline) - .multiview(crate::render::renderer::VIEW_MASK, 0) - .shader_resource_access(0, *draw_payload.camera_ubo, AccessType::VertexShaderReadUniformBuffer) - .shader_resource_access(1, instance_node, AccessType::VertexShaderReadOther) - .shader_resource_access(2, joint_node, AccessType::VertexShaderReadOther) - .color_attachment_image(0, *draw_payload.color_target, LoadOp::Load, StoreOp::Store) - .depth_stencil(DepthStencilInfo::DEPTH_WRITE_LESS) - .depth_stencil_attachment_image(*draw_payload.depth_target, LoadOp::Load, StoreOp::Store) - .resource_access(i_node, AccessType::IndexBuffer) - .resource_access(v_node, AccessType::VertexBuffer) - .resource_access(indirect_node, AccessType::IndirectBuffer); - - let image_node = cmd_builder.bind_resource(&texture); - for (idx, _) in asset.textures.iter().enumerate() { - cmd_builder.set_shader_resource_access( - (3, [idx as u32]), + cmd_builder.set_resource_access( image_node, AccessType::FragmentShaderReadSampledImageOrUniformTexelBuffer, ); diff --git a/app/src/main/rust/src/scene/scene.rs b/app/src/main/rust/src/scene/scene.rs index 2bf2a66..c632a71 100644 --- a/app/src/main/rust/src/scene/scene.rs +++ b/app/src/main/rust/src/scene/scene.rs @@ -1,3 +1,4 @@ +use vk_graph::driver::buffer::Buffer; use { crate::{ render::renderer::{self, DrawPayload}, @@ -46,13 +47,13 @@ pub struct Assets { // these _asset fields don't really need to be here because GltfInstance holds a reference, but I don't really want to delete them in case we want to add animations to them (which would require an accessible reference to the asset) left_controller_scene_asset: Arc, - left_controller_scene_instance: GltfInstance, + pub left_controller_scene_instance: GltfInstance, right_controller_scene_asset: Arc, - right_controller_scene_instance: GltfInstance, + pub right_controller_scene_instance: GltfInstance, slim_left_controller_scene_asset: Arc, - slim_left_controller_scene_instance: GltfInstance, + pub slim_left_controller_scene_instance: GltfInstance, slim_right_controller_scene_asset: Arc, - slim_right_controller_scene_instance: GltfInstance, + pub slim_right_controller_scene_instance: GltfInstance, ray_scene_asset: Arc, ray_scene_instance: GltfInstance, @@ -68,7 +69,7 @@ pub struct Scene { } impl Scene { - pub fn load(device: &Device, asset_manager: &AssetManager) -> Self { + pub fn load(device: &Device, camera_buffers: &Vec>, asset_manager: &AssetManager) -> Self { let gltf_unlit_shaders = { let mut asset = asset_manager.open(c"shaders/gltf_unlit.spv").expect("Failed to load 'gltf_unlit' shader"); let spv_bytes = asset.buffer().unwrap(); @@ -244,47 +245,47 @@ impl Scene { let asset = asset_manager.open(c"meshes/scene.glb").expect("Failed to load 'scene.glb'"); Arc::new(GltfAsset::new("Test".to_string(), asset, device, gltf_unlit_pipeline.clone(), gltf_unlit_no_cull_pipeline.clone())) }; - let scene_instance = GltfInstance::new(scene_asset.clone(), device); + let scene_instance = GltfInstance::new(scene_asset.clone(), device, camera_buffers); let animated_asset = { let asset = asset_manager.open(c"meshes/animated.glb").expect("Failed to load 'animated.glb'"); Arc::new(GltfAsset::new("Animated".to_string(), asset, device, gltf_unlit_translucent_pipeline.clone(), gltf_unlit_translucent_no_cull_pipeline.clone())) }; - let animated_instance = GltfInstance::new(animated_asset.clone(), device); + let animated_instance = GltfInstance::new(animated_asset.clone(), device, camera_buffers); let left_controller_scene_asset = { let asset = asset_manager.open(c"meshes/left_controller.glb").expect("Failed to load 'left_controller.glb'"); Arc::new(GltfAsset::new("Controller".to_string(), asset, device, gltf_unlit_pipeline.clone(), gltf_unlit_no_cull_pipeline.clone())) }; - let left_controller_scene_instance = GltfInstance::new(left_controller_scene_asset.clone(), device); + let left_controller_scene_instance = GltfInstance::new(left_controller_scene_asset.clone(), device, camera_buffers); let right_controller_scene_asset = { let asset = asset_manager.open(c"meshes/right_controller.glb").expect("Failed to load 'right_controller.glb'"); Arc::new(GltfAsset::new("Controller".to_string(), asset, device, gltf_unlit_pipeline.clone(), gltf_unlit_no_cull_pipeline.clone())) }; - let right_controller_scene_instance = GltfInstance::new(right_controller_scene_asset.clone(), device); + let right_controller_scene_instance = GltfInstance::new(right_controller_scene_asset.clone(), device, camera_buffers); let slim_left_controller_scene_asset = { let asset = asset_manager.open(c"meshes/slim_left_controller.glb").expect("Failed to load 'slim_left_controller.glb'"); Arc::new(GltfAsset::new("Controller".to_string(), asset, device, gltf_unlit_pipeline.clone(), gltf_unlit_no_cull_pipeline.clone())) }; - let slim_left_controller_scene_instance = GltfInstance::new(slim_left_controller_scene_asset.clone(), device); + let slim_left_controller_scene_instance = GltfInstance::new(slim_left_controller_scene_asset.clone(), device, camera_buffers); let slim_right_controller_scene_asset = { let asset = asset_manager.open(c"meshes/slim_right_controller.glb").expect("Failed to load 'slim_right_controller.glb'"); Arc::new(GltfAsset::new("Controller".to_string(), asset, device, gltf_unlit_pipeline.clone(), gltf_unlit_no_cull_pipeline.clone())) }; - let slim_right_controller_scene_instance = GltfInstance::new(slim_right_controller_scene_asset.clone(), device); + let slim_right_controller_scene_instance = GltfInstance::new(slim_right_controller_scene_asset.clone(), device, camera_buffers); let ray_scene_asset = { let asset = asset_manager.open(c"meshes/ray.glb").expect("Failed to load 'ray.glb'"); Arc::new(GltfAsset::new("Ray".to_string(), asset, device, gltf_unlit_translucent_pipeline.clone(), gltf_unlit_translucent_no_cull_pipeline.clone())) }; - let ray_scene_instance = GltfInstance::new(ray_scene_asset.clone(), device); + let ray_scene_instance = GltfInstance::new(ray_scene_asset.clone(), device, camera_buffers); let pointer_scene_asset = { let asset = asset_manager.open(c"meshes/pointer.glb").expect("Failed to load 'pointer.glb'"); Arc::new(GltfAsset::new("Pointer".to_string(), asset, device, gltf_unlit_translucent_pipeline.clone(), gltf_unlit_translucent_no_cull_pipeline.clone())) }; - let pointer_scene_instance = GltfInstance::new(pointer_scene_asset.clone(), device); + let pointer_scene_instance = GltfInstance::new(pointer_scene_asset.clone(), device, camera_buffers); let spawn_matrix = scene_instance.find_spawnpoint_transform(); if let Some(spawn_matrix) = &spawn_matrix { @@ -344,11 +345,8 @@ impl Scene { } }; - if let Some(ref skin) = *skin { - scene.record_with_transform_override_texture(graph, draw_payload, controller_matrix, skin.texture.clone()); - } else { - scene.record_with_transform(graph, draw_payload, controller_matrix); - } + + scene.record_with_transform(graph, draw_payload, controller_matrix); if let Some(ray_transform) = ray_transform { self.assets.ray_scene_instance.record_with_transform(graph, draw_payload, &ray_transform); }