use exr::prelude::{ReadChannels, ReadLayers}; use std::path::Path; pub fn load_exr_heightmap( device: &wgpu::Device, queue: &wgpu::Queue, path: impl AsRef, ) -> Result<(wgpu::Texture, wgpu::TextureView, wgpu::Sampler), Box> { let image = exr::prelude::read() .no_deep_data() .largest_resolution_level() .all_channels() .all_layers() .all_attributes() .from_file(path)?; let layer = &image.layer_data[0]; let width = layer.size.width() as u32; let height = layer.size.height() as u32; let channel = &layer.channel_data.list[0]; let float_data: Vec = channel.sample_data.values_as_f32().collect(); let texture_size = wgpu::Extent3d { width, height, depth_or_array_layers: 1, }; let texture = device.create_texture(&wgpu::TextureDescriptor { label: Some("Height Map Texture"), size: texture_size, mip_level_count: 1, sample_count: 1, dimension: wgpu::TextureDimension::D2, format: wgpu::TextureFormat::R32Float, usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, view_formats: &[], }); queue.write_texture( texture.as_image_copy(), bytemuck::cast_slice(&float_data), wgpu::TexelCopyBufferLayout { offset: 0, bytes_per_row: Some(4 * width), rows_per_image: Some(height), }, texture_size, ); let view = texture.create_view(&wgpu::TextureViewDescriptor::default()); let sampler = device.create_sampler(&wgpu::SamplerDescriptor { label: Some("Height Map Sampler"), address_mode_u: wgpu::AddressMode::ClampToEdge, address_mode_v: wgpu::AddressMode::ClampToEdge, address_mode_w: wgpu::AddressMode::ClampToEdge, mag_filter: wgpu::FilterMode::Nearest, min_filter: wgpu::FilterMode::Nearest, mipmap_filter: wgpu::FilterMode::Nearest, ..Default::default() }); Ok((texture, view, sampler)) }