summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-01-23 21:42:04 +0100
committermetamuffin <metamuffin@disroot.org>2025-01-23 21:42:04 +0100
commitdd40803458695abcd4100fffb874cc25a71ea758 (patch)
tree2ac174eb7d6c6414d32740b7f067b5c821ece176 /client
parent25280332af8dce146295b2dcb48c044c45a92eba (diff)
downloadweareserver-dd40803458695abcd4100fffb874cc25a71ea758.tar
weareserver-dd40803458695abcd4100fffb874cc25a71ea758.tar.bz2
weareserver-dd40803458695abcd4100fffb874cc25a71ea758.tar.zst
anisotropic texture filtering
Diffstat (limited to 'client')
-rw-r--r--client/src/scene_prepare.rs31
-rw-r--r--client/src/shaders/fragment_pbr.wgsl2
-rw-r--r--client/src/shaders/texture_copy.wgsl15
-rw-r--r--client/src/ui.rs14
4 files changed, 46 insertions, 16 deletions
diff --git a/client/src/scene_prepare.rs b/client/src/scene_prepare.rs
index e50dd34..d4535a1 100644
--- a/client/src/scene_prepare.rs
+++ b/client/src/scene_prepare.rs
@@ -49,9 +49,9 @@ use wgpu::{
Operations, PipelineCompilationOptions, PipelineLayoutDescriptor, PolygonMode, PrimitiveState,
PrimitiveTopology, PushConstantRange, Queue, RenderPassColorAttachment, RenderPassDescriptor,
RenderPipeline, RenderPipelineDescriptor, SamplerBindingType, SamplerDescriptor, ShaderStages,
- StencilState, StoreOp, Texture, TextureDescriptor, TextureDimension, TextureFormat,
- TextureSampleType, TextureUsages, TextureViewDescriptor, TextureViewDimension, VertexAttribute,
- VertexBufferLayout, VertexFormat, VertexState, VertexStepMode, include_wgsl,
+ StencilState, StoreOp, Texture, TextureAspect, TextureDescriptor, TextureDimension,
+ TextureFormat, TextureSampleType, TextureUsages, TextureViewDescriptor, TextureViewDimension,
+ VertexAttribute, VertexBufferLayout, VertexFormat, VertexState, VertexStepMode, include_wgsl,
util::{BufferInitDescriptor, DeviceExt},
};
@@ -94,12 +94,18 @@ impl<K: Hash + Eq + Clone, V: Clone> DemandMap<K, V> {
}
}
+struct GraphicsConfig {
+ max_anisotropy: u16,
+ max_mip_count: u32,
+}
+
pub struct ScenePreparer {
device: Arc<Device>,
queue: Arc<Queue>,
layouts: SceneBgLayouts,
shaders: SceneShaders,
render_format: TextureFormat,
+ config: GraphicsConfig,
textures: DemandMap<TextureSpec, (Arc<Texture>, Arc<BindGroup>)>,
placeholder_textures: DemandMap<TextureIdentityKind, (Arc<Texture>, Arc<BindGroup>)>,
@@ -187,6 +193,10 @@ impl ScenePreparer {
Self {
// TODO normal mipmap requires linear texture, also demand map?
render_format,
+ config: GraphicsConfig {
+ max_anisotropy: 16,
+ max_mip_count: 16,
+ },
layouts: SceneBgLayouts::load(&device),
shaders: SceneShaders::load(&device),
device,
@@ -293,8 +303,8 @@ impl ScenePreparer {
dims.0,
dims.1,
format,
- dims.0.ilog2().max(4) - 3,
Some(&mipgen),
+ &self.config,
);
self.textures.insert(spec, tex_bg, image.len());
debug!(
@@ -324,8 +334,8 @@ impl ScenePreparer {
} else {
TextureFormat::Rgba8UnormSrgb
},
- 1,
None,
+ &self.config,
);
self.placeholder_textures.insert(kind, tex_bg, 4);
num_done += 1;
@@ -606,7 +616,7 @@ impl MipGenerationPipeline {
pub fn load(device: &Device, format: TextureFormat) -> Self {
let shader = device.create_shader_module(include_wgsl!("shaders/texture_copy.wgsl"));
let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
- label: Some("map generator"),
+ label: Some("mip generator"),
layout: None,
vertex: wgpu::VertexState {
module: &shader,
@@ -645,9 +655,11 @@ fn create_texture(
width: u32,
height: u32,
format: TextureFormat,
- mip_level_count: u32,
mipgen: Option<&MipGenerationPipeline>,
+ config: &GraphicsConfig,
) -> (Arc<Texture>, Arc<BindGroup>) {
+ let mip_level_count = (width.ilog2().max(4) - 3).min(config.max_mip_count);
+
let extent = Extent3d {
depth_or_array_layers: 1,
width,
@@ -672,6 +684,7 @@ fn create_texture(
mag_filter: FilterMode::Linear,
min_filter: FilterMode::Linear,
mipmap_filter: FilterMode::Linear,
+ anisotropy_clamp: config.max_anisotropy,
..Default::default()
});
let bind_group = device.create_bind_group(&BindGroupDescriptor {
@@ -695,7 +708,7 @@ fn create_texture(
label: Some("mip generation level view"),
format: None,
dimension: None,
- aspect: wgpu::TextureAspect::All,
+ aspect: TextureAspect::All,
base_mip_level: mip,
mip_level_count: Some(1),
base_array_layer: 0,
@@ -848,6 +861,8 @@ impl PipelineSpec {
label: None,
bind_group_layouts: &[&layouts.texture, &layouts.texture, &layouts.material],
push_constant_ranges: &[PushConstantRange {
+ // 4x4 view projections
+ // 3x3(+1 pad) model basis
range: 0..((4 * 4 + 3 * 4) * size_of::<f32>() as u32),
stages: ShaderStages::VERTEX,
}],
diff --git a/client/src/shaders/fragment_pbr.wgsl b/client/src/shaders/fragment_pbr.wgsl
index 2908d6f..f3ed37e 100644
--- a/client/src/shaders/fragment_pbr.wgsl
+++ b/client/src/shaders/fragment_pbr.wgsl
@@ -48,7 +48,7 @@ fn main(vo: VertexOut) -> @location(0) vec4<f32> {
let color = t_albedo.rgb * lighting;
- // TODO better (and faster?) randomneess for alpha dither
+ // TODO better (and faster?) randomness for alpha dither
if fract(dot(sin(vo.clip * 123.) * 1213., vec4(3., 2., 1., 4.))) > alpha {
discard;
}
diff --git a/client/src/shaders/texture_copy.wgsl b/client/src/shaders/texture_copy.wgsl
index ff58f87..be38a76 100644
--- a/client/src/shaders/texture_copy.wgsl
+++ b/client/src/shaders/texture_copy.wgsl
@@ -1,3 +1,18 @@
+// wearechat - generic multiplayer game with voip
+// Copyright (C) 2025 metamuffin
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, version 3 of the License only.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
struct VertexOut {
@builtin(position) clip: vec4<f32>,
@location(0) texcoord: vec2<f32>,
diff --git a/client/src/ui.rs b/client/src/ui.rs
index 78ca29d..fd94dfb 100644
--- a/client/src/ui.rs
+++ b/client/src/ui.rs
@@ -20,7 +20,7 @@ use egui::{
epaint::{ImageDelta, Primitive, Vertex},
};
use glam::{Affine3A, Mat2, Mat3, Mat4, Vec2, Vec3, Vec3Swizzles, Vec4Swizzles, vec2, vec4};
-use log::{info, warn};
+use log::{debug, warn};
use rand::random;
use std::{
collections::HashMap,
@@ -180,7 +180,7 @@ impl UiRenderer {
mapped_at_creation: false,
});
let id = ViewportId::from_hash_of(random::<u128>());
- info!("ui surface added: {id:?}");
+ debug!("ui surface added: {id:?}");
self.surfaces.write().unwrap().insert(id, UiSurface {
transform,
content: Arc::new(content),
@@ -206,7 +206,7 @@ impl UiRenderer {
if let Some((_texbg, tex, texsize)) = textures.get_mut(&texid) {
let pos = delta.pos.unwrap_or([0, 0]);
- info!("updating UI texture at {pos:?}");
+ debug!("updating UI texture at {pos:?}");
self.queue.write_texture(
ImageCopyTexture {
texture: &tex,
@@ -231,7 +231,7 @@ impl UiRenderer {
delta.pos, None,
"partial update impossible; texture does not yet exist"
);
- info!(
+ debug!(
"uploading new UI texture: width={}, height={}",
delta.image.width(),
delta.image.height()
@@ -432,7 +432,7 @@ impl UiRenderer {
}
while index_count > surf.index_capacity {
- info!(
+ debug!(
"index buffer overflow ({index_count}). expanding {} -> {}",
surf.index_capacity,
surf.index_capacity * 2
@@ -446,7 +446,7 @@ impl UiRenderer {
});
}
while vertex_count > surf.vertex_capacity {
- info!(
+ debug!(
"vertex buffer overflow ({vertex_count}). expanding {} -> {}",
surf.vertex_capacity,
surf.vertex_capacity * 2
@@ -514,7 +514,7 @@ impl UiRenderer {
}
}
for s in surfaces_closed {
- info!("ui surface closed: {s:?}");
+ debug!("ui surface closed: {s:?}");
surfaces.remove(&s);
}