From 5cd40afa568e36b6f79d8c6ec8e52b998d4d5dd3 Mon Sep 17 00:00:00 2001 From: Quaternions Date: Sat, 30 Sep 2023 13:00:01 -0700 Subject: [PATCH] create ModelGraphicsInstance and include inverse transpose matrix for normals --- src/load_roblox.rs | 2 +- src/main.rs | 40 +++++++++++++++++++++++++--------------- src/model.rs | 11 ++++++++--- src/shader.wgsl | 7 ++++--- 4 files changed, 38 insertions(+), 22 deletions(-) diff --git a/src/load_roblox.rs b/src/load_roblox.rs index 7ade02f9..fdde353c 100644 --- a/src/load_roblox.rs +++ b/src/load_roblox.rs @@ -249,7 +249,7 @@ pub fn generate_indexed_models_roblox(dom:rbx_dom_weak::WeakDom) -> Result<(Inde } }; indexed_models[model_id].instances.push(ModelInstance { - model_transform, + transform:model_transform, color:glam::vec4(color3.r as f32/255f32, color3.g as f32/255f32, color3.b as f32/255f32, 1.0-*transparency), }); } diff --git a/src/main.rs b/src/main.rs index acec91e7..ffee7353 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use std::{borrow::Cow, time::Instant}; use wgpu::{util::DeviceExt, AstcBlock, AstcChannel}; -use model::{Vertex,ModelInstance}; +use model::{Vertex,ModelInstance,ModelGraphicsInstance}; use body::{InputInstruction, PhysicsInstruction}; use instruction::{TimedInstruction, InstructionConsumer}; @@ -18,7 +18,7 @@ struct Entity { } struct ModelGraphics { - instances: Vec, + instances: Vec, vertex_buf: wgpu::Buffer, entities: Vec, bind_group: wgpu::BindGroup, @@ -87,7 +87,7 @@ impl GraphicsData { for model in &indexed_models.models{ //make aabb and run vertices to get realistic bounds for model_instance in &model.instances{ - self.physics.models.push(body::ModelPhysics::from_model(&model,model_instance.model_transform)); + self.physics.models.push(body::ModelPhysics::from_model(&model,model_instance.transform)); } } println!("Physics Objects: {}",self.physics.models.len()); @@ -155,6 +155,14 @@ impl GraphicsData { //the models received here are supposed to be tightly packed, i.e. no code needs to check if two models are using the same groups. let mut unique_texture_models=Vec::with_capacity(indexed_models.models.len()); for mut model in indexed_models.models.drain(..){ + //convert ModelInstance into ModelGraphicsInstance + let instances:Vec=model.instances.iter().map(|instance|{ + ModelGraphicsInstance{ + transform: glam::Mat4::from(instance.transform), + normal_transform: glam::Mat4::from(instance.transform.inverse()).transpose(), + color: instance.color, + } + }).collect(); //check each group, if it's using a new texture then make a new clone of the model let id=unique_texture_models.len(); let mut unique_textures=Vec::new(); @@ -174,7 +182,7 @@ impl GraphicsData { unique_vertices:model.unique_vertices.clone(), texture:group.texture, groups:Vec::new(), - instances:model.instances.clone(), + instances:instances.clone(), }); texture_index }; @@ -297,14 +305,16 @@ impl GraphicsData { } } -const MODEL_BUFFER_SIZE:usize=4*4 + 4;//let size=std::mem::size_of::(); +const MODEL_BUFFER_SIZE:usize=4*4 + 4*4 + 4;//let size=std::mem::size_of::(); const MODEL_BUFFER_SIZE_BYTES:usize=MODEL_BUFFER_SIZE*4; -fn get_instances_buffer_data(instances:&[ModelInstance]) -> Vec { +fn get_instances_buffer_data(instances:&[ModelGraphicsInstance]) -> Vec { let mut raw = Vec::with_capacity(MODEL_BUFFER_SIZE*instances.len()); for (i,mi) in instances.iter().enumerate(){ let mut v = raw.split_off(MODEL_BUFFER_SIZE*i); - //model_transform - raw.extend_from_slice(&AsRef::<[f32; 4*4]>::as_ref(&glam::Mat4::from(mi.model_transform))[..]); + //model transform + raw.extend_from_slice(&AsRef::<[f32; 4*4]>::as_ref(&mi.transform)[..]); + //normal transform + raw.extend_from_slice(&AsRef::<[f32; 4*4]>::as_ref(&mi.normal_transform)[..]); //color raw.extend_from_slice(AsRef::<[f32; 4]>::as_ref(&mi.color)); raw.append(&mut v); @@ -350,34 +360,34 @@ impl framework::Example for GraphicsData { indexed_models.push(primitives::the_unit_cube_lol()); println!("models.len = {:?}", indexed_models.len()); indexed_models[0].instances.push(ModelInstance{ - model_transform:glam::Affine3A::from_translation(glam::vec3(10.,0.,-10.)), + transform:glam::Affine3A::from_translation(glam::vec3(10.,0.,-10.)), color:glam::Vec4::ONE, }); //quad monkeys indexed_models[1].instances.push(ModelInstance{ - model_transform:glam::Affine3A::from_translation(glam::vec3(10.,5.,10.)), + transform:glam::Affine3A::from_translation(glam::vec3(10.,5.,10.)), color:glam::Vec4::ONE, }); indexed_models[1].instances.push(ModelInstance{ - model_transform:glam::Affine3A::from_translation(glam::vec3(20.,5.,10.)), + transform:glam::Affine3A::from_translation(glam::vec3(20.,5.,10.)), color:glam::vec4(1.0,0.0,0.0,1.0), }); indexed_models[1].instances.push(ModelInstance{ - model_transform:glam::Affine3A::from_translation(glam::vec3(10.,5.,20.)), + transform:glam::Affine3A::from_translation(glam::vec3(10.,5.,20.)), color:glam::vec4(0.0,1.0,0.0,1.0), }); indexed_models[1].instances.push(ModelInstance{ - model_transform:glam::Affine3A::from_translation(glam::vec3(20.,5.,20.)), + transform:glam::Affine3A::from_translation(glam::vec3(20.,5.,20.)), color:glam::vec4(0.0,0.0,1.0,1.0), }); //teapot indexed_models[2].instances.push(ModelInstance{ - model_transform:glam::Affine3A::from_translation(glam::vec3(-10.,5.,10.)), + transform:glam::Affine3A::from_translation(glam::vec3(-10.,5.,10.)), color:glam::Vec4::ONE, }); //ground indexed_models[3].instances.push(ModelInstance{ - model_transform:glam::Affine3A::from_translation(glam::vec3(0.,0.,0.))*glam::Affine3A::from_scale(glam::vec3(160.0, 1.0, 160.0)), + transform:glam::Affine3A::from_translation(glam::vec3(0.,0.,0.))*glam::Affine3A::from_scale(glam::vec3(160.0, 1.0, 160.0)), color:glam::Vec4::ONE, }); diff --git a/src/model.rs b/src/model.rs index 2123e61f..79bd70e4 100644 --- a/src/model.rs +++ b/src/model.rs @@ -41,17 +41,22 @@ pub struct IndexedModelSingleTexture{ pub unique_vertices:Vec, pub texture:Option,//RenderPattern? material/texture/shader/flat color pub groups: Vec, - pub instances:Vec, + pub instances:Vec, } pub struct ModelSingleTexture{ - pub instances: Vec, + pub instances: Vec, pub vertices: Vec, pub entities: Vec>, pub texture: Option, } #[derive(Clone)] +pub struct ModelGraphicsInstance{ + pub transform:glam::Mat4, + pub normal_transform:glam::Mat4, + pub color:glam::Vec4, +} pub struct ModelInstance{ - pub model_transform:glam::Affine3A, + pub transform:glam::Affine3A, pub color:glam::Vec4, } pub struct IndexedModelInstances{ diff --git a/src/shader.wgsl b/src/shader.wgsl index 9de865ca..5e2a7e10 100644 --- a/src/shader.wgsl +++ b/src/shader.wgsl @@ -42,7 +42,8 @@ fn vs_sky(@builtin(vertex_index) vertex_index: u32) -> SkyOutput { } struct ModelInstance{ - model_transform:mat4x4, + transform:mat4x4, + normal_transform:mat4x4, color:vec4, } //my fancy idea is to create a megatexture for each model that includes all the textures each intance will need @@ -75,9 +76,9 @@ fn vs_entity_texture( @location(2) normal: vec3, @location(3) color: vec4, ) -> EntityOutputTexture { - var position: vec4 = model_instances[instance].model_transform * vec4(pos, 1.0); + var position: vec4 = model_instances[instance].transform * vec4(pos, 1.0); var result: EntityOutputTexture; - result.normal = (model_instances[instance].model_transform * vec4(normal, 0.0)).xyz; + result.normal = (model_instances[instance].normal_transform * vec4(normal, 1.0)).xyz; result.texture = texture; result.color = color; result.model_color = model_instances[instance].color;