Refactor shader to get translate directly

This commit is contained in:
Maximilian Ammann 2022-01-01 17:10:51 +01:00
parent b91c9ea2d1
commit 7d0b6497eb
3 changed files with 73 additions and 75 deletions

View File

@ -65,33 +65,53 @@ impl VertexShaderState {
pub mod tile { pub mod tile {
use crate::platform::COLOR_TEXTURE_FORMAT; use crate::platform::COLOR_TEXTURE_FORMAT;
use crate::render::shader_ffi::GpuVertexUniform; use crate::render::shader_ffi::{GpuVertexUniform, TileUniform};
use super::{FragmentShaderState, VertexShaderState}; use super::{FragmentShaderState, VertexShaderState};
pub const VERTEX: VertexShaderState = VertexShaderState::new( pub const VERTEX: VertexShaderState = VertexShaderState::new(
include_str!("tile.vertex.wgsl"), include_str!("tile.vertex.wgsl"),
&[wgpu::VertexBufferLayout { &[
array_stride: std::mem::size_of::<GpuVertexUniform>() as u64, wgpu::VertexBufferLayout {
step_mode: wgpu::VertexStepMode::Vertex, array_stride: std::mem::size_of::<GpuVertexUniform>() as u64,
attributes: &[ step_mode: wgpu::VertexStepMode::Vertex,
wgpu::VertexAttribute { attributes: &[
offset: 0, wgpu::VertexAttribute {
format: wgpu::VertexFormat::Float32x2, offset: 0,
shader_location: 0, format: wgpu::VertexFormat::Float32x2,
}, shader_location: 0,
wgpu::VertexAttribute { },
offset: wgpu::VertexFormat::Float32x2.size(), wgpu::VertexAttribute {
format: wgpu::VertexFormat::Float32x2, offset: wgpu::VertexFormat::Float32x2.size(),
shader_location: 1, format: wgpu::VertexFormat::Float32x2,
}, shader_location: 1,
wgpu::VertexAttribute { },
offset: 2 * wgpu::VertexFormat::Float32x2.size(), wgpu::VertexAttribute {
format: wgpu::VertexFormat::Uint32, offset: 2 * wgpu::VertexFormat::Float32x2.size(),
shader_location: 2, format: wgpu::VertexFormat::Uint32,
}, shader_location: 2,
], },
}], ],
},
wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<TileUniform>() as u64,
step_mode: wgpu::VertexStepMode::Instance,
attributes: &[
// color
wgpu::VertexAttribute {
offset: 0,
format: wgpu::VertexFormat::Float32x4,
shader_location: 3,
},
// translate
wgpu::VertexAttribute {
offset: wgpu::VertexFormat::Float32x4.size(),
format: wgpu::VertexFormat::Float32x2,
shader_location: 4,
},
],
},
],
); );
pub const FRAGMENT: FragmentShaderState = FragmentShaderState::new( pub const FRAGMENT: FragmentShaderState = FragmentShaderState::new(

View File

@ -15,12 +15,7 @@ struct TileUniform {
pad2: i32; pad2: i32;
}; };
struct Tiles {
tiles: [[stride(32)]] array<TileUniform, 128>;
};
[[group(0), binding(0)]] var<uniform> globals: GlobalsUniform; [[group(0), binding(0)]] var<uniform> globals: GlobalsUniform;
[[group(0), binding(1)]] var<uniform> tiles: Tiles;
struct VertexOutput { struct VertexOutput {
[[location(0)]] v_color: vec4<f32>; [[location(0)]] v_color: vec4<f32>;
@ -32,14 +27,15 @@ fn main(
[[location(0)]] position: vec2<f32>, [[location(0)]] position: vec2<f32>,
[[location(1)]] normal: vec2<f32>, [[location(1)]] normal: vec2<f32>,
[[location(2)]] tile_id: u32, [[location(2)]] tile_id: u32,
[[location(3)]] color: vec4<f32>,
[[location(4)]] translate: vec2<f32>,
[[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 tile = tiles.tiles[instance_idx];
let z = 0.0; let z = 0.0;
let world_pos = position + tile.translate + normal; let world_pos = position + translate + normal;
let 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(tile.color, position); return VertexOutput(color, position);
} }

View File

@ -6,15 +6,13 @@ use std::ops::Range;
use log::{trace, warn}; use log::{trace, warn};
use lyon::tessellation::VertexBuffers; use lyon::tessellation::VertexBuffers;
use wgpu::util::DeviceExt; use wgpu::util::DeviceExt;
use wgpu::{Buffer, Limits, Queue}; use wgpu::{Buffer, BufferAddress, Limits, Queue};
use winit::dpi::PhysicalSize; use winit::dpi::PhysicalSize;
use winit::event::{ use winit::event::{
DeviceEvent, ElementState, KeyboardInput, MouseButton, TouchPhase, WindowEvent, DeviceEvent, ElementState, KeyboardInput, MouseButton, TouchPhase, WindowEvent,
}; };
use winit::window::Window; use winit::window::Window;
use vector_tile::parse_tile_reader;
use crate::fps_meter::FPSMeter; use crate::fps_meter::FPSMeter;
use crate::io::cache::Cache; use crate::io::cache::Cache;
use crate::io::{static_database, TileCoords}; use crate::io::{static_database, TileCoords};
@ -190,7 +188,7 @@ impl State {
let tiles_uniform_buffer = device.create_buffer(&wgpu::BufferDescriptor { let tiles_uniform_buffer = device.create_buffer(&wgpu::BufferDescriptor {
label: Some("Tiles ubo"), label: Some("Tiles ubo"),
size: tiles_uniform_buffer_size, size: tiles_uniform_buffer_size,
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
mapped_at_creation: false, mapped_at_creation: false,
}); });
@ -203,47 +201,27 @@ impl State {
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: Some("Bind group layout"), label: Some("Bind group layout"),
entries: &[ entries: &[wgpu::BindGroupLayoutEntry {
wgpu::BindGroupLayoutEntry { binding: 0,
binding: 0, visibility: wgpu::ShaderStages::VERTEX,
visibility: wgpu::ShaderStages::VERTEX, ty: wgpu::BindingType::Buffer {
ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform,
ty: wgpu::BufferBindingType::Uniform, has_dynamic_offset: false,
has_dynamic_offset: false, min_binding_size: wgpu::BufferSize::new(globals_buffer_byte_size),
min_binding_size: wgpu::BufferSize::new(globals_buffer_byte_size),
},
count: None,
}, },
wgpu::BindGroupLayoutEntry { count: None,
binding: 1, }],
visibility: wgpu::ShaderStages::VERTEX,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: wgpu::BufferSize::new(tiles_uniform_buffer_size),
},
count: None,
},
],
}); });
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
label: Some("Bind group"), label: Some("Bind group"),
layout: &bind_group_layout, layout: &bind_group_layout,
entries: &[ entries: &[wgpu::BindGroupEntry {
wgpu::BindGroupEntry { binding: 0,
binding: 0, resource: wgpu::BindingResource::Buffer(
resource: wgpu::BindingResource::Buffer( globals_uniform_buffer.as_entire_buffer_binding(),
globals_uniform_buffer.as_entire_buffer_binding(), ),
), }],
},
wgpu::BindGroupEntry {
binding: 1,
resource: wgpu::BindingResource::Buffer(
tiles_uniform_buffer.as_entire_buffer_binding(),
),
},
],
}); });
let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
@ -327,7 +305,7 @@ impl State {
sample_count, sample_count,
scene: SceneParams::new(), scene: SceneParams::new(),
globals_uniform_buffer, globals_uniform_buffer,
tiles_uniform_buffer: tiles_uniform_buffer, tiles_uniform_buffer,
fps_meter: FPSMeter::new(), fps_meter: FPSMeter::new(),
tile_mask_instances, tile_mask_instances,
camera, camera,
@ -507,16 +485,20 @@ impl State {
.vertices() .vertices()
.slice(entry.vertices_buffer_range()), .slice(entry.vertices_buffer_range()),
); );
let id = entry.id as BufferAddress;
pass.set_vertex_buffer(
1,
self.tiles_uniform_buffer.slice(
std::mem::size_of::<TileUniform>() as u64 * id
..std::mem::size_of::<TileUniform>() as u64 * (id + 1),
),
);
/* if !self.tile_fill_range.is_empty() { /* if !self.tile_fill_range.is_empty() {
pass.draw_indexed(self.tile_fill_range.clone(), 0, 0..1); pass.draw_indexed(self.tile_fill_range.clone(), 0, 0..1);
}*/ }*/
trace!("current buffer_pool index {:?}", self.buffer_pool.index); trace!("current buffer_pool index {:?}", self.buffer_pool.index);
// FIXME: Custom Instance index possibly breaks on Metal // FIXME: Custom Instance index possibly breaks on Metal
pass.draw_indexed( pass.draw_indexed(entry.indices_range(), 0, 0..1);
entry.indices_range(),
0,
entry.id as u32..(entry.id + 1) as u32,
);
} }
} }
} }