Compare commits

..

1 Commits

Author SHA1 Message Date
92bd2ea9ad Temporal dithering 2024-11-17 20:09:19 +03:00
4 changed files with 48 additions and 55 deletions

View File

@ -199,7 +199,7 @@ impl<'a> State<'a> {
required_features: wgpu::Features::PUSH_CONSTANTS required_features: wgpu::Features::PUSH_CONSTANTS
| wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES, | wgpu::Features::TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES,
required_limits: wgpu::Limits { required_limits: wgpu::Limits {
max_push_constant_size: 16, max_push_constant_size: 20,
..wgpu::Limits::default() ..wgpu::Limits::default()
}, },
memory_hints: Default::default(), memory_hints: Default::default(),

View File

@ -7,6 +7,7 @@ var<uniform> camera: CameraUniform;
struct MeshUniform { struct MeshUniform {
color: vec4<f32>, color: vec4<f32>,
seed: u32,
} }
var<push_constant> mesh: MeshUniform; var<push_constant> mesh: MeshUniform;
@ -37,7 +38,7 @@ fn vs_main(ver: VertexInput) -> VertexOutput {
var out: VertexOutput; var out: VertexOutput;
var light = dot(ver.normal, normalize(vec3(1., 1., 1.))); var light = dot(ver.normal, normalize(vec3(1., 1., 1.)));
light = .7 + .3 * light; light = .7 + .3 * light;
out.vertex_color = vec4(light * mesh.color.xyz, mesh.color.w); out.vertex_color = light * mesh.color;
out.clip_position = camera.mvp * vec4(ver.position, 1.); out.clip_position = camera.mvp * vec4(ver.position, 1.);
return out; return out;
} }
@ -50,7 +51,7 @@ fn fs_main(in: VertexOutput) -> FragmentOutput {
var y = bitcast<u32>(in.clip_position.y); var y = bitcast<u32>(in.clip_position.y);
var z = bitcast<u32>(in.clip_position.z); var z = bitcast<u32>(in.clip_position.z);
var alpha = in.vertex_color.w; var alpha = in.vertex_color.w;
var seed = hash(hash(hash(x) ^ y) ^ z); var seed = hash(hash(hash(mesh.seed ^ x) ^ y) ^ z);
var mask = 0u; var mask = 0u;
for (var sample = 0u; sample < 8u; sample++) { for (var sample = 0u; sample < 8u; sample++) {
var threshold = f32(hash(seed ^ sample)) / 0x1p32; var threshold = f32(hash(seed ^ sample)) / 0x1p32;

View File

@ -4,8 +4,6 @@ use bytemuck::{bytes_of, cast_slice, Pod, Zeroable};
use glam::{Vec3, Vec4}; use glam::{Vec3, Vec4};
use wgpu::util::DeviceExt as _; use wgpu::util::DeviceExt as _;
use crate::scene::Face;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug, Pod, Zeroable)] #[derive(Copy, Clone, Debug, Pod, Zeroable)]
struct Vertex { struct Vertex {
@ -13,19 +11,11 @@ struct Vertex {
pub normal: [f32; 3], pub normal: [f32; 3],
} }
impl From<crate::scene::Vertex> for Vertex {
fn from(value: crate::scene::Vertex) -> Self {
Vertex {
position: value.position.into(),
normal: value.normal.into(),
}
}
}
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Pod, Zeroable)] #[derive(Copy, Clone, Pod, Zeroable)]
struct PushConsts { struct PushConsts {
pub color: [f32; 4], pub color: [f32; 4],
pub seed: u32,
} }
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
@ -34,29 +24,49 @@ pub struct Attrs {
} }
impl Attrs { impl Attrs {
fn consts(&self) -> PushConsts { fn consts(&self, seed: u32) -> PushConsts {
PushConsts { PushConsts {
color: self.color.to_array(), color: self.color.to_array(),
seed,
} }
} }
} }
pub struct Mesh { pub struct Mesh {
consts: PushConsts, attrs: Attrs,
npoints: u32, npoints: u32,
buf: wgpu::Buffer, buf: wgpu::Buffer,
} }
impl Mesh { impl Mesh {
pub fn new_list(device: &wgpu::Device, attrs: Attrs, tris: Vec<Face>) -> Self { pub fn new_list(device: &wgpu::Device, attrs: Attrs, tris: Vec<(Vec3, Vec3, Vec3)>) -> Self {
let data: Vec<Vertex> = tris.into_iter().flat_map(|face| face.map(Into::into)).collect(); let data: Vec<Vertex> = tris
.into_iter()
.flat_map(|(a, b, c)| {
let n = (b - a).cross(c - a).normalize();
[
Vertex {
position: a.into(),
normal: n.into(),
},
Vertex {
position: b.into(),
normal: n.into(),
},
Vertex {
position: c.into(),
normal: n.into(),
},
]
})
.collect();
let buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { let buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Mesh Vertex Buffer"), label: Some("Mesh Vertex Buffer"),
contents: cast_slice(&data), contents: cast_slice(&data),
usage: wgpu::BufferUsages::VERTEX, usage: wgpu::BufferUsages::VERTEX,
}); });
Mesh { Mesh {
consts: attrs.consts(), attrs,
npoints: data.len() as u32, npoints: data.len() as u32,
buf, buf,
} }
@ -149,10 +159,12 @@ impl Renderer {
cam_bind: &wgpu::BindGroup, cam_bind: &wgpu::BindGroup,
meshes: impl Iterator<Item = &'a Mesh>, meshes: impl Iterator<Item = &'a Mesh>,
) { ) {
let seed = rand::random();
pass.set_pipeline(&self.pipeline); pass.set_pipeline(&self.pipeline);
pass.set_bind_group(0, cam_bind, &[]); pass.set_bind_group(0, cam_bind, &[]);
for mesh in meshes { for mesh in meshes {
pass.set_push_constants(wgpu::ShaderStages::VERTEX, 0, bytes_of(&mesh.consts)); let consts = mesh.attrs.consts(seed);
pass.set_push_constants(wgpu::ShaderStages::VERTEX, 0, bytes_of(&consts));
pass.set_vertex_buffer(0, mesh.buf.slice(..)); pass.set_vertex_buffer(0, mesh.buf.slice(..));
pass.draw(0..mesh.npoints, 0..1); pass.draw(0..mesh.npoints, 0..1);
} }

View File

@ -17,12 +17,7 @@ pub struct FancyLine {
pub pts: Vec<Ray>, pub pts: Vec<Ray>,
} }
pub struct Vertex { pub type Face = (Vec3, Vec3, Vec3);
pub position: Vec3,
pub normal: Vec3,
}
pub type Face = [Vertex; 3];
pub enum Mesh { pub enum Mesh {
List(Vec<Face>), List(Vec<Face>),
@ -165,44 +160,29 @@ impl Renderable for Tube {
let d = Vec2::from_angle(k as f32 * step); let d = Vec2::from_angle(k as f32 * step);
vec3(d.x, 0., d.y) vec3(d.x, 0., d.y)
}; };
let side = vec3(0., self.external_halflength, 0.); let side = vec3(0., self.external_halflength, 0.);
let r1 = self.inner_radius; let r1 = self.inner_radius;
let r2 = self.outer_radius; let r2 = self.outer_radius;
let vertex = |k, r, h| {
let n = dir(k);
Vertex {
position: r * n + h * side,
normal: n,
}
};
let inner = (0..sides).flat_map(|k| { let inner = (0..sides).flat_map(|k| {
[ let a = r1 * dir(k);
[vertex(k, -r1, -1.), vertex(k, -r1, 1.), vertex(k + 1, -r1, -1.)], let b = r1 * dir(k + 1);
[vertex(k + 1, -r1, -1.), vertex(k, -r1, 1.), vertex(k + 1, -r1, 1.)], [(a - side, b - side, a + side), (b - side, b + side, a + side)]
]
}); });
let outer = (0..sides).flat_map(|k| { let outer = (0..sides).flat_map(|k| {
[ let a = r2 * dir(k);
[vertex(k, r2, -1.), vertex(k + 1, r2, -1.), vertex(k, r2, 1.)], let b = r2 * dir(k + 1);
[vertex(k + 1, r2, -1.), vertex(k + 1, r2, 1.), vertex(k, r2, 1.)], [(a - side, b - side, a + side), (b - side, b + side, a + side)]
]
}); });
let vertex = |k, r, h| {
let n = dir(k);
Vertex {
position: r * n + h * side,
normal: h * Vec3::Y,
}
};
let cap = (0..sides).flat_map(|k| { let cap = (0..sides).flat_map(|k| {
let a = r1 * dir(k);
let b = r1 * dir(k + 1);
let c = r2 * dir(k + 1);
let d = r2 * dir(k);
[ [
[vertex(k, r1, -1.), vertex(k + 1, r1, -1.), vertex(k + 1, r2, -1.)], (a - side, b - side, c - side),
[vertex(k, r1, -1.), vertex(k + 1, r2, -1.), vertex(k, r2, -1.)], (a - side, c - side, d - side),
[vertex(k, r1, 1.), vertex(k + 1, r1, 1.), vertex(k + 1, r2, 1.)], (a + side, b + side, c + side),
[vertex(k, r1, 1.), vertex(k + 1, r2, 1.), vertex(k, r2, 1.)], (a + side, c + side, d + side),
] ]
}); });
chain!(inner, outer, cap).collect() chain!(inner, outer, cap).collect()