From 42b5f1997cdd5e99645e24dca6cb89cc7b081a09 Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Sat, 1 Nov 2025 18:23:08 -0700 Subject: Add support for alpha mode --- src/asset/model.c | 75 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 48 insertions(+), 27 deletions(-) (limited to 'src/asset/model.c') diff --git a/src/asset/model.c b/src/asset/model.c index 2ee3cd1..a97d20e 100644 --- a/src/asset/model.c +++ b/src/asset/model.c @@ -138,6 +138,7 @@ #define DEFINE_HAS_NORMAL_MAP "HAS_NORMAL_MAP" #define DEFINE_HAS_OCCLUSION_MAP "HAS_OCCLUSION_MAP" #define DEFINE_HAS_EMISSIVE_MAP "HAS_EMISSIVE_MAP" +#define DEFINE_HAS_TRANSPARENCY "HAS_TRANSPARENCY" #define DEFINE_HAS_JOINTS "HAS_JOINTS" #define DEFINE_MAX_JOINTS "MAX_JOINTS" @@ -166,6 +167,8 @@ typedef struct MeshPermutation { bool has_normal_map : 1; bool has_occlusion_map : 1; bool has_emissive_map : 1; + // Material. + bool has_transparency : 1; }; int32_t all; }; @@ -192,6 +195,7 @@ static size_t make_defines( check(has_normal_map, DEFINE_HAS_NORMAL_MAP); check(has_occlusion_map, DEFINE_HAS_OCCLUSION_MAP); check(has_emissive_map, DEFINE_HAS_EMISSIVE_MAP); + check(has_transparency, DEFINE_HAS_TRANSPARENCY); if (perm.has_joints) { defines[next].name = sstring_make(DEFINE_MAX_JOINTS); @@ -208,12 +212,12 @@ static ShaderProgram* make_shader_permutation( LOGD( "Compiling Cook-Torrance shader permutation: texcoords: %d, normals: " "%d, tangents: %d, joints: %d, weights: %d, albedo map: %d, " - "metallic-roughness map: " - "%d, normal " - "map: %d, AO map: %d, emissive map: %d", + "metallic-roughness map: %d, normal map: %d, AO map: %d, emissive map: " + "%d, has transparency: %d", perm.has_texcoords, perm.has_normals, perm.has_tangents, perm.has_joints, perm.has_weights, perm.has_albedo_map, perm.has_metallic_roughness_map, - perm.has_normal_map, perm.has_occlusion_map, perm.has_emissive_map); + perm.has_normal_map, perm.has_occlusion_map, perm.has_emissive_map, + perm.has_transparency); ShaderCompilerDefine defines[GFX_MAX_SHADER_COMPILER_DEFINES]; const size_t num_defines = make_defines(perm, defines); @@ -742,6 +746,19 @@ static bool load_texture_and_uniform( return true; } +static AlphaMode to_gfx_alpha_mode(cgltf_alpha_mode mode) { + switch (mode) { + case cgltf_alpha_mode_opaque: + return Opaque; + case cgltf_alpha_mode_mask: + return Mask; + case cgltf_alpha_mode_blend: + return Blend; + } + FAIL("unhandled alpha mode"); + return Opaque; +} + /// Load all materials from the glTF scene. /// /// Return an array of Materials such that the index of each descriptor matches @@ -770,27 +787,27 @@ static bool load_materials( assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); desc.uniforms[next_uniform++] = (ShaderUniform){ - .name = sstring_make(UNIFORM_BASE_COLOR_FACTOR), - .type = UniformVec4, - .value.vec4 = vec4_from_array(pbr->base_color_factor)}; + .name = sstring_make(UNIFORM_BASE_COLOR_FACTOR), + .type = UniformVec4, + .value.uniform_vec4 = vec4_from_array(pbr->base_color_factor)}; assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); desc.uniforms[next_uniform++] = - (ShaderUniform){.name = sstring_make(UNIFORM_METALLIC_FACTOR), - .type = UniformFloat, - .value.scalar = pbr->metallic_factor}; + (ShaderUniform){.name = sstring_make(UNIFORM_METALLIC_FACTOR), + .type = UniformFloat, + .value.uniform_float = pbr->metallic_factor}; assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); desc.uniforms[next_uniform++] = (ShaderUniform){.name = sstring_make(UNIFORM_ROUGHNESS_FACTOR), .type = UniformFloat, - .value.scalar = pbr->roughness_factor}; + .value.uniform_float = pbr->roughness_factor}; assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); - desc.uniforms[next_uniform++] = - (ShaderUniform){.name = sstring_make(UNIFORM_EMISSIVE_FACTOR), - .type = UniformVec3, - .value.vec3 = vec3_from_array(mat->emissive_factor)}; + desc.uniforms[next_uniform++] = (ShaderUniform){ + .name = sstring_make(UNIFORM_EMISSIVE_FACTOR), + .type = UniformVec3, + .value.uniform_vec3 = vec3_from_array(mat->emissive_factor)}; if (pbr->base_color_texture.texture) { if (!load_texture_and_uniform( @@ -837,6 +854,9 @@ static bool load_materials( assert(next_uniform < GFX_MAX_UNIFORMS_PER_MATERIAL); desc.num_uniforms = next_uniform; + desc.alpha_mode = to_gfx_alpha_mode(mat->alpha_mode); + desc.alpha_cutoff = mat->alpha_cutoff; + materials[i] = gfx_make_material(&desc); if (!materials[i]) { return false; @@ -852,27 +872,27 @@ static Material* make_default_material() { assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); desc.uniforms[desc.num_uniforms++] = - (ShaderUniform){.name = sstring_make(UNIFORM_BASE_COLOR_FACTOR), - .type = UniformVec4, - .value.vec4 = vec4_make(1, 1, 1, 1)}; + (ShaderUniform){.name = sstring_make(UNIFORM_BASE_COLOR_FACTOR), + .type = UniformVec4, + .value.uniform_vec4 = vec4_make(1, 1, 1, 1)}; assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); desc.uniforms[desc.num_uniforms++] = - (ShaderUniform){.name = sstring_make(UNIFORM_METALLIC_FACTOR), - .type = UniformFloat, - .value.scalar = 0}; + (ShaderUniform){.name = sstring_make(UNIFORM_METALLIC_FACTOR), + .type = UniformFloat, + .value.uniform_float = 0}; assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); desc.uniforms[desc.num_uniforms++] = - (ShaderUniform){.name = sstring_make(UNIFORM_ROUGHNESS_FACTOR), - .type = UniformFloat, - .value.scalar = 1}; + (ShaderUniform){.name = sstring_make(UNIFORM_ROUGHNESS_FACTOR), + .type = UniformFloat, + .value.uniform_float = 1}; assert(desc.num_uniforms < GFX_MAX_UNIFORMS_PER_MATERIAL); desc.uniforms[desc.num_uniforms++] = - (ShaderUniform){.name = sstring_make(UNIFORM_EMISSIVE_FACTOR), - .type = UniformVec3, - .value.vec3 = vec3_make(0, 0, 0)}; + (ShaderUniform){.name = sstring_make(UNIFORM_EMISSIVE_FACTOR), + .type = UniformVec3, + .value.uniform_vec3 = vec3_make(0, 0, 0)}; return gfx_make_material(&desc); } @@ -950,6 +970,7 @@ static bool load_meshes( perm.has_normal_map = mat->normal_texture.texture != 0; perm.has_occlusion_map = mat->occlusion_texture.texture != 0; perm.has_emissive_map = mat->emissive_texture.texture != 0; + perm.has_transparency = mat->alpha_mode != cgltf_alpha_mode_opaque; if (mat->has_pbr_metallic_roughness) { const cgltf_pbr_metallic_roughness* pbr = -- cgit v1.2.3