use std::sync::LazyLock;
use awsm_renderer_core::cubemap::CubemapImage;
use awsm_renderer_core::sampler::{AddressMode, FilterMode, MipmapFilterMode};
use awsm_renderer_core::{cubemap::images::CubemapBitmapColors, renderer::AwsmRendererWebGpu};
use crate::error::Result;
use crate::textures::{CubemapTextureKey, SamplerCacheKey, Textures};
#[derive(Clone)]
pub struct Ibl {
pub prefiltered_env: IblTexture,
pub irradiance: IblTexture,
}
impl Ibl {
pub fn new(prefiltered_env: IblTexture, irradiance: IblTexture) -> Self {
Self {
prefiltered_env,
irradiance,
}
}
}
#[derive(Clone)]
pub struct IblTexture {
pub texture_key: CubemapTextureKey,
pub texture_view: web_sys::GpuTextureView,
pub sampler: web_sys::GpuSampler,
pub mip_count: u32,
}
static SAMPLER_CACHE_KEY: LazyLock<SamplerCacheKey> = LazyLock::new(|| SamplerCacheKey {
address_mode_u: Some(AddressMode::ClampToEdge),
address_mode_v: Some(AddressMode::ClampToEdge),
address_mode_w: Some(AddressMode::ClampToEdge),
mag_filter: Some(FilterMode::Linear),
min_filter: Some(FilterMode::Linear),
mipmap_filter: Some(MipmapFilterMode::Linear),
max_anisotropy: Some(16),
..Default::default()
});
impl IblTexture {
pub fn sampler_cache_key() -> SamplerCacheKey {
SAMPLER_CACHE_KEY.clone()
}
pub fn new(
texture_key: CubemapTextureKey,
texture_view: web_sys::GpuTextureView,
sampler: web_sys::GpuSampler,
mip_count: u32,
) -> Self {
Self {
texture_key,
texture_view,
sampler,
mip_count,
}
}
pub async fn new_colors(
gpu: &AwsmRendererWebGpu,
textures: &mut Textures,
default_colors: CubemapBitmapColors,
) -> Result<Self> {
let resources = Self::prepare_resources(gpu, default_colors).await?;
Self::register(gpu, textures, resources)
}
pub async fn prepare_resources(
gpu: &AwsmRendererWebGpu,
default_colors: CubemapBitmapColors,
) -> Result<IblTextureResources> {
let (texture, view, mip_count) = CubemapImage::new_colors(default_colors, 256, 256)
.await?
.create_texture_and_view(gpu, Some("IBL Cubemap"))
.await?;
Ok(IblTextureResources {
texture,
view,
mip_count,
})
}
pub fn register(
gpu: &AwsmRendererWebGpu,
textures: &mut Textures,
resources: IblTextureResources,
) -> Result<Self> {
let texture_key = textures.insert_cubemap(resources.texture);
let sampler_key = textures.get_sampler_key(gpu, Self::sampler_cache_key())?;
let sampler = textures.get_sampler(sampler_key)?.clone();
Ok(Self::new(
texture_key,
resources.view,
sampler,
resources.mip_count,
))
}
}
pub struct IblTextureResources {
pub texture: web_sys::GpuTexture,
pub view: web_sys::GpuTextureView,
pub mip_count: u32,
}