use askama::Template;
use crate::{
dynamic_materials::ShadingBase,
shaders::{AwsmShaderError, Result},
shadows::shader::masked_cache_key::ShaderCacheKeyShadowMasked,
};
#[derive(Debug)]
pub struct ShaderTemplateShadowMasked {
pub bind_groups: ShaderTemplateShadowMaskedBindGroups,
pub vertex: ShaderTemplateShadowMaskedVertex,
pub fragment: ShaderTemplateShadowMaskedFragment,
}
#[derive(Template, Debug)]
#[template(path = "shadow_masked_wgsl/bind_groups.wgsl", whitespace = "minimize")]
pub struct ShaderTemplateShadowMaskedBindGroups {
texture_pool_arrays_len: u32,
texture_pool_samplers_len: u32,
instancing_transforms: bool,
}
impl ShaderTemplateShadowMaskedBindGroups {
pub fn new(
texture_pool_arrays_len: u32,
texture_pool_samplers_len: u32,
instancing_transforms: bool,
) -> Self {
Self {
texture_pool_arrays_len,
texture_pool_samplers_len,
instancing_transforms,
}
}
}
#[derive(Template, Debug)]
#[template(path = "shadow_masked_wgsl/vertex.wgsl", whitespace = "minimize")]
pub struct ShaderTemplateShadowMaskedVertex {
instancing_transforms: bool,
max_morph_unroll: u32,
max_skin_unroll: u32,
has_custom_vertex: bool,
dynamic_wgsl_vertex: String,
dynamic_vertex_struct_decl: String,
dynamic_vertex_loader_decl: String,
}
impl ShaderTemplateShadowMaskedVertex {
pub fn new(
instancing_transforms: bool,
has_custom_vertex: bool,
dynamic_wgsl_vertex: String,
dynamic_vertex_struct_decl: String,
dynamic_vertex_loader_decl: String,
) -> Self {
Self {
instancing_transforms,
max_morph_unroll: 2,
max_skin_unroll: 2,
has_custom_vertex,
dynamic_wgsl_vertex,
dynamic_vertex_struct_decl,
dynamic_vertex_loader_decl,
}
}
}
#[derive(Template, Debug)]
#[template(path = "shadow_masked_wgsl/fragment.wgsl", whitespace = "minimize")]
pub struct ShaderTemplateShadowMaskedFragment {
texture_pool_arrays_len: u32,
texture_pool_samplers_len: u32,
base: ShadingBase,
dynamic_struct_decl: String,
dynamic_loader_decl: String,
dynamic_texture_helpers: String,
dynamic_alpha_wgsl: String,
flipbook_cell_wgsl: String,
}
impl ShaderTemplateShadowMaskedFragment {
pub fn new(
texture_pool_arrays_len: u32,
texture_pool_samplers_len: u32,
base: ShadingBase,
dynamic_struct_decl: String,
dynamic_loader_decl: String,
dynamic_texture_helpers: String,
dynamic_alpha_wgsl: String,
flipbook_cell_wgsl: String,
) -> Self {
Self {
texture_pool_arrays_len,
texture_pool_samplers_len,
base,
dynamic_struct_decl,
dynamic_loader_decl,
dynamic_texture_helpers,
dynamic_alpha_wgsl,
flipbook_cell_wgsl,
}
}
}
impl TryFrom<&ShaderCacheKeyShadowMasked> for ShaderTemplateShadowMasked {
type Error = AwsmShaderError;
fn try_from(value: &ShaderCacheKeyShadowMasked) -> Result<Self> {
let (struct_decl, loader_decl, texture_helpers, alpha_wgsl) = match &value.dynamic_alpha {
Some(info) => (
info.struct_decl.clone(),
info.loader_decl.clone(),
info.texture_helpers.clone(),
info.alpha_wgsl.clone(),
),
None => (String::new(), String::new(), String::new(), String::new()),
};
Ok(Self {
bind_groups: ShaderTemplateShadowMaskedBindGroups::new(
value.texture_pool_arrays_len,
value.texture_pool_samplers_len,
value.instancing_transforms,
),
vertex: ShaderTemplateShadowMaskedVertex::new(
value.instancing_transforms,
false,
String::new(),
String::new(),
String::new(),
),
fragment: ShaderTemplateShadowMaskedFragment::new(
value.texture_pool_arrays_len,
value.texture_pool_samplers_len,
value.base,
struct_decl,
loader_decl,
texture_helpers,
alpha_wgsl,
if value.base == ShadingBase::Flipbook {
awsm_renderer_materials::flipbook::FLIPBOOK_CELL_WGSL.to_string()
} else {
String::new()
},
),
})
}
}
impl ShaderTemplateShadowMasked {
pub fn into_source(self) -> Result<String> {
let bind_groups_source = self.bind_groups.render()?;
let vertex_source = self.vertex.render()?;
let fragment_source = self.fragment.render()?;
Ok(format!(
"{}\n{}\n{}",
bind_groups_source, vertex_source, fragment_source
))
}
pub fn debug_label(&self) -> Option<&str> {
Some("Shadow Masked")
}
}