mirror of
https://github.com/maplibre/maplibre-rs.git
synced 2025-12-08 19:05:57 +00:00
Encode mask directly in shader
This commit is contained in:
parent
45fa50962e
commit
a5fc17a2e6
@ -112,64 +112,38 @@ pub mod tile_mask {
|
|||||||
|
|
||||||
pub const VERTEX: VertexShaderState = VertexShaderState::new(
|
pub const VERTEX: VertexShaderState = VertexShaderState::new(
|
||||||
include_str!("tile_mask.vertex.wgsl"),
|
include_str!("tile_mask.vertex.wgsl"),
|
||||||
&[
|
&[wgpu::VertexBufferLayout {
|
||||||
wgpu::VertexBufferLayout {
|
array_stride: std::mem::size_of::<MaskInstanceUniform>() as u64,
|
||||||
array_stride: std::mem::size_of::<GpuVertexUniform>() as u64,
|
step_mode: wgpu::VertexStepMode::Instance,
|
||||||
step_mode: wgpu::VertexStepMode::Vertex,
|
attributes: &[
|
||||||
attributes: &[
|
// offset position
|
||||||
// position
|
wgpu::VertexAttribute {
|
||||||
wgpu::VertexAttribute {
|
offset: 0,
|
||||||
offset: 0,
|
format: wgpu::VertexFormat::Float32x2,
|
||||||
format: wgpu::VertexFormat::Float32x2,
|
shader_location: 4,
|
||||||
shader_location: 0,
|
},
|
||||||
},
|
// target_width
|
||||||
// normal
|
wgpu::VertexAttribute {
|
||||||
wgpu::VertexAttribute {
|
offset: 1 * wgpu::VertexFormat::Float32x2.size(),
|
||||||
offset: wgpu::VertexFormat::Float32x2.size(),
|
format: wgpu::VertexFormat::Float32,
|
||||||
format: wgpu::VertexFormat::Float32x2,
|
shader_location: 5,
|
||||||
shader_location: 1,
|
},
|
||||||
},
|
// target_height
|
||||||
// ?
|
wgpu::VertexAttribute {
|
||||||
wgpu::VertexAttribute {
|
offset: 1 * wgpu::VertexFormat::Float32x2.size()
|
||||||
offset: 2 * wgpu::VertexFormat::Float32x2.size(),
|
+ wgpu::VertexFormat::Float32.size(),
|
||||||
format: wgpu::VertexFormat::Uint32,
|
format: wgpu::VertexFormat::Float32,
|
||||||
shader_location: 2,
|
shader_location: 6,
|
||||||
},
|
},
|
||||||
],
|
// debug_color
|
||||||
},
|
wgpu::VertexAttribute {
|
||||||
wgpu::VertexBufferLayout {
|
offset: 1 * wgpu::VertexFormat::Float32x2.size()
|
||||||
array_stride: std::mem::size_of::<MaskInstanceUniform>() as u64,
|
+ 2 * wgpu::VertexFormat::Float32.size(),
|
||||||
step_mode: wgpu::VertexStepMode::Instance,
|
format: wgpu::VertexFormat::Float32x4,
|
||||||
attributes: &[
|
shader_location: 7,
|
||||||
// offset position
|
},
|
||||||
wgpu::VertexAttribute {
|
],
|
||||||
offset: 0,
|
}],
|
||||||
format: wgpu::VertexFormat::Float32x2,
|
|
||||||
shader_location: 4,
|
|
||||||
},
|
|
||||||
// target_width
|
|
||||||
wgpu::VertexAttribute {
|
|
||||||
offset: 1 * wgpu::VertexFormat::Float32x2.size(),
|
|
||||||
format: wgpu::VertexFormat::Float32,
|
|
||||||
shader_location: 5,
|
|
||||||
},
|
|
||||||
// target_height
|
|
||||||
wgpu::VertexAttribute {
|
|
||||||
offset: 1 * wgpu::VertexFormat::Float32x2.size()
|
|
||||||
+ wgpu::VertexFormat::Float32.size(),
|
|
||||||
format: wgpu::VertexFormat::Float32,
|
|
||||||
shader_location: 6,
|
|
||||||
},
|
|
||||||
// debug_color
|
|
||||||
wgpu::VertexAttribute {
|
|
||||||
offset: 1 * wgpu::VertexFormat::Float32x2.size()
|
|
||||||
+ 2 * wgpu::VertexFormat::Float32.size(),
|
|
||||||
format: wgpu::VertexFormat::Float32x4,
|
|
||||||
shader_location: 7,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
|
|
||||||
pub const FRAGMENT: FragmentShaderState = FragmentShaderState::new(
|
pub const FRAGMENT: FragmentShaderState = FragmentShaderState::new(
|
||||||
|
|||||||
@ -38,12 +38,12 @@ fn main(
|
|||||||
[[location(2)]] a_prim_id: u32,
|
[[location(2)]] a_prim_id: u32,
|
||||||
[[builtin(instance_index)]] instance_idx: u32 // instance_index is used when we have multiple instances of the same "object"
|
[[builtin(instance_index)]] instance_idx: u32 // instance_index is used when we have multiple instances of the same "object"
|
||||||
) -> VertexOutput {
|
) -> VertexOutput {
|
||||||
var prim: PrimitiveUniform = u_primitives.primitives[a_prim_id];
|
let prim: PrimitiveUniform = u_primitives.primitives[a_prim_id];
|
||||||
var z = 0.0;
|
let z = 0.0;
|
||||||
|
|
||||||
var world_pos = a_position + prim.translate + a_normal * prim.width;
|
let world_pos = a_position + prim.translate + a_normal * prim.width;
|
||||||
|
|
||||||
var position = globals.camera.view_proj * vec4<f32>(world_pos, z, 1.0);
|
let position = globals.camera.view_proj * vec4<f32>(world_pos, z, 1.0);
|
||||||
|
|
||||||
return VertexOutput(prim.color, position);
|
return VertexOutput(prim.color, position);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -15,27 +15,54 @@ struct VertexOutput {
|
|||||||
[[builtin(position)]] position: vec4<f32>;
|
[[builtin(position)]] position: vec4<f32>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let EXTENT = 4096.0;
|
||||||
|
|
||||||
[[stage(vertex)]]
|
[[stage(vertex)]]
|
||||||
fn main(
|
fn main(
|
||||||
[[location(0)]] a_position: vec2<f32>,
|
|
||||||
[[location(4)]] mask_offset: vec2<f32>,
|
[[location(4)]] mask_offset: vec2<f32>,
|
||||||
[[location(5)]] target_width: f32,
|
[[location(5)]] target_width: f32,
|
||||||
[[location(6)]] target_height: f32,
|
[[location(6)]] target_height: f32,
|
||||||
[[location(7)]] debug_color: vec4<f32>,
|
[[location(7)]] debug_color: vec4<f32>,
|
||||||
|
[[builtin(vertex_index)]] vertex_idx: u32,
|
||||||
[[builtin(instance_index)]] instance_idx: u32 // instance_index is used when we have multiple instances of the same "object"
|
[[builtin(instance_index)]] instance_idx: u32 // instance_index is used when we have multiple instances of the same "object"
|
||||||
) -> VertexOutput {
|
) -> VertexOutput {
|
||||||
let z = 0.0;
|
var a_position: vec2<f32>;
|
||||||
|
|
||||||
var m: mat3x3<f32> = mat3x3<f32>(
|
// Encode a square within the shader
|
||||||
|
switch (vertex_idx) {
|
||||||
|
case 0: {
|
||||||
|
a_position = vec2<f32>(0.0, 0.0);
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
a_position = vec2<f32>(0.0, EXTENT);
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
a_position = vec2<f32>(EXTENT, 0.0);
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
a_position = vec2<f32>(EXTENT, 0.0);
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
a_position = vec2<f32>(0.0, EXTENT);
|
||||||
|
}
|
||||||
|
case 5: {
|
||||||
|
a_position = vec2<f32>(EXTENT, EXTENT);
|
||||||
|
}
|
||||||
|
default: { }
|
||||||
|
}
|
||||||
|
|
||||||
|
let scaling: mat3x3<f32> = mat3x3<f32>(
|
||||||
vec3<f32>(target_width, 0.0, 0.0),
|
vec3<f32>(target_width, 0.0, 0.0),
|
||||||
vec3<f32>(0.0, target_height, 0.0),
|
vec3<f32>(0.0, target_height, 0.0),
|
||||||
vec3<f32>(0.0, 0.0, 1.0)
|
vec3<f32>(0.0, 0.0, 1.0)
|
||||||
);
|
);
|
||||||
|
|
||||||
var world_pos_3d = vec3<f32>(a_position + mask_offset, z);
|
let z = 0.0;
|
||||||
var world_pos = m * world_pos_3d;
|
|
||||||
|
|
||||||
var position = globals.camera.view_proj * vec4<f32>(world_pos, 1.0);
|
let world_pos_3d = vec3<f32>(a_position + mask_offset, z);
|
||||||
|
let world_pos = scaling * world_pos_3d;
|
||||||
|
|
||||||
|
let position = globals.camera.view_proj * vec4<f32>(world_pos, 1.0);
|
||||||
|
|
||||||
return VertexOutput(debug_color, position);
|
return VertexOutput(debug_color, position);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -42,13 +42,10 @@ impl Default for SceneParams {
|
|||||||
|
|
||||||
const INDEX_FORMAT: wgpu::IndexFormat = wgpu::IndexFormat::Uint32;
|
const INDEX_FORMAT: wgpu::IndexFormat = wgpu::IndexFormat::Uint32;
|
||||||
|
|
||||||
type IndexDataType = u32; // Must match INDEX_FORMAT
|
|
||||||
|
|
||||||
const PRIM_BUFFER_LEN: usize = 256;
|
const PRIM_BUFFER_LEN: usize = 256;
|
||||||
const STROKE_PRIM_ID: u32 = 0;
|
const STROKE_PRIM_ID: u32 = 0;
|
||||||
const FILL_PRIM_ID: u32 = 1;
|
const FILL_PRIM_ID: u32 = 1;
|
||||||
const SECOND_TILE_FILL_PRIM_ID: u32 = 2;
|
const SECOND_TILE_FILL_PRIM_ID: u32 = 2;
|
||||||
const MASK_FILL_PRIM_ID: u32 = 3;
|
|
||||||
const SECOND_TILE_STROKE_PRIM_ID: u32 = 5;
|
const SECOND_TILE_STROKE_PRIM_ID: u32 = 5;
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
@ -84,9 +81,6 @@ pub struct State {
|
|||||||
tile2_fill_range: Range<u32>,
|
tile2_fill_range: Range<u32>,
|
||||||
tile2_stroke_range: Range<u32>,
|
tile2_stroke_range: Range<u32>,
|
||||||
|
|
||||||
tile_mask_vertex_uniform_buffer: wgpu::Buffer,
|
|
||||||
tile_mask_indices_uniform_buffer: wgpu::Buffer,
|
|
||||||
tile_mask_range: Range<u32>,
|
|
||||||
tile_mask_instances: wgpu::Buffer,
|
tile_mask_instances: wgpu::Buffer,
|
||||||
|
|
||||||
pub camera: camera::Camera,
|
pub camera: camera::Camera,
|
||||||
@ -120,9 +114,6 @@ impl SceneParams {
|
|||||||
cpu_primitives[SECOND_TILE_FILL_PRIM_ID as usize] =
|
cpu_primitives[SECOND_TILE_FILL_PRIM_ID as usize] =
|
||||||
PrimitiveUniform::new([0.0, 1.0, 1.0, 1.0], [4096.0, 0.0], 0, 1.0, 0.0, 1.0);
|
PrimitiveUniform::new([0.0, 1.0, 1.0, 1.0], [4096.0, 0.0], 0, 1.0, 0.0, 1.0);
|
||||||
|
|
||||||
cpu_primitives[MASK_FILL_PRIM_ID as usize] =
|
|
||||||
PrimitiveUniform::new([0.0, 0.0, 1.0, 1.0], [0.0, 0.0], 0, 1.0, 0.0, 1.0);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
cpu_primitives,
|
cpu_primitives,
|
||||||
..SceneParams::default()
|
..SceneParams::default()
|
||||||
@ -243,24 +234,6 @@ impl State {
|
|||||||
usage: wgpu::BufferUsages::INDEX,
|
usage: wgpu::BufferUsages::INDEX,
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut tile_mask_geometry: VertexBuffers<GpuVertexUniform, IndexDataType> =
|
|
||||||
VertexBuffers::new();
|
|
||||||
let tile_mask = TileMask();
|
|
||||||
let tile_mask_range = tile_mask.tesselate_fill(&mut tile_mask_geometry, MASK_FILL_PRIM_ID);
|
|
||||||
let tile_mask_vertex_uniform_buffer =
|
|
||||||
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
|
||||||
label: None,
|
|
||||||
contents: bytemuck::cast_slice(&tile_mask_geometry.vertices),
|
|
||||||
usage: wgpu::BufferUsages::VERTEX,
|
|
||||||
});
|
|
||||||
|
|
||||||
let tile_mask_indices_uniform_buffer =
|
|
||||||
device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
|
||||||
label: None,
|
|
||||||
contents: bytemuck::cast_slice(&tile_mask_geometry.indices),
|
|
||||||
usage: wgpu::BufferUsages::INDEX,
|
|
||||||
});
|
|
||||||
|
|
||||||
let instances = [
|
let instances = [
|
||||||
// Step 1
|
// Step 1
|
||||||
MaskInstanceUniform::new([0.0, 0.0], 4.0, 4.0, [1.0, 0.0, 0.0, 1.0]), // horizontal
|
MaskInstanceUniform::new([0.0, 0.0], 4.0, 4.0, [1.0, 0.0, 0.0, 1.0]), // horizontal
|
||||||
@ -439,12 +412,9 @@ impl State {
|
|||||||
globals_uniform_buffer,
|
globals_uniform_buffer,
|
||||||
prims_uniform_buffer,
|
prims_uniform_buffer,
|
||||||
indices_uniform_buffer,
|
indices_uniform_buffer,
|
||||||
tile_mask_vertex_uniform_buffer,
|
|
||||||
fps_meter: FPSMeter::new(),
|
fps_meter: FPSMeter::new(),
|
||||||
tile_stroke_range,
|
tile_stroke_range,
|
||||||
tile2_fill_range,
|
tile2_fill_range,
|
||||||
tile_mask_indices_uniform_buffer,
|
|
||||||
tile_mask_range,
|
|
||||||
tile_mask_instances,
|
tile_mask_instances,
|
||||||
camera,
|
camera,
|
||||||
projection,
|
projection,
|
||||||
@ -567,15 +537,11 @@ impl State {
|
|||||||
pass.set_bind_group(0, &self.bind_group, &[]);
|
pass.set_bind_group(0, &self.bind_group, &[]);
|
||||||
|
|
||||||
{
|
{
|
||||||
// Draw Mask
|
// Draw masks
|
||||||
pass.set_pipeline(&self.mask_pipeline);
|
pass.set_pipeline(&self.mask_pipeline);
|
||||||
pass.set_index_buffer(
|
pass.set_vertex_buffer(0, self.tile_mask_instances.slice(..));
|
||||||
self.tile_mask_indices_uniform_buffer.slice(..),
|
// Draw 11 squares each out of 6 vertices
|
||||||
INDEX_FORMAT,
|
pass.draw(0..6, 0..11);
|
||||||
);
|
|
||||||
pass.set_vertex_buffer(0, self.tile_mask_vertex_uniform_buffer.slice(..));
|
|
||||||
pass.set_vertex_buffer(1, self.tile_mask_instances.slice(..));
|
|
||||||
pass.draw_indexed(self.tile_mask_range.clone(), 0, 0..11);
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
pass.set_pipeline(&self.render_pipeline);
|
pass.set_pipeline(&self.render_pipeline);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user