summaryrefslogtreecommitdiff
path: root/client/src/scene_prepare.rs
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-01-19 20:36:21 +0100
committermetamuffin <metamuffin@disroot.org>2025-01-19 20:36:21 +0100
commit5ef0fc14d1d12cc5e7cc6a1fb896953d6d668891 (patch)
tree7a8a3258965b250e7c6bce39cfad3b8c0c452a5e /client/src/scene_prepare.rs
parent736c0c34b9e727bf4b25e800f748199d13ff561f (diff)
downloadweareserver-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.rs71
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,