#![allow(clippy::type_complexity)]
#![allow(clippy::too_many_arguments)]
#![allow(clippy::match_like_matches_macro)]
#![allow(clippy::vec_init_then_push)]
pub mod anti_alias;
pub mod bind_group_layout;
pub mod bind_groups;
pub mod bounds;
pub mod buffer;
pub mod camera;
pub mod debug;
pub mod environment;
pub mod error;
pub mod frustum;
pub mod instances;
pub mod lights;
pub mod materials;
pub mod meshes;
pub mod picker;
pub mod pipeline_layouts;
pub mod pipelines;
pub mod post_process;
pub mod render;
pub mod render_passes;
pub mod render_textures;
pub mod renderable;
pub mod shaders;
pub mod textures;
pub mod transforms;
pub mod update;
pub mod core {
pub use awsm_renderer_core::*;
}
#[cfg(feature = "gltf")]
pub mod gltf;
#[cfg(feature = "animation")]
pub mod animation;
use std::sync::LazyLock;
use awsm_renderer_core::{
brdf_lut::generate::{BrdfLut, BrdfLutOptions},
command::color::Color,
compatibility::CompatibilityRequirements,
cubemap::images::CubemapBitmapColors,
renderer::{AwsmRendererWebGpu, AwsmRendererWebGpuBuilder},
};
use bind_groups::BindGroups;
use camera::CameraBuffer;
use instances::Instances;
use lights::Lights;
use materials::Materials;
use meshes::Meshes;
use pipelines::Pipelines;
use shaders::Shaders;
use textures::Textures;
use transforms::Transforms;
use crate::{
anti_alias::AntiAliasing,
bind_group_layout::BindGroupLayouts,
debug::AwsmRendererLogging,
environment::{Environment, Skybox},
lights::ibl::{Ibl, IblTexture},
picker::Picker,
pipeline_layouts::PipelineLayouts,
post_process::PostProcessing,
render_passes::{RenderPassInitContext, RenderPasses},
render_textures::{RenderTextureFormats, RenderTextures},
};
pub struct AwsmRenderer {
pub gpu: core::renderer::AwsmRendererWebGpu,
pub bind_group_layouts: BindGroupLayouts,
pub bind_groups: BindGroups,
pub meshes: Meshes,
pub camera: CameraBuffer,
pub transforms: Transforms,
pub instances: Instances,
pub shaders: Shaders,
pub materials: Materials,
pub pipeline_layouts: PipelineLayouts,
pub pipelines: Pipelines,
pub lights: Lights,
pub textures: Textures,
pub logging: AwsmRendererLogging,
pub render_textures: RenderTextures,
pub render_passes: RenderPasses,
pub environment: Environment,
pub anti_aliasing: AntiAliasing,
pub post_processing: PostProcessing,
pub picker: Picker,
_clear_color_perceptual_to_linear: Color,
_clear_color: Color,
#[cfg(feature = "gltf")]
gltf: gltf::cache::GltfCache,
#[cfg(feature = "animation")]
pub animations: animation::Animations,
}
pub static COMPATIBITLIY_REQUIREMENTS: LazyLock<CompatibilityRequirements> =
LazyLock::new(|| CompatibilityRequirements {
storage_buffers: Some(9),
});
impl AwsmRenderer {
pub async fn remove_all(&mut self) -> crate::error::Result<()> {
let renderer = AwsmRendererBuilder::new(self.gpu.clone())
.with_logging(self.logging.clone())
.with_clear_color(self._clear_color.clone())
.with_render_texture_formats(self.render_textures.formats.clone())
.build()
.await?;
*self = renderer;
Ok(())
}
}
pub struct AwsmRendererBuilder {
gpu: AwsmRendererGpuBuilderKind,
logging: AwsmRendererLogging,
render_texture_formats: Option<RenderTextureFormats>,
brdf_lut_options: BrdfLutOptions,
clear_color: Color,
skybox_colors: CubemapBitmapColors,
ibl_filtered_env_colors: CubemapBitmapColors,
ibl_irradiance_colors: CubemapBitmapColors,
anti_aliasing: AntiAliasing,
post_processing: PostProcessing,
}
pub enum AwsmRendererGpuBuilderKind {
WebGpuBuilder(AwsmRendererWebGpuBuilder),
WebGpuBuilt(AwsmRendererWebGpu),
}
impl From<AwsmRendererWebGpuBuilder> for AwsmRendererGpuBuilderKind {
fn from(builder: AwsmRendererWebGpuBuilder) -> Self {
AwsmRendererGpuBuilderKind::WebGpuBuilder(builder)
}
}
impl From<AwsmRendererWebGpu> for AwsmRendererGpuBuilderKind {
fn from(gpu: AwsmRendererWebGpu) -> Self {
AwsmRendererGpuBuilderKind::WebGpuBuilt(gpu)
}
}
impl AwsmRendererBuilder {
pub fn new(gpu: impl Into<AwsmRendererGpuBuilderKind>) -> Self {
Self {
gpu: gpu.into(),
logging: AwsmRendererLogging::default(),
render_texture_formats: None,
clear_color: Color::BLACK,
brdf_lut_options: BrdfLutOptions::default(),
skybox_colors: CubemapBitmapColors {
z_positive: Color::BLACK,
z_negative: Color::BLACK,
x_positive: Color::BLACK,
x_negative: Color::BLACK,
y_positive: Color::BLACK,
y_negative: Color::BLACK,
},
ibl_filtered_env_colors: CubemapBitmapColors {
z_positive: Color::WHITE,
z_negative: Color::WHITE,
x_positive: Color::WHITE,
x_negative: Color::WHITE,
y_positive: Color::WHITE,
y_negative: Color::WHITE,
},
ibl_irradiance_colors: CubemapBitmapColors {
z_positive: Color::WHITE,
z_negative: Color::WHITE,
x_positive: Color::WHITE,
x_negative: Color::WHITE,
y_positive: Color::WHITE,
y_negative: Color::WHITE,
},
anti_aliasing: AntiAliasing::default(),
post_processing: PostProcessing::default(),
}
}
pub fn with_brdf_lut_options(mut self, options: BrdfLutOptions) -> Self {
self.brdf_lut_options = options;
self
}
pub fn with_ibl_filtered_env_colors(mut self, colors: CubemapBitmapColors) -> Self {
self.ibl_filtered_env_colors = colors;
self
}
pub fn with_anti_aliasing(mut self, anti_aliasing: AntiAliasing) -> Self {
self.anti_aliasing = anti_aliasing;
self
}
pub fn with_ibl_irradiance_colors(mut self, colors: CubemapBitmapColors) -> Self {
self.ibl_irradiance_colors = colors;
self
}
pub fn with_skybox_colors(mut self, colors: CubemapBitmapColors) -> Self {
self.skybox_colors = colors;
self
}
pub fn with_logging(mut self, logging: AwsmRendererLogging) -> Self {
self.logging = logging;
self
}
pub fn with_render_texture_formats(mut self, formats: RenderTextureFormats) -> Self {
self.render_texture_formats = Some(formats);
self
}
pub fn with_clear_color(mut self, color: Color) -> Self {
self.clear_color = color;
self
}
pub async fn build(self) -> std::result::Result<AwsmRenderer, crate::error::AwsmError> {
let Self {
gpu,
logging,
render_texture_formats,
brdf_lut_options,
clear_color,
skybox_colors,
ibl_filtered_env_colors,
ibl_irradiance_colors,
anti_aliasing,
post_processing,
} = self;
let mut gpu = match gpu {
AwsmRendererGpuBuilderKind::WebGpuBuilder(builder) => builder.build().await?,
AwsmRendererGpuBuilderKind::WebGpuBuilt(gpu) => gpu,
};
let mut render_texture_formats = match render_texture_formats {
Some(formats) => formats,
None => RenderTextureFormats::new(&gpu.device).await,
};
let mut pipeline_layouts = PipelineLayouts::new();
let mut bind_group_layouts = BindGroupLayouts::new();
let mut pipelines = Pipelines::new();
let mut shaders = Shaders::new();
let mut textures = Textures::new(&gpu)?;
let camera = camera::CameraBuffer::new(&gpu)?;
let lights = Lights::new(
&gpu,
Ibl::new(
IblTexture::new_colors(&gpu, &mut textures, ibl_filtered_env_colors).await?,
IblTexture::new_colors(&gpu, &mut textures, ibl_irradiance_colors).await?,
),
BrdfLut::new(&gpu, brdf_lut_options).await?,
)?;
let meshes = Meshes::new(&gpu)?;
let transforms = Transforms::new(&gpu)?;
let instances = Instances::new(&gpu)?;
let materials = Materials::new(&gpu)?;
let environment =
Environment::new(Skybox::new_colors(&gpu, &mut textures, skybox_colors).await?);
let mut render_pass_init = RenderPassInitContext {
gpu: &mut gpu,
bind_group_layouts: &mut bind_group_layouts,
pipeline_layouts: &mut pipeline_layouts,
pipelines: &mut pipelines,
shaders: &mut shaders,
render_texture_formats: &mut render_texture_formats,
textures: &mut textures,
};
let render_passes = RenderPasses::new(&mut render_pass_init).await?;
let bind_groups = BindGroups::new();
let render_textures = RenderTextures::new(&gpu, render_texture_formats).await?;
let picker = Picker::new(
&gpu,
&mut bind_group_layouts,
&mut pipeline_layouts,
&mut shaders,
&mut pipelines,
)
.await?;
#[cfg(feature = "gltf")]
let gltf = gltf::cache::GltfCache::default();
#[cfg(feature = "animation")]
let animations = animation::Animations::default();
let mut _self = AwsmRenderer {
gpu,
meshes,
camera,
transforms,
instances,
shaders,
bind_group_layouts,
bind_groups,
materials,
pipeline_layouts,
pipelines,
lights,
textures,
environment,
render_passes,
_clear_color: clear_color.clone(),
_clear_color_perceptual_to_linear: clear_color.perceptual_to_linear(),
logging,
render_textures,
anti_aliasing,
post_processing,
picker,
#[cfg(feature = "gltf")]
gltf,
#[cfg(feature = "animation")]
animations,
};
_self.set_anti_aliasing(_self.anti_aliasing.clone()).await?;
_self
.set_post_processing(_self.post_processing.clone())
.await?;
Ok(_self)
}
}