#[derive(Debug)]
pub struct TextureTarget {
texture: wgpu::Texture,
view: wgpu::TextureView,
format: wgpu::TextureFormat,
width: u32,
height: u32,
}
impl TextureTarget {
pub fn new(
device: &wgpu::Device,
label: &'static str,
width: u32,
height: u32,
format: wgpu::TextureFormat,
usage: wgpu::TextureUsages,
) -> Self {
let texture = device.create_texture(&wgpu::TextureDescriptor {
label: Some(label),
size: wgpu::Extent3d {
width,
height,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: wgpu::TextureDimension::D2,
format,
usage,
view_formats: &[],
});
let view = texture.create_view(&wgpu::TextureViewDescriptor::default());
Self {
texture,
view,
format,
width,
height,
}
}
#[inline]
pub const fn view(&self) -> &wgpu::TextureView {
&self.view
}
#[inline]
pub const fn texture(&self) -> &wgpu::Texture {
&self.texture
}
#[inline]
pub const fn format(&self) -> wgpu::TextureFormat {
self.format
}
#[inline]
pub const fn width(&self) -> u32 {
self.width
}
#[inline]
pub const fn height(&self) -> u32 {
self.height
}
}
#[derive(Debug)]
pub struct GBuffer {
albedo: TextureTarget,
normal: TextureTarget,
material: TextureTarget,
depth: TextureTarget,
width: u32,
height: u32,
}
impl GBuffer {
pub fn new(device: &wgpu::Device, width: u32, height: u32) -> Self {
let color_usage =
wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING;
let depth_usage =
wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING;
Self {
albedo: TextureTarget::new(
device,
"scenix.gbuffer.albedo",
width,
height,
wgpu::TextureFormat::Rgba8Unorm,
color_usage,
),
normal: TextureTarget::new(
device,
"scenix.gbuffer.normal",
width,
height,
wgpu::TextureFormat::Rgba16Float,
color_usage,
),
material: TextureTarget::new(
device,
"scenix.gbuffer.material",
width,
height,
wgpu::TextureFormat::Rgba8Unorm,
color_usage,
),
depth: TextureTarget::new(
device,
"scenix.gbuffer.depth",
width,
height,
wgpu::TextureFormat::Depth32Float,
depth_usage,
),
width,
height,
}
}
#[inline]
pub fn resize(&mut self, device: &wgpu::Device, width: u32, height: u32) {
if self.width != width || self.height != height {
*self = Self::new(device, width, height);
}
}
#[inline]
pub const fn width(&self) -> u32 {
self.width
}
#[inline]
pub const fn height(&self) -> u32 {
self.height
}
#[inline]
pub const fn albedo(&self) -> &TextureTarget {
&self.albedo
}
#[inline]
pub const fn normal(&self) -> &TextureTarget {
&self.normal
}
#[inline]
pub const fn material(&self) -> &TextureTarget {
&self.material
}
#[inline]
pub const fn depth(&self) -> &TextureTarget {
&self.depth
}
}