Load DEM BVH into texture

This commit is contained in:
Matthew Gordon 2024-11-22 21:42:37 -04:00
parent ab2e366e7f
commit 5e3b97ed61
4 changed files with 86 additions and 7 deletions

View File

@ -1,4 +1,4 @@
use super::raster::Dem;
use super::raster::{Dem, DemBvh};
use {
bytemuck::{Pod, Zeroable},
std::{borrow::Cow, num::NonZero, rc::Rc},
@ -70,6 +70,7 @@ impl Camera {
struct UniformBufferContents {
camera_matrix: [f32; 16],
dem_texture_size: [u32; 2],
dembvh_texture_size: [u32; 2],
}
// This struct is 72 bytes but WGSL expects the buffer size to be be a multiple
// of the alignment of the member with the largest alignment. The mat4x4<f32>
@ -107,6 +108,12 @@ impl UniformBufferManager {
.clone_from_slice(&dem_texture_size.to_array());
}
fn set_dembvh_texture_size(&mut self, dembvh_texture_size: glam::UVec2) {
self.cpu_buffer
.dembvh_texture_size
.clone_from_slice(&dembvh_texture_size.to_array());
}
fn get_binding(&self) -> wgpu::BindingResource<'_> {
wgpu::BindingResource::Buffer(wgpu::BufferBinding {
buffer: &self.gpu_buffer,
@ -144,11 +151,14 @@ impl DemRenderer {
let index_count = index_data.len();
let (dem_texture_view, dem_texture_size) = load_dem_texture(&source, device, queue);
let (dembvh_texture_view, dembvh_texture_size) =
create_dembvh_texture(&source, device, queue);
let camera = Camera::new(surface_config.width as f32 / surface_config.height as f32);
let mut uniforms = UniformBufferManager::new(device);
uniforms.set_dem_texture_size(dem_texture_size);
uniforms.set_dembvh_texture_size(dembvh_texture_size);
let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: None,
@ -173,6 +183,16 @@ impl DemRenderer {
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 2,
visibility: wgpu::ShaderStages::FRAGMENT,
ty: wgpu::BindingType::Texture {
multisampled: false,
sample_type: wgpu::TextureSampleType::Uint,
view_dimension: wgpu::TextureViewDimension::D2,
},
count: None,
},
],
});
@ -187,6 +207,10 @@ impl DemRenderer {
binding: 1,
resource: wgpu::BindingResource::TextureView(&dem_texture_view),
},
wgpu::BindGroupEntry {
binding: 2,
resource: wgpu::BindingResource::TextureView(&dembvh_texture_view),
},
],
label: Some("DemRendererBindGroup"),
});
@ -397,6 +421,57 @@ fn load_dem_texture(
)
}
fn create_dembvh_texture(
dem: &Dem,
device: &wgpu::Device,
queue: &wgpu::Queue,
) -> (wgpu::TextureView, glam::UVec2) {
let source = DemBvh::new(dem);
let dembvh_size = source.layers.first().expect("DEM BVH contains layers").size;
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some("Dem Texture"),
size: wgpu::Extent3d {
width: dembvh_size,
height: dembvh_size,
depth_or_array_layers: 1,
},
mip_level_count: source.layers.len() as u32,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format: wgpu::TextureFormat::Rg16Uint,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
view_formats: &[],
});
for (level, grid) in source.layers.iter().enumerate() {
queue.write_texture(
wgpu::ImageCopyTexture {
texture: &texture,
mip_level: level as u32,
origin: wgpu::Origin3d::ZERO,
aspect: wgpu::TextureAspect::All,
},
bytemuck::cast_slice(&grid.data[..]),
wgpu::ImageDataLayout {
offset: 0,
bytes_per_row: Some(std::mem::size_of::<u16>() as u32 * 2 * grid.size),
rows_per_image: Some(grid.size),
},
wgpu::Extent3d {
width: grid.size,
height: grid.size,
depth_or_array_layers: 1,
},
);
}
(
texture.create_view(&wgpu::TextureViewDescriptor::default()),
glam::UVec2::new(dembvh_size, dembvh_size),
)
}
fn get_animated_camera_position(animation_time: std::time::Duration, dem_size: f32) -> glam::Vec3 {
let animation_phase = 2.0 * std::f32::consts::PI * (animation_time.as_secs_f32() % 10.0) / 10.0;
glam::Vec3::new(

View File

@ -5,7 +5,8 @@ struct VertexOutput {
struct Uniforms {
transform: mat4x4<f32>,
dem_texture_size: vec2<u32>
dem_texture_size: vec2<u32>,
dembvh_texture_size: vec2<u32>
}
@group(0) @binding(0)
@ -14,6 +15,9 @@ var<uniform> uniforms: Uniforms;
@group(0) @binding(1)
var dem_texture: texture_2d<u32>;
@group(0) @binding(2)
var dembvh_texture: texture_2d<u32>;
@vertex
fn vs_main(
@ -28,7 +32,7 @@ fn vs_main(
@fragment
fn fs_solid(vertex: VertexOutput) -> @location(0) vec4<f32> {
let texture_index = vec2<i32>(fract(abs(vertex.test)/500.0)*vec2<f32>(uniforms.dem_texture_size));
let v_i = textureLoad(dem_texture, texture_index, 0).r;
let v = f32(v_i) / 65535.0;
return vec4<f32>(v, v, 1.0, 1.0);
let v_i = vec3<u32>(textureLoad(dem_texture, texture_index, 0).r, textureLoad(dembvh_texture, texture_index, 0).rg);
let v = vec3<f32>(v_i) / 65535.0;
return vec4<f32>(v, 1.0);
}

View File

@ -59,7 +59,7 @@ fn round_bound(v: u32) -> u32 {
}
impl DemBvh {
fn new(dem: &Dem) -> DemBvh {
pub fn new(dem: &Dem) -> DemBvh {
let mut layers = vec![create_first_dembvh_layer(dem)];
while layers.last().unwrap().size > 1 {
layers.push(create_next_dembvh_layer(layers.last().unwrap()));

View File

@ -1,3 +1,3 @@
mod dem;
pub use dem::Dem;
pub use dem::{Dem, DemBvh};