use askama::Template;
use crate::{
render_passes::material_prep::shader::cache_key::ShaderCacheKeyMaterialPrep,
shaders::{AwsmShaderError, Result},
};
pub struct ShaderTemplateMaterialPrep {
pub bind_groups: ShaderTemplateMaterialPrepBindGroups,
pub compute: ShaderTemplateMaterialPrepCompute,
}
#[derive(Template, Debug)]
#[template(path = "material_prep_wgsl/bind_groups.wgsl", whitespace = "minimize")]
pub struct ShaderTemplateMaterialPrepBindGroups {
pub multisampled_geometry: bool,
pub shadows: bool,
pub needs_shadow_sampling: bool,
pub sscs_available: bool,
pub shadow_group_index: u32,
pub froxel_slice_count: u32,
}
#[derive(Template, Debug)]
#[template(path = "material_prep_wgsl/compute.wgsl", whitespace = "minimize")]
pub struct ShaderTemplateMaterialPrepCompute {
pub multisampled_geometry: bool,
pub max_prep_uv_sets: u32,
pub max_prep_color_sets: u32,
pub shadows: bool,
pub max_shadow_casters: u32,
pub shadow_visibility_layers: u32,
pub msaa_sample_count: u32,
pub edge_shadow_tex_width: u32,
}
impl TryFrom<&ShaderCacheKeyMaterialPrep> for ShaderTemplateMaterialPrep {
type Error = AwsmShaderError;
fn try_from(key: &ShaderCacheKeyMaterialPrep) -> Result<Self> {
let multisampled_geometry = key.msaa_sample_count.is_some();
let froxel_slice_count = crate::render_passes::light_culling::DEFAULT_SLICE_COUNT;
Ok(ShaderTemplateMaterialPrep {
bind_groups: ShaderTemplateMaterialPrepBindGroups {
multisampled_geometry,
shadows: true,
needs_shadow_sampling: true,
sscs_available: true,
shadow_group_index: 2,
froxel_slice_count,
},
compute: ShaderTemplateMaterialPrepCompute {
multisampled_geometry,
max_prep_uv_sets: crate::render_passes::material_prep::MAX_PREP_UV_SETS,
max_prep_color_sets: crate::render_passes::material_prep::MAX_PREP_COLOR_SETS,
shadows: true,
max_shadow_casters: key.max_shadow_casters,
shadow_visibility_layers: key.max_shadow_casters.div_ceil(4).max(1),
msaa_sample_count: key.msaa_sample_count.unwrap_or(0),
edge_shadow_tex_width:
crate::render_passes::material_prep::buffers::EDGE_SHADOW_TEX_WIDTH,
},
})
}
}
impl ShaderTemplateMaterialPrep {
pub fn into_source(self) -> Result<String> {
let bind_groups_source = self.bind_groups.render()?;
let compute_source = self.compute.render()?;
Ok(format!("{}\n{}", bind_groups_source, compute_source))
}
pub fn debug_label(&self) -> Option<&str> {
Some("Material Prep")
}
}