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 { use {
bytemuck::{Pod, Zeroable}, bytemuck::{Pod, Zeroable},
std::{borrow::Cow, num::NonZero, rc::Rc}, std::{borrow::Cow, num::NonZero, rc::Rc},
@ -70,6 +70,7 @@ impl Camera {
struct UniformBufferContents { struct UniformBufferContents {
camera_matrix: [f32; 16], camera_matrix: [f32; 16],
dem_texture_size: [u32; 2], 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 // 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> // 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()); .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<'_> { fn get_binding(&self) -> wgpu::BindingResource<'_> {
wgpu::BindingResource::Buffer(wgpu::BufferBinding { wgpu::BindingResource::Buffer(wgpu::BufferBinding {
buffer: &self.gpu_buffer, buffer: &self.gpu_buffer,
@ -144,11 +151,14 @@ impl DemRenderer {
let index_count = index_data.len(); let index_count = index_data.len();
let (dem_texture_view, dem_texture_size) = load_dem_texture(&source, device, queue); 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 camera = Camera::new(surface_config.width as f32 / surface_config.height as f32);
let mut uniforms = UniformBufferManager::new(device); let mut uniforms = UniformBufferManager::new(device);
uniforms.set_dem_texture_size(dem_texture_size); 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 { let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
label: None, label: None,
@ -173,6 +183,16 @@ impl DemRenderer {
}, },
count: None, 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, binding: 1,
resource: wgpu::BindingResource::TextureView(&dem_texture_view), resource: wgpu::BindingResource::TextureView(&dem_texture_view),
}, },
wgpu::BindGroupEntry {
binding: 2,
resource: wgpu::BindingResource::TextureView(&dembvh_texture_view),
},
], ],
label: Some("DemRendererBindGroup"), 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 { 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; let animation_phase = 2.0 * std::f32::consts::PI * (animation_time.as_secs_f32() % 10.0) / 10.0;
glam::Vec3::new( glam::Vec3::new(

View File

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

View File

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

View File

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