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(
|
||||
include_str!("tile_mask.vertex.wgsl"),
|
||||
&[
|
||||
wgpu::VertexBufferLayout {
|
||||
array_stride: std::mem::size_of::<GpuVertexUniform>() as u64,
|
||||
step_mode: wgpu::VertexStepMode::Vertex,
|
||||
attributes: &[
|
||||
// position
|
||||
wgpu::VertexAttribute {
|
||||
offset: 0,
|
||||
format: wgpu::VertexFormat::Float32x2,
|
||||
shader_location: 0,
|
||||
},
|
||||
// normal
|
||||
wgpu::VertexAttribute {
|
||||
offset: wgpu::VertexFormat::Float32x2.size(),
|
||||
format: wgpu::VertexFormat::Float32x2,
|
||||
shader_location: 1,
|
||||
},
|
||||
// ?
|
||||
wgpu::VertexAttribute {
|
||||
offset: 2 * wgpu::VertexFormat::Float32x2.size(),
|
||||
format: wgpu::VertexFormat::Uint32,
|
||||
shader_location: 2,
|
||||
},
|
||||
],
|
||||
},
|
||||
wgpu::VertexBufferLayout {
|
||||
array_stride: std::mem::size_of::<MaskInstanceUniform>() as u64,
|
||||
step_mode: wgpu::VertexStepMode::Instance,
|
||||
attributes: &[
|
||||
// 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,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
&[wgpu::VertexBufferLayout {
|
||||
array_stride: std::mem::size_of::<MaskInstanceUniform>() as u64,
|
||||
step_mode: wgpu::VertexStepMode::Instance,
|
||||
attributes: &[
|
||||
// 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(
|
||||
|
||||
@ -38,12 +38,12 @@ fn main(
|
||||
[[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"
|
||||
) -> VertexOutput {
|
||||
var prim: PrimitiveUniform = u_primitives.primitives[a_prim_id];
|
||||
var z = 0.0;
|
||||
let prim: PrimitiveUniform = u_primitives.primitives[a_prim_id];
|
||||
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);
|
||||
}
|
||||
|
||||
@ -15,27 +15,54 @@ struct VertexOutput {
|
||||
[[builtin(position)]] position: vec4<f32>;
|
||||
};
|
||||
|
||||
let EXTENT = 4096.0;
|
||||
|
||||
[[stage(vertex)]]
|
||||
fn main(
|
||||
[[location(0)]] a_position: vec2<f32>,
|
||||
[[location(4)]] mask_offset: vec2<f32>,
|
||||
[[location(5)]] target_width: f32,
|
||||
[[location(6)]] target_height: 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"
|
||||
) -> 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>(0.0, target_height, 0.0),
|
||||
vec3<f32>(0.0, 0.0, 1.0)
|
||||
);
|
||||
|
||||
var world_pos_3d = vec3<f32>(a_position + mask_offset, z);
|
||||
var world_pos = m * world_pos_3d;
|
||||
let z = 0.0;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -42,13 +42,10 @@ impl Default for SceneParams {
|
||||
|
||||
const INDEX_FORMAT: wgpu::IndexFormat = wgpu::IndexFormat::Uint32;
|
||||
|
||||
type IndexDataType = u32; // Must match INDEX_FORMAT
|
||||
|
||||
const PRIM_BUFFER_LEN: usize = 256;
|
||||
const STROKE_PRIM_ID: u32 = 0;
|
||||
const FILL_PRIM_ID: u32 = 1;
|
||||
const SECOND_TILE_FILL_PRIM_ID: u32 = 2;
|
||||
const MASK_FILL_PRIM_ID: u32 = 3;
|
||||
const SECOND_TILE_STROKE_PRIM_ID: u32 = 5;
|
||||
|
||||
pub struct State {
|
||||
@ -84,9 +81,6 @@ pub struct State {
|
||||
tile2_fill_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,
|
||||
|
||||
pub camera: camera::Camera,
|
||||
@ -120,9 +114,6 @@ impl SceneParams {
|
||||
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);
|
||||
|
||||
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 {
|
||||
cpu_primitives,
|
||||
..SceneParams::default()
|
||||
@ -243,24 +234,6 @@ impl State {
|
||||
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 = [
|
||||
// Step 1
|
||||
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,
|
||||
prims_uniform_buffer,
|
||||
indices_uniform_buffer,
|
||||
tile_mask_vertex_uniform_buffer,
|
||||
fps_meter: FPSMeter::new(),
|
||||
tile_stroke_range,
|
||||
tile2_fill_range,
|
||||
tile_mask_indices_uniform_buffer,
|
||||
tile_mask_range,
|
||||
tile_mask_instances,
|
||||
camera,
|
||||
projection,
|
||||
@ -567,15 +537,11 @@ impl State {
|
||||
pass.set_bind_group(0, &self.bind_group, &[]);
|
||||
|
||||
{
|
||||
// Draw Mask
|
||||
// Draw masks
|
||||
pass.set_pipeline(&self.mask_pipeline);
|
||||
pass.set_index_buffer(
|
||||
self.tile_mask_indices_uniform_buffer.slice(..),
|
||||
INDEX_FORMAT,
|
||||
);
|
||||
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_vertex_buffer(0, self.tile_mask_instances.slice(..));
|
||||
// Draw 11 squares each out of 6 vertices
|
||||
pass.draw(0..6, 0..11);
|
||||
}
|
||||
{
|
||||
pass.set_pipeline(&self.render_pipeline);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user