diff options
author | metamuffin <metamuffin@disroot.org> | 2025-01-19 20:36:21 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-01-19 20:36:21 +0100 |
commit | 5ef0fc14d1d12cc5e7cc6a1fb896953d6d668891 (patch) | |
tree | 7a8a3258965b250e7c6bce39cfad3b8c0c452a5e /client/src/scene_prepare.rs | |
parent | 736c0c34b9e727bf4b25e800f748199d13ff561f (diff) | |
download | weareserver-5ef0fc14d1d12cc5e7cc6a1fb896953d6d668891.tar weareserver-5ef0fc14d1d12cc5e7cc6a1fb896953d6d668891.tar.bz2 weareserver-5ef0fc14d1d12cc5e7cc6a1fb896953d6d668891.tar.zst |
client: send material data to shader
Diffstat (limited to 'client/src/scene_prepare.rs')
-rw-r--r-- | client/src/scene_prepare.rs | 71 |
1 files changed, 67 insertions, 4 deletions
diff --git a/client/src/scene_prepare.rs b/client/src/scene_prepare.rs index 97ab166..0e65e72 100644 --- a/client/src/scene_prepare.rs +++ b/client/src/scene_prepare.rs @@ -19,8 +19,9 @@ use crate::{ meshops::{generate_normals, generate_tangents, generate_texcoords}, }; use anyhow::Result; +use bytemuck::{Pod, Zeroable}; use egui::{Grid, Widget}; -use glam::{Vec2, Vec3}; +use glam::{UVec3, UVec4, Vec2, Vec3, Vec3A, uvec3, uvec4}; use humansize::DECIMAL; use image::ImageReader; use log::{debug, trace}; @@ -87,6 +88,7 @@ pub struct ScenePreparer { device: Arc<Device>, queue: Arc<Queue>, texture_bgl: BindGroupLayout, + material_bgl: BindGroupLayout, textures: DemandMap<(Resource<Image<'static>>, bool), (Arc<Texture>, Arc<BindGroup>)>, placeholder_textures: DemandMap<TextureIdentityKind, (Arc<Texture>, Arc<BindGroup>)>, @@ -96,6 +98,7 @@ pub struct ScenePreparer { generated_normal_buffers: DemandMap<NormalBufferSpec, Arc<Buffer>>, generated_texcoord_buffers: DemandMap<TexcoordBufferSpec, Arc<Buffer>>, mesh_parts: DemandMap<Resource<MeshPart>, Arc<RMeshPart>>, + materials: DemandMap<Material, Arc<BindGroup>>, pub prefabs: DemandMap<Resource<Prefab>, Arc<RPrefab>>, } @@ -109,6 +112,7 @@ pub struct RMeshPart { pub va_texcoord: Arc<Buffer>, pub tex_albedo: Arc<BindGroup>, pub tex_normal: Arc<BindGroup>, + pub material: Arc<BindGroup>, pub double_sided: bool, } @@ -136,10 +140,29 @@ enum TextureIdentityKind { Multiply, } +#[derive(Debug, Clone, Copy, Pod, Zeroable, Hash, PartialEq, Eq)] +#[repr(C)] +struct Material { + roughness: u32, + metallic: u32, + _pad1: [u32; 2], + albedo_alpha: UVec4, + emission: UVec3, + _pad2: u32, +} + impl ScenePreparer { - pub fn new(device: Arc<Device>, queue: Arc<Queue>, texture_bgl: BindGroupLayout) -> Self { + pub fn new( + device: Arc<Device>, + queue: Arc<Queue>, + texture_bgl: BindGroupLayout, + material_bgl: BindGroupLayout, + ) -> Self { Self { + device, + queue, texture_bgl, + material_bgl, index_buffers: DemandMap::new(), vertex_buffers: DemandMap::new(), mesh_parts: DemandMap::new(), @@ -149,8 +172,7 @@ impl ScenePreparer { generated_tangent_buffers: DemandMap::new(), generated_normal_buffers: DemandMap::new(), generated_texcoord_buffers: DemandMap::new(), - device, - queue, + materials: DemandMap::new(), } } pub fn update(&self, dls: &Downloader) -> Result<usize> { @@ -312,6 +334,22 @@ impl ScenePreparer { ); } } + for spec in self.materials.needed() { + let buffer = self.device.create_buffer_init(&BufferInitDescriptor { + label: Some("material props"), + usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM, + contents: bytemuck::cast_slice(&[spec]), + }); + let bind_group = self.device.create_bind_group(&BindGroupDescriptor { + label: Some("material"), + layout: &self.material_bgl, + entries: &[BindGroupEntry { + binding: 0, + resource: buffer.as_entire_binding(), + }], + }); + self.materials.insert(spec, Arc::new(bind_group), 0); + } for pres in self.mesh_parts.needed() { let start = Instant::now(); if let Some(part) = dls.try_get(pres.clone())? { @@ -375,6 +413,28 @@ impl ScenePreparer { } } + let material = self.materials.try_get({ + let albedo = part.g_albedo.unwrap_or(Vec3A::ONE); + let emission = part.g_emission.unwrap_or(Vec3A::ONE); + Material { + roughness: part.g_roughness.unwrap_or(1.).to_bits(), + metallic: part.g_metallic.unwrap_or(0.).to_bits(), + _pad1: [0, 0], + albedo_alpha: uvec4( + albedo.x.to_bits(), + albedo.y.to_bits(), + albedo.z.to_bits(), + part.g_alpha.unwrap_or(1.).to_bits(), + ), + emission: uvec3( + emission.x.to_bits(), + emission.y.to_bits(), + emission.z.to_bits(), + ), + _pad2: 0, + } + }); + if let ( Some((index, index_count)), Some(va_normal), @@ -383,8 +443,10 @@ impl ScenePreparer { Some(va_position), Some(tex_normal), Some(tex_albedo), + Some(material), ) = ( index, normal, tangent, texcoord, position, tex_normal, tex_albedo, + material, ) { debug!("part created (took {:?}) {pres}", start.elapsed()); self.mesh_parts.insert( @@ -398,6 +460,7 @@ impl ScenePreparer { va_texcoord, tex_albedo, tex_normal, + material, double_sided: part.g_double_sided.is_some(), }), 0, |