1#![allow(clippy::type_complexity)]
4#![allow(clippy::too_many_arguments)]
5#![allow(clippy::match_like_matches_macro)]
6#![allow(clippy::vec_init_then_push)]
7pub mod anti_alias;
8pub mod bind_group_layout;
9pub mod bind_groups;
10pub mod bounds;
11pub mod buffer;
12pub mod camera;
13pub mod debug;
14pub mod environment;
15pub mod error;
16pub mod frustum;
17pub mod instances;
18pub mod lights;
19pub mod materials;
20pub mod meshes;
21pub mod picker;
22pub mod pipeline_layouts;
23pub mod pipelines;
24pub mod post_process;
25pub mod render;
26pub mod render_passes;
27pub mod render_textures;
28pub mod renderable;
29pub mod shaders;
30pub mod textures;
31pub mod transforms;
32pub mod update;
33pub mod core {
35 pub use awsm_renderer_core::*;
36}
37#[cfg(feature = "gltf")]
38pub mod gltf;
39
40#[cfg(feature = "animation")]
41pub mod animation;
42
43use std::sync::LazyLock;
44
45use awsm_renderer_core::{
46 brdf_lut::generate::{BrdfLut, BrdfLutOptions},
47 command::color::Color,
48 compatibility::CompatibilityRequirements,
49 cubemap::images::CubemapBitmapColors,
50 renderer::{AwsmRendererWebGpu, AwsmRendererWebGpuBuilder},
51};
52use bind_groups::BindGroups;
53use camera::CameraBuffer;
54use instances::Instances;
55use lights::Lights;
56use materials::Materials;
57use meshes::Meshes;
58use pipelines::Pipelines;
59use shaders::Shaders;
60use textures::Textures;
61use transforms::Transforms;
62
63use crate::{
64 anti_alias::AntiAliasing,
65 bind_group_layout::BindGroupLayouts,
66 debug::AwsmRendererLogging,
67 environment::{Environment, Skybox},
68 lights::ibl::{Ibl, IblTexture},
69 picker::Picker,
70 pipeline_layouts::PipelineLayouts,
71 post_process::PostProcessing,
72 render_passes::{RenderPassInitContext, RenderPasses},
73 render_textures::{RenderTextureFormats, RenderTextures},
74};
75
76pub struct AwsmRenderer {
78 pub gpu: core::renderer::AwsmRendererWebGpu,
79 pub bind_group_layouts: BindGroupLayouts,
80 pub bind_groups: BindGroups,
81 pub meshes: Meshes,
82 pub camera: CameraBuffer,
83 pub transforms: Transforms,
84 pub instances: Instances,
85 pub shaders: Shaders,
86 pub materials: Materials,
87 pub pipeline_layouts: PipelineLayouts,
88 pub pipelines: Pipelines,
89 pub lights: Lights,
90 pub textures: Textures,
91 pub logging: AwsmRendererLogging,
92 pub render_textures: RenderTextures,
93 pub render_passes: RenderPasses,
94 pub environment: Environment,
95 pub anti_aliasing: AntiAliasing,
96 pub post_processing: PostProcessing,
97 pub picker: Picker,
98 _clear_color_perceptual_to_linear: Color,
100 _clear_color: Color,
101
102 #[cfg(feature = "gltf")]
103 gltf: gltf::cache::GltfCache,
104
105 #[cfg(feature = "animation")]
106 pub animations: animation::Animations,
107}
108
109pub static COMPATIBITLIY_REQUIREMENTS: LazyLock<CompatibilityRequirements> =
111 LazyLock::new(|| CompatibilityRequirements {
112 storage_buffers: Some(9),
113 });
114
115impl AwsmRenderer {
116 pub async fn remove_all(&mut self) -> crate::error::Result<()> {
118 let renderer = AwsmRendererBuilder::new(self.gpu.clone())
120 .with_logging(self.logging.clone())
121 .with_clear_color(self._clear_color.clone())
122 .with_render_texture_formats(self.render_textures.formats.clone())
123 .build()
124 .await?;
125
126 *self = renderer;
127 Ok(())
128 }
129}
130
131pub struct AwsmRendererBuilder {
133 gpu: AwsmRendererGpuBuilderKind,
134 logging: AwsmRendererLogging,
135 render_texture_formats: Option<RenderTextureFormats>,
136 brdf_lut_options: BrdfLutOptions,
137 clear_color: Color,
138 skybox_colors: CubemapBitmapColors,
141 ibl_filtered_env_colors: CubemapBitmapColors,
142 ibl_irradiance_colors: CubemapBitmapColors,
143 anti_aliasing: AntiAliasing,
144 post_processing: PostProcessing,
145}
146
147pub enum AwsmRendererGpuBuilderKind {
149 WebGpuBuilder(AwsmRendererWebGpuBuilder),
151 WebGpuBuilt(AwsmRendererWebGpu),
153}
154
155impl From<AwsmRendererWebGpuBuilder> for AwsmRendererGpuBuilderKind {
156 fn from(builder: AwsmRendererWebGpuBuilder) -> Self {
157 AwsmRendererGpuBuilderKind::WebGpuBuilder(builder)
158 }
159}
160
161impl From<AwsmRendererWebGpu> for AwsmRendererGpuBuilderKind {
162 fn from(gpu: AwsmRendererWebGpu) -> Self {
163 AwsmRendererGpuBuilderKind::WebGpuBuilt(gpu)
164 }
165}
166
167impl AwsmRendererBuilder {
168 pub fn new(gpu: impl Into<AwsmRendererGpuBuilderKind>) -> Self {
170 Self {
171 gpu: gpu.into(),
172 logging: AwsmRendererLogging::default(),
173 render_texture_formats: None,
174 clear_color: Color::BLACK,
175 brdf_lut_options: BrdfLutOptions::default(),
176 skybox_colors: CubemapBitmapColors {
177 z_positive: Color::BLACK,
178 z_negative: Color::BLACK,
179 x_positive: Color::BLACK,
180 x_negative: Color::BLACK,
181 y_positive: Color::BLACK,
182 y_negative: Color::BLACK,
183 },
184 ibl_filtered_env_colors: CubemapBitmapColors {
193 z_positive: Color::WHITE,
194 z_negative: Color::WHITE,
195 x_positive: Color::WHITE,
196 x_negative: Color::WHITE,
197 y_positive: Color::WHITE,
198 y_negative: Color::WHITE,
199 },
200 ibl_irradiance_colors: CubemapBitmapColors {
201 z_positive: Color::WHITE,
202 z_negative: Color::WHITE,
203 x_positive: Color::WHITE,
204 x_negative: Color::WHITE,
205 y_positive: Color::WHITE,
206 y_negative: Color::WHITE,
207 },
208 anti_aliasing: AntiAliasing::default(),
209 post_processing: PostProcessing::default(),
210 }
211 }
212
213 pub fn with_brdf_lut_options(mut self, options: BrdfLutOptions) -> Self {
215 self.brdf_lut_options = options;
216 self
217 }
218
219 pub fn with_ibl_filtered_env_colors(mut self, colors: CubemapBitmapColors) -> Self {
221 self.ibl_filtered_env_colors = colors;
222 self
223 }
224
225 pub fn with_anti_aliasing(mut self, anti_aliasing: AntiAliasing) -> Self {
227 self.anti_aliasing = anti_aliasing;
228 self
229 }
230
231 pub fn with_ibl_irradiance_colors(mut self, colors: CubemapBitmapColors) -> Self {
233 self.ibl_irradiance_colors = colors;
234 self
235 }
236
237 pub fn with_skybox_colors(mut self, colors: CubemapBitmapColors) -> Self {
239 self.skybox_colors = colors;
240 self
241 }
242
243 pub fn with_logging(mut self, logging: AwsmRendererLogging) -> Self {
245 self.logging = logging;
246 self
247 }
248
249 pub fn with_render_texture_formats(mut self, formats: RenderTextureFormats) -> Self {
251 self.render_texture_formats = Some(formats);
252 self
253 }
254
255 pub fn with_clear_color(mut self, color: Color) -> Self {
257 self.clear_color = color;
258 self
259 }
260
261 pub async fn build(self) -> std::result::Result<AwsmRenderer, crate::error::AwsmError> {
263 let Self {
264 gpu,
265 logging,
266 render_texture_formats,
267 brdf_lut_options,
268 clear_color,
269 skybox_colors,
270 ibl_filtered_env_colors,
271 ibl_irradiance_colors,
272 anti_aliasing,
273 post_processing,
274 } = self;
275
276 let mut gpu = match gpu {
277 AwsmRendererGpuBuilderKind::WebGpuBuilder(builder) => builder.build().await?,
278 AwsmRendererGpuBuilderKind::WebGpuBuilt(gpu) => gpu,
279 };
280
281 let mut render_texture_formats = match render_texture_formats {
282 Some(formats) => formats,
283 None => RenderTextureFormats::new(&gpu.device).await,
284 };
285
286 let mut pipeline_layouts = PipelineLayouts::new();
293 let mut bind_group_layouts = BindGroupLayouts::new();
294 let mut pipelines = Pipelines::new();
295 let mut shaders = Shaders::new();
296
297 let mut textures = Textures::new(&gpu)?;
298 let camera = camera::CameraBuffer::new(&gpu)?;
299 let lights = Lights::new(
300 &gpu,
301 Ibl::new(
302 IblTexture::new_colors(&gpu, &mut textures, ibl_filtered_env_colors).await?,
303 IblTexture::new_colors(&gpu, &mut textures, ibl_irradiance_colors).await?,
304 ),
305 BrdfLut::new(&gpu, brdf_lut_options).await?,
306 )?;
307 let meshes = Meshes::new(&gpu)?;
308 let transforms = Transforms::new(&gpu)?;
309 let instances = Instances::new(&gpu)?;
310 let materials = Materials::new(&gpu)?;
311 let environment =
312 Environment::new(Skybox::new_colors(&gpu, &mut textures, skybox_colors).await?);
313
314 let mut render_pass_init = RenderPassInitContext {
317 gpu: &mut gpu,
318 bind_group_layouts: &mut bind_group_layouts,
319 pipeline_layouts: &mut pipeline_layouts,
320 pipelines: &mut pipelines,
321 shaders: &mut shaders,
322 render_texture_formats: &mut render_texture_formats,
323 textures: &mut textures,
324 };
325 let render_passes = RenderPasses::new(&mut render_pass_init).await?;
326
327 let bind_groups = BindGroups::new();
328 let render_textures = RenderTextures::new(&gpu, render_texture_formats).await?;
329
330 let picker = Picker::new(
331 &gpu,
332 &mut bind_group_layouts,
333 &mut pipeline_layouts,
334 &mut shaders,
335 &mut pipelines,
336 )
337 .await?;
338
339 #[cfg(feature = "gltf")]
340 let gltf = gltf::cache::GltfCache::default();
341 #[cfg(feature = "animation")]
342 let animations = animation::Animations::default();
343
344 let mut _self = AwsmRenderer {
345 gpu,
346 meshes,
347 camera,
348 transforms,
349 instances,
350 shaders,
351 bind_group_layouts,
352 bind_groups,
353 materials,
354 pipeline_layouts,
355 pipelines,
356 lights,
357 textures,
358 environment,
359 render_passes,
360 _clear_color: clear_color.clone(),
361 _clear_color_perceptual_to_linear: clear_color.perceptual_to_linear(),
362 logging,
363 render_textures,
364 anti_aliasing,
365 post_processing,
366 picker,
367 #[cfg(feature = "gltf")]
368 gltf,
369 #[cfg(feature = "animation")]
370 animations,
371 };
372
373 _self.set_anti_aliasing(_self.anti_aliasing.clone()).await?;
375 _self
376 .set_post_processing(_self.post_processing.clone())
377 .await?;
378
379 Ok(_self)
380 }
381}