Files
coven/modules/ufbx/test/test_material.h

1636 lines
87 KiB
C

#undef UFBXT_TEST_GROUP
#define UFBXT_TEST_GROUP "material"
#if UFBXT_IMPL
void ufbxt_check_texture_content(ufbx_scene *scene, ufbx_texture *texture, const char *filename)
{
char buf[512];
ufbxt_assert(texture->content.size > 0);
ufbxt_assert(texture->content.data);
snprintf(buf, sizeof(buf), "%stextures/%s", data_root, filename);
void *ref = malloc(texture->content.size);
ufbxt_assert(ref);
FILE *f = fopen(buf, "rb");
ufbxt_assert(f);
size_t num_read = fread(ref, 1, texture->content.size, f);
fclose(f);
ufbxt_assert(num_read == texture->content.size);
ufbxt_assert(!memcmp(ref, texture->content.data, texture->content.size));
free(ref);
}
void ufbxt_check_material_texture_ex(ufbx_scene *scene, ufbx_texture *texture, const char *directory, const char *filename, bool require_content)
{
char buf[512];
snprintf(buf, sizeof(buf), "%s%s", directory, filename);
ufbxt_assert(!strcmp(texture->relative_filename.data, buf));
if (require_content && (scene->metadata.version >= 7000 || !scene->metadata.ascii)) {
ufbxt_assert(texture->content.size);
}
if (texture->content.size) {
ufbxt_check_texture_content(scene, texture, filename);
}
}
void ufbxt_check_material_texture(ufbx_scene *scene, ufbx_texture *texture, const char *filename, bool require_content)
{
ufbxt_check_material_texture_ex(scene, texture, "textures\\", filename, require_content);
}
#endif
UFBXT_FILE_TEST(maya_textured_cube)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "phong1");
ufbxt_assert(material);
ufbxt_assert(material->textures.count == 6);
ufbxt_check_material_texture(scene, material->fbx.diffuse_color.texture, "checkerboard_diffuse.png", true);
ufbxt_check_material_texture(scene, material->fbx.specular_color.texture, "checkerboard_specular.png", true);
ufbxt_check_material_texture(scene, material->fbx.reflection_color.texture, "checkerboard_reflection.png", true);
ufbxt_check_material_texture(scene, material->fbx.transparency_color.texture, "checkerboard_transparency.png", true);
ufbxt_check_material_texture(scene, material->fbx.emission_color.texture, "checkerboard_emissive.png", true);
ufbxt_check_material_texture(scene, material->fbx.ambient_color.texture, "checkerboard_ambient.png", true);
}
#endif
UFBXT_FILE_TEST(synthetic_texture_split)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "phong1");
ufbxt_assert(material);
ufbxt_assert(material->textures.count == 6);
ufbxt_check_material_texture(scene, material->fbx.diffuse_color.texture, "checkerboard_diffuse.png", true);
ufbxt_check_material_texture(scene, material->fbx.specular_color.texture, "checkerboard_specular.png", true);
ufbxt_check_material_texture(scene, material->fbx.reflection_color.texture, "checkerboard_reflection.png", true);
ufbxt_check_material_texture(scene, material->fbx.transparency_color.texture, "checkerboard_transparency.png", true);
ufbxt_check_material_texture(scene, material->fbx.emission_color.texture, "checkerboard_emissive.png", true);
ufbxt_check_material_texture(scene, material->fbx.ambient_color.texture, "checkerboard_ambient.png", true);
}
#endif
UFBXT_TEST(ignore_embedded)
#if UFBXT_IMPL
{
char path[512];
ufbxt_file_iterator iter = { "maya_textured_cube" };
while (ufbxt_next_file(&iter, path, sizeof(path))) {
ufbx_load_opts opts = { 0 };
opts.ignore_embedded = true;
ufbx_scene *scene = ufbx_load_file(path, &opts, NULL);
ufbxt_assert(scene);
ufbxt_check_scene(scene);
for (size_t i = 0; i < scene->videos.count; i++) {
ufbxt_assert(scene->videos.data[i]->content.data == NULL);
ufbxt_assert(scene->videos.data[i]->content.size == 0);
}
for (size_t i = 0; i < scene->textures.count; i++) {
ufbxt_assert(scene->textures.data[i]->content.data == NULL);
ufbxt_assert(scene->textures.data[i]->content.size == 0);
}
ufbx_free_scene(scene);
}
}
#endif
UFBXT_FILE_TEST(maya_shared_textures)
#if UFBXT_IMPL
{
ufbx_material *material;
material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "Shared");
ufbxt_assert(material);
ufbxt_assert(material->textures.count == 6);
ufbxt_assert(material->shader_type == UFBX_SHADER_FBX_LAMBERT);
ufbxt_check_material_texture(scene, material->fbx.diffuse_color.texture, "checkerboard_ambient.png", true); // sic: test has wrong texture
ufbxt_check_material_texture(scene, material->fbx.diffuse_factor.texture, "checkerboard_diffuse.png", true);
ufbxt_check_material_texture(scene, material->fbx.emission_color.texture, "checkerboard_emissive.png", true);
ufbxt_check_material_texture(scene, material->fbx.ambient_color.texture, "checkerboard_ambient.png", true);
ufbxt_check_material_texture(scene, material->fbx.transparency_color.texture, "checkerboard_transparency.png", true);
ufbxt_check_material_texture(scene, material->fbx.bump.texture, "checkerboard_bump.png", true);
material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "Special");
ufbxt_assert(material->shader_type == UFBX_SHADER_FBX_PHONG);
ufbxt_assert(material);
ufbxt_assert(material->textures.count == 1);
ufbxt_assert(!strcmp(material->fbx.diffuse_color.texture->relative_filename.data, "textures\\tiny_clouds.png"));
}
#endif
UFBXT_FILE_TEST(maya_arnold_textures)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "aiStandardSurface1");
ufbxt_assert(material);
ufbxt_assert(material->textures.count == 5);
ufbxt_assert(material->shader_type == UFBX_SHADER_ARNOLD_STANDARD_SURFACE);
ufbxt_check_material_texture(scene, material->pbr.base_color.texture, "checkerboard_diffuse.png", true);
ufbxt_check_material_texture(scene, material->pbr.specular_color.texture, "checkerboard_specular.png", true);
ufbxt_check_material_texture(scene, material->pbr.roughness.texture, "checkerboard_roughness.png", true);
ufbxt_check_material_texture(scene, material->pbr.metalness.texture, "checkerboard_metallic.png", true);
ufbxt_check_material_texture(scene, material->pbr.diffuse_roughness.texture, "checkerboard_roughness.png", true);
}
#endif
UFBXT_FILE_TEST(max_physical_material_properties)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "PhysicalMaterial");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_3DS_MAX_PHYSICAL_MATERIAL);
ufbxt_assert( 1 == (int)round(100.0f * material->pbr.base_factor.value_real));
ufbxt_assert( 2 == (int)round(100.0f * material->pbr.base_color.value_vec4.x));
ufbxt_assert( 3 == (int)round(100.0f * material->pbr.base_color.value_vec4.y));
ufbxt_assert( 4 == (int)round(100.0f * material->pbr.base_color.value_vec4.z));
ufbxt_assert( 5 == (int)round(100.0f * material->pbr.base_color.value_vec4.w));
ufbxt_assert( 6 == (int)round(100.0f * material->pbr.roughness.value_real));
ufbxt_assert( 7 == (int)round(100.0f * material->pbr.metalness.value_real));
ufbxt_assert(80 == (int)round(100.0f * material->pbr.specular_ior.value_real)); // 3ds Max doesn't allow lower than 0.1 IOR
ufbxt_assert( 9 == (int)round(100.0f * material->pbr.transmission_factor.value_real));
ufbxt_assert(10 == (int)round(100.0f * material->pbr.transmission_color.value_vec4.x));
ufbxt_assert(11 == (int)round(100.0f * material->pbr.transmission_color.value_vec4.y));
ufbxt_assert(12 == (int)round(100.0f * material->pbr.transmission_color.value_vec4.z));
ufbxt_assert(13 == (int)round(100.0f * material->pbr.transmission_color.value_vec4.w));
ufbxt_assert(14 == (int)round(100.0f * material->pbr.transmission_roughness.value_real));
ufbxt_assert( 6 == (int)round(100.0f * material->pbr.transmission_depth.value_real)); // ??? Unit conversion probably
ufbxt_assert(16 == (int)round(100.0f * material->pbr.subsurface_factor.value_real));
ufbxt_assert(17 == (int)round(100.0f * material->pbr.subsurface_tint_color.value_vec4.x));
ufbxt_assert(18 == (int)round(100.0f * material->pbr.subsurface_tint_color.value_vec4.y));
ufbxt_assert(19 == (int)round(100.0f * material->pbr.subsurface_tint_color.value_vec4.z));
ufbxt_assert(20 == (int)round(100.0f * material->pbr.subsurface_tint_color.value_vec4.w));
ufbxt_assert(21 == (int)round(100.0f * material->pbr.subsurface_color.value_vec4.x));
ufbxt_assert(22 == (int)round(100.0f * material->pbr.subsurface_color.value_vec4.y));
ufbxt_assert(23 == (int)round(100.0f * material->pbr.subsurface_color.value_vec4.z));
ufbxt_assert(24 == (int)round(100.0f * material->pbr.subsurface_color.value_vec4.w));
ufbxt_assert(10 == (int)round(100.0f * material->pbr.subsurface_radius.value_real)); // ??? Unit conversion probably
ufbxt_assert(26 == (int)round(100.0f * material->pbr.subsurface_scale.value_real));
ufbxt_assert(27 == (int)round(100.0f * material->pbr.emission_factor.value_real));
ufbxt_assert(28 == (int)round(100.0f * material->pbr.emission_color.value_vec4.x));
ufbxt_assert(29 == (int)round(100.0f * material->pbr.emission_color.value_vec4.y));
ufbxt_assert(30 == (int)round(100.0f * material->pbr.emission_color.value_vec4.z));
ufbxt_assert(31 == (int)round(100.0f * material->pbr.emission_color.value_vec4.w));
ufbxt_assert(32 == (int)round(100.0f * material->pbr.specular_anisotropy.value_real));
ufbxt_assert(33 == (int)round(100.0f * material->pbr.specular_rotation.value_real));
ufbxt_assert(34 == (int)round(100.0f * material->pbr.normal_map.value_real));
ufbxt_assert(35 == (int)round(100.0f * material->pbr.coat_normal.value_real));
ufbxt_assert(36 == (int)round(100.0f * material->pbr.displacement_map.value_real));
ufbxt_assert(37 == (int)round(100.0f * material->pbr.diffuse_roughness.value_real));
ufbxt_assert(38 == (int)round(100.0f * material->pbr.coat_factor.value_real));
ufbxt_assert(39 == (int)round(100.0f * material->pbr.coat_color.value_vec4.x));
ufbxt_assert(40 == (int)round(100.0f * material->pbr.coat_color.value_vec4.y));
ufbxt_assert(41 == (int)round(100.0f * material->pbr.coat_color.value_vec4.z));
ufbxt_assert(42 == (int)round(100.0f * material->pbr.coat_color.value_vec4.w));
ufbxt_assert(43 == (int)round(100.0f * material->pbr.coat_roughness.value_real));
ufbxt_assert(44 == (int)round(100.0f * material->pbr.coat_ior.value_real));
ufbxt_assert(45 == (int)round(100.0f * material->pbr.coat_affect_base_color.value_real));
ufbxt_assert(46 == (int)round(100.0f * material->pbr.coat_affect_base_roughness.value_real));
ufbxt_assert(material->pbr.base_factor.texture_enabled);
ufbxt_assert(material->pbr.base_color.texture_enabled);
ufbxt_assert(material->pbr.specular_factor.texture_enabled);
ufbxt_assert(material->pbr.specular_color.texture_enabled);
ufbxt_assert(material->pbr.roughness.texture_enabled);
ufbxt_assert(material->pbr.metalness.texture_enabled);
ufbxt_assert(material->pbr.diffuse_roughness.texture_enabled);
ufbxt_assert(material->pbr.specular_anisotropy.texture_enabled);
ufbxt_assert(material->pbr.specular_rotation.texture_enabled);
ufbxt_assert(material->pbr.transmission_factor.texture_enabled);
ufbxt_assert(material->pbr.transmission_color.texture_enabled);
ufbxt_assert(material->pbr.transmission_roughness.texture_enabled);
ufbxt_assert(material->pbr.specular_ior.texture_enabled);
ufbxt_assert(material->pbr.subsurface_factor.texture_enabled);
ufbxt_assert(material->pbr.subsurface_tint_color.texture_enabled);
ufbxt_assert(material->pbr.subsurface_scale.texture_enabled);
ufbxt_assert(material->pbr.emission_factor.texture_enabled);
ufbxt_assert(material->pbr.emission_color.texture_enabled);
ufbxt_assert(material->pbr.coat_factor.texture_enabled);
ufbxt_assert(material->pbr.coat_color.texture_enabled);
ufbxt_assert(material->pbr.coat_roughness.texture_enabled);
ufbxt_assert(material->pbr.normal_map.texture_enabled);
ufbxt_assert(material->pbr.coat_normal.texture_enabled);
ufbxt_assert(material->pbr.displacement_map.texture_enabled);
ufbxt_assert(material->pbr.opacity.texture_enabled);
ufbxt_assert(material->pbr.base_factor.value_components == 1);
ufbxt_assert(material->pbr.base_color.value_components == 4);
ufbxt_assert(material->pbr.specular_factor.value_components == 1);
ufbxt_assert(material->pbr.specular_color.value_components == 4);
ufbxt_assert(material->pbr.roughness.value_components == 1);
ufbxt_assert(material->pbr.metalness.value_components == 1);
ufbxt_assert(material->pbr.diffuse_roughness.value_components == 1);
ufbxt_assert(material->pbr.specular_anisotropy.value_components == 1);
ufbxt_assert(material->pbr.specular_rotation.value_components == 1);
ufbxt_assert(material->pbr.transmission_factor.value_components == 1);
ufbxt_assert(material->pbr.transmission_color.value_components == 4);
ufbxt_assert(material->pbr.transmission_roughness.value_components == 1);
ufbxt_assert(material->pbr.transmission_extra_roughness.value_components == 0);
ufbxt_assert(material->pbr.specular_ior.value_components == 1);
ufbxt_assert(material->pbr.subsurface_factor.value_components == 1);
ufbxt_assert(material->pbr.subsurface_tint_color.value_components == 4);
ufbxt_assert(material->pbr.subsurface_color.value_components == 4);
ufbxt_assert(material->pbr.subsurface_radius.value_components == 1);
ufbxt_assert(material->pbr.subsurface_scale.value_components == 1);
ufbxt_assert(material->pbr.emission_factor.value_components == 1);
ufbxt_assert(material->pbr.emission_color.value_components == 4);
ufbxt_assert(material->pbr.coat_factor.value_components == 1);
ufbxt_assert(material->pbr.coat_color.value_components == 4);
ufbxt_assert(material->pbr.coat_roughness.value_components == 1);
ufbxt_assert(material->pbr.normal_map.value_components == 1);
ufbxt_assert(material->pbr.coat_normal.value_components == 1);
ufbxt_assert(material->pbr.displacement_map.value_components == 1);
ufbxt_assert(material->pbr.opacity.value_components == 0);
}
#endif
UFBXT_FILE_TEST(max_physical_material_inverted)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "InvertedMaterial");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_3DS_MAX_PHYSICAL_MATERIAL);
ufbxt_assert_close_real(err, material->pbr.roughness.value_real, 0.9f);
ufbxt_assert_close_real(err, material->pbr.transmission_roughness.value_real, 0.8f);
ufbxt_assert_close_real(err, material->pbr.coat_roughness.value_real, 0.7f);
}
#endif
UFBXT_FILE_TEST(max_physical_material_textures)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "PhysicalMaterial");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_3DS_MAX_PHYSICAL_MATERIAL);
ufbxt_check_material_texture(scene, material->pbr.base_factor.texture, "checkerboard_weight.png", true);
ufbxt_check_material_texture(scene, material->pbr.base_color.texture, "checkerboard_diffuse.png", true);
ufbxt_check_material_texture(scene, material->pbr.specular_factor.texture, "checkerboard_reflection.png", true);
ufbxt_check_material_texture(scene, material->pbr.specular_color.texture, "checkerboard_reflection.png", true);
ufbxt_check_material_texture(scene, material->pbr.roughness.texture, "checkerboard_roughness.png", true);
ufbxt_check_material_texture(scene, material->pbr.metalness.texture, "checkerboard_metallic.png", true);
ufbxt_check_material_texture(scene, material->pbr.diffuse_roughness.texture, "checkerboard_roughness.png", true);
ufbxt_check_material_texture(scene, material->pbr.specular_anisotropy.texture, "checkerboard_weight.png", true);
ufbxt_check_material_texture(scene, material->pbr.specular_rotation.texture, "checkerboard_weight.png", true);
ufbxt_check_material_texture(scene, material->pbr.transmission_factor.texture, "checkerboard_transparency.png", true);
ufbxt_check_material_texture(scene, material->pbr.transmission_color.texture, "checkerboard_transparency.png", true);
ufbxt_check_material_texture(scene, material->pbr.transmission_roughness.texture, "checkerboard_roughness.png", true);
ufbxt_check_material_texture(scene, material->pbr.specular_ior.texture, "checkerboard_weight.png", true);
ufbxt_check_material_texture(scene, material->pbr.subsurface_factor.texture, "checkerboard_weight.png", true);
ufbxt_check_material_texture(scene, material->pbr.subsurface_tint_color.texture, "checkerboard_weight.png", true);
ufbxt_check_material_texture(scene, material->pbr.subsurface_scale.texture, "checkerboard_weight.png", true);
ufbxt_check_material_texture(scene, material->pbr.emission_factor.texture, "checkerboard_emissive.png", true);
ufbxt_check_material_texture(scene, material->pbr.emission_color.texture, "checkerboard_emissive.png", true);
ufbxt_check_material_texture(scene, material->pbr.coat_factor.texture, "checkerboard_specular.png", true);
ufbxt_check_material_texture(scene, material->pbr.coat_color.texture, "checkerboard_specular.png", true);
ufbxt_check_material_texture(scene, material->pbr.coat_roughness.texture, "checkerboard_specular.png", true);
ufbxt_check_material_texture(scene, material->pbr.normal_map.texture, "checkerboard_bump.png", true);
ufbxt_check_material_texture(scene, material->pbr.coat_normal.texture, "checkerboard_bump.png", true);
ufbxt_check_material_texture(scene, material->pbr.displacement_map.texture, "checkerboard_displacement.png", true);
ufbxt_check_material_texture(scene, material->pbr.opacity.texture, "checkerboard_transparency.png", true);
}
#endif
UFBXT_FILE_TEST(max_pbr_metal_rough_material)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "01 - Default");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_3DS_MAX_PBR_METAL_ROUGH);
ufbxt_assert( 1 == (int)round(100.0f * material->pbr.base_color.value_vec4.x));
ufbxt_assert( 2 == (int)round(100.0f * material->pbr.base_color.value_vec4.y));
ufbxt_assert( 3 == (int)round(100.0f * material->pbr.base_color.value_vec4.z));
ufbxt_assert( 4 == (int)round(100.0f * material->pbr.base_color.value_vec4.w));
ufbxt_assert( 5 == (int)round(100.0f * material->pbr.metalness.value_real));
ufbxt_assert( 6 == (int)round(100.0f * material->pbr.roughness.value_real));
// ufbxt_assert( 7 == (int)round(100.0f * material->pbr.normal_map.value_real)); (not in file?!)
ufbxt_assert( 8 == (int)round(100.0f * material->pbr.emission_color.value_vec4.x));
ufbxt_assert( 9 == (int)round(100.0f * material->pbr.emission_color.value_vec4.y));
ufbxt_assert(10 == (int)round(100.0f * material->pbr.emission_color.value_vec4.z));
ufbxt_assert(11 == (int)round(100.0f * material->pbr.emission_color.value_vec4.w));
ufbxt_assert(12 == (int)round(100.0f * material->pbr.displacement_map.value_real));
ufbxt_assert_close_real(err, material->pbr.base_factor.value_real, 1.0f);
ufbxt_assert_close_real(err, material->pbr.emission_factor.value_real, 1.0f);
ufbxt_check_material_texture(scene, material->pbr.base_color.texture, "checkerboard_diffuse.png", false);
ufbxt_check_material_texture(scene, material->pbr.metalness.texture, "checkerboard_metallic.png", false);
ufbxt_check_material_texture(scene, material->pbr.roughness.texture, "checkerboard_roughness.png", false);
ufbxt_check_material_texture(scene, material->pbr.ambient_occlusion.texture, "checkerboard_ambient.png", false);
ufbxt_check_material_texture(scene, material->pbr.normal_map.texture, "checkerboard_normal.png", false);
ufbxt_check_material_texture(scene, material->pbr.emission_color.texture, "checkerboard_emissive.png", false);
ufbxt_check_material_texture(scene, material->pbr.displacement_map.texture, "checkerboard_displacement.png", false);
ufbxt_check_material_texture(scene, material->pbr.opacity.texture, "checkerboard_transparency.png", false);
ufbxt_assert(material->features.metalness.enabled);
ufbxt_assert(!material->features.specular.enabled);
}
#endif
UFBXT_FILE_TEST(max_pbr_metal_gloss_material)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "01 - Default");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_3DS_MAX_PBR_METAL_ROUGH);
ufbxt_assert( 1 == (int)round(100.0f * material->pbr.base_color.value_vec4.x));
ufbxt_assert( 2 == (int)round(100.0f * material->pbr.base_color.value_vec4.y));
ufbxt_assert( 3 == (int)round(100.0f * material->pbr.base_color.value_vec4.z));
ufbxt_assert( 4 == (int)round(100.0f * material->pbr.base_color.value_vec4.w));
ufbxt_assert( 5 == (int)round(100.0f * material->pbr.metalness.value_real));
ufbxt_assert( 6 == (int)round(100.0f * material->pbr.glossiness.value_real));
// ufbxt_assert( 7 == (int)round(100.0f * material->pbr.normal_map.value_real)); (not in file?!)
ufbxt_assert( 8 == (int)round(100.0f * material->pbr.emission_color.value_vec4.x));
ufbxt_assert( 9 == (int)round(100.0f * material->pbr.emission_color.value_vec4.y));
ufbxt_assert(10 == (int)round(100.0f * material->pbr.emission_color.value_vec4.z));
ufbxt_assert(11 == (int)round(100.0f * material->pbr.emission_color.value_vec4.w));
ufbxt_assert(12 == (int)round(100.0f * material->pbr.displacement_map.value_real));
ufbxt_assert(100 - 6 == (int)round(100.0f * material->pbr.roughness.value_real));
ufbxt_assert_close_real(err, material->pbr.base_factor.value_real, 1.0f);
ufbxt_assert_close_real(err, material->pbr.emission_factor.value_real, 1.0f);
ufbxt_check_material_texture(scene, material->pbr.base_color.texture, "checkerboard_diffuse.png", false);
ufbxt_check_material_texture(scene, material->pbr.metalness.texture, "checkerboard_metallic.png", false);
ufbxt_check_material_texture(scene, material->pbr.glossiness.texture, "checkerboard_roughness.png", false);
ufbxt_check_material_texture(scene, material->pbr.ambient_occlusion.texture, "checkerboard_ambient.png", false);
ufbxt_check_material_texture(scene, material->pbr.normal_map.texture, "checkerboard_normal.png", false);
ufbxt_check_material_texture(scene, material->pbr.emission_color.texture, "checkerboard_emissive.png", false);
ufbxt_check_material_texture(scene, material->pbr.displacement_map.texture, "checkerboard_displacement.png", false);
ufbxt_check_material_texture(scene, material->pbr.opacity.texture, "checkerboard_transparency.png", false);
ufbxt_assert(material->pbr.roughness.texture == NULL);
ufbxt_assert(material->features.metalness.enabled);
ufbxt_assert(!material->features.specular.enabled);
}
#endif
UFBXT_FILE_TEST(max_pbr_spec_rough_material)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "02 - Default");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_3DS_MAX_PBR_SPEC_GLOSS);
ufbxt_assert( 1 == (int)round(100.0f * material->pbr.base_color.value_vec4.x));
ufbxt_assert( 2 == (int)round(100.0f * material->pbr.base_color.value_vec4.y));
ufbxt_assert( 3 == (int)round(100.0f * material->pbr.base_color.value_vec4.z));
ufbxt_assert( 4 == (int)round(100.0f * material->pbr.base_color.value_vec4.w));
ufbxt_assert( 5 == (int)round(100.0f * material->pbr.specular_color.value_vec4.x));
ufbxt_assert( 6 == (int)round(100.0f * material->pbr.specular_color.value_vec4.y));
ufbxt_assert( 7 == (int)round(100.0f * material->pbr.specular_color.value_vec4.z));
ufbxt_assert( 8 == (int)round(100.0f * material->pbr.specular_color.value_vec4.w));
ufbxt_assert( 9 == (int)round(100.0f * material->pbr.roughness.value_real));
// ufbxt_assert(10 == (int)round(100.0f * material->pbr.normal_map.value_real)); (not in file?!)
ufbxt_assert(12 == (int)round(100.0f * material->pbr.emission_color.value_vec4.x));
ufbxt_assert(13 == (int)round(100.0f * material->pbr.emission_color.value_vec4.y));
ufbxt_assert(14 == (int)round(100.0f * material->pbr.emission_color.value_vec4.z));
ufbxt_assert(15 == (int)round(100.0f * material->pbr.emission_color.value_vec4.w));
ufbxt_assert(16 == (int)round(100.0f * material->pbr.displacement_map.value_real));
ufbxt_assert_close_real(err, material->pbr.base_factor.value_real, 1.0f);
ufbxt_assert_close_real(err, material->pbr.emission_factor.value_real, 1.0f);
ufbxt_check_material_texture(scene, material->pbr.base_color.texture, "checkerboard_diffuse.png", false);
ufbxt_check_material_texture(scene, material->pbr.specular_color.texture, "checkerboard_specular.png", false);
ufbxt_check_material_texture(scene, material->pbr.roughness.texture, "checkerboard_weight.png", false);
ufbxt_check_material_texture(scene, material->pbr.ambient_occlusion.texture, "checkerboard_ambient.png", false);
ufbxt_check_material_texture(scene, material->pbr.normal_map.texture, "checkerboard_normal.png", false);
ufbxt_check_material_texture(scene, material->pbr.emission_color.texture, "checkerboard_emissive.png", false);
ufbxt_check_material_texture(scene, material->pbr.displacement_map.texture, "checkerboard_displacement.png", false);
ufbxt_check_material_texture(scene, material->pbr.opacity.texture, "checkerboard_transparency.png", false);
ufbxt_assert(!material->features.metalness.enabled);
ufbxt_assert(material->features.specular.enabled);
}
#endif
UFBXT_FILE_TEST(max_pbr_spec_gloss_material)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "02 - Default");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_3DS_MAX_PBR_SPEC_GLOSS);
ufbxt_assert( 1 == (int)round(100.0f * material->pbr.base_color.value_vec4.x));
ufbxt_assert( 2 == (int)round(100.0f * material->pbr.base_color.value_vec4.y));
ufbxt_assert( 3 == (int)round(100.0f * material->pbr.base_color.value_vec4.z));
ufbxt_assert( 4 == (int)round(100.0f * material->pbr.base_color.value_vec4.w));
ufbxt_assert( 5 == (int)round(100.0f * material->pbr.specular_color.value_vec4.x));
ufbxt_assert( 6 == (int)round(100.0f * material->pbr.specular_color.value_vec4.y));
ufbxt_assert( 7 == (int)round(100.0f * material->pbr.specular_color.value_vec4.z));
ufbxt_assert( 8 == (int)round(100.0f * material->pbr.specular_color.value_vec4.w));
ufbxt_assert( 9 == (int)round(100.0f * material->pbr.glossiness.value_real));
// ufbxt_assert(10 == (int)round(100.0f * material->pbr.normal_map.value_real)); (not in file?!)
ufbxt_assert(12 == (int)round(100.0f * material->pbr.emission_color.value_vec4.x));
ufbxt_assert(13 == (int)round(100.0f * material->pbr.emission_color.value_vec4.y));
ufbxt_assert(14 == (int)round(100.0f * material->pbr.emission_color.value_vec4.z));
ufbxt_assert(15 == (int)round(100.0f * material->pbr.emission_color.value_vec4.w));
ufbxt_assert(16 == (int)round(100.0f * material->pbr.displacement_map.value_real));
ufbxt_assert(100 - 9 == (int)round(100.0f * material->pbr.roughness.value_real));
ufbxt_assert_close_real(err, material->pbr.base_factor.value_real, 1.0f);
ufbxt_assert_close_real(err, material->pbr.emission_factor.value_real, 1.0f);
ufbxt_check_material_texture(scene, material->pbr.base_color.texture, "checkerboard_diffuse.png", false);
ufbxt_check_material_texture(scene, material->pbr.specular_color.texture, "checkerboard_specular.png", false);
ufbxt_check_material_texture(scene, material->pbr.glossiness.texture, "checkerboard_weight.png", false);
ufbxt_check_material_texture(scene, material->pbr.ambient_occlusion.texture, "checkerboard_ambient.png", false);
ufbxt_check_material_texture(scene, material->pbr.normal_map.texture, "checkerboard_normal.png", false);
ufbxt_check_material_texture(scene, material->pbr.emission_color.texture, "checkerboard_emissive.png", false);
ufbxt_check_material_texture(scene, material->pbr.displacement_map.texture, "checkerboard_displacement.png", false);
ufbxt_check_material_texture(scene, material->pbr.opacity.texture, "checkerboard_transparency.png", false);
ufbxt_assert(material->pbr.roughness.texture == NULL);
ufbxt_assert(!material->features.metalness.enabled);
ufbxt_assert(material->features.specular.enabled);
}
#endif
UFBXT_FILE_TEST(max_gltf_material)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "01 - Default");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_GLTF_MATERIAL);
ufbxt_assert( 1 == (int)round(100.0f * material->pbr.base_color.value_vec4.x));
ufbxt_assert( 2 == (int)round(100.0f * material->pbr.base_color.value_vec4.y));
ufbxt_assert( 3 == (int)round(100.0f * material->pbr.base_color.value_vec4.z));
ufbxt_assert( 4 == (int)round(100.0f * material->pbr.base_color.value_vec4.w));
ufbxt_assert( 5 == (int)round(100.0f * material->pbr.metalness.value_real));
ufbxt_assert( 6 == (int)round(100.0f * material->pbr.roughness.value_real));
ufbxt_assert( 7 == (int)round(100.0f * material->pbr.normal_map.value_real));
ufbxt_assert( 8 == (int)round(100.0f * material->pbr.ambient_occlusion.value_real));
ufbxt_assert( 9 == (int)round(100.0f * material->pbr.emission_color.value_vec4.x));
ufbxt_assert(10 == (int)round(100.0f * material->pbr.emission_color.value_vec4.y));
ufbxt_assert(11 == (int)round(100.0f * material->pbr.emission_color.value_vec4.z));
ufbxt_assert(12 == (int)round(100.0f * material->pbr.emission_color.value_vec4.w));
ufbxt_assert(13 == (int)round(100.0f * material->pbr.coat_factor.value_real));
ufbxt_assert(14 == (int)round(100.0f * material->pbr.coat_roughness.value_real));
ufbxt_assert(15 == (int)round(100.0f * material->pbr.coat_normal.value_real));
ufbxt_assert(16 == (int)round(100.0f * material->pbr.sheen_color.value_vec4.x));
ufbxt_assert(17 == (int)round(100.0f * material->pbr.sheen_color.value_vec4.y));
ufbxt_assert(18 == (int)round(100.0f * material->pbr.sheen_color.value_vec4.z));
ufbxt_assert(19 == (int)round(100.0f * material->pbr.sheen_color.value_vec4.w));
ufbxt_assert(20 == (int)round(100.0f * material->pbr.sheen_roughness.value_real));
ufbxt_assert(21 == (int)round(100.0f * material->pbr.specular_factor.value_real));
ufbxt_assert(22 == (int)round(100.0f * material->pbr.specular_color.value_vec4.x));
ufbxt_assert(23 == (int)round(100.0f * material->pbr.specular_color.value_vec4.y));
ufbxt_assert(24 == (int)round(100.0f * material->pbr.specular_color.value_vec4.z));
ufbxt_assert(25 == (int)round(100.0f * material->pbr.specular_color.value_vec4.w));
ufbxt_assert(26 == (int)round(100.0f * material->pbr.transmission_factor.value_real));
// TODO? Volume
ufbxt_assert(133 == (int)round(100.0f * material->pbr.specular_ior.value_real));
ufbxt_assert_close_real(err, material->pbr.base_factor.value_real, 1.0f);
ufbxt_assert_close_real(err, material->pbr.emission_factor.value_real, 1.0f);
ufbxt_check_material_texture(scene, material->pbr.base_color.texture, "checkerboard_diffuse.png", true);
ufbxt_check_material_texture(scene, material->pbr.opacity.texture, "checkerboard_transparency.png", true);
ufbxt_check_material_texture(scene, material->pbr.metalness.texture, "checkerboard_metallic.png", true);
ufbxt_check_material_texture(scene, material->pbr.roughness.texture, "checkerboard_roughness.png", true);
ufbxt_check_material_texture(scene, material->pbr.normal_map.texture, "checkerboard_normal.png", true);
ufbxt_check_material_texture(scene, material->pbr.ambient_occlusion.texture, "checkerboard_weight.png", true);
ufbxt_check_material_texture(scene, material->pbr.emission_color.texture, "checkerboard_emissive.png", true);
ufbxt_check_material_texture(scene, material->pbr.coat_factor.texture, "checkerboard_weight.png", true);
ufbxt_check_material_texture(scene, material->pbr.coat_roughness.texture, "checkerboard_roughness.png", true);
ufbxt_check_material_texture(scene, material->pbr.coat_normal.texture, "checkerboard_normal.png", true);
ufbxt_check_material_texture(scene, material->pbr.sheen_color.texture, "checkerboard_ambient.png", true);
ufbxt_check_material_texture(scene, material->pbr.sheen_roughness.texture, "checkerboard_roughness.png", true);
ufbxt_check_material_texture(scene, material->pbr.specular_factor.texture, "checkerboard_weight.png", true);
ufbxt_check_material_texture(scene, material->pbr.specular_color.texture, "checkerboard_specular.png", true);
ufbxt_check_material_texture(scene, material->pbr.transmission_factor.texture, "checkerboard_transparency.png", true);
ufbxt_assert(material->features.metalness.enabled);
ufbxt_assert(!material->features.metalness.is_explicit);
ufbxt_assert(material->features.double_sided.enabled);
ufbxt_assert(material->features.double_sided.is_explicit);
ufbxt_assert(material->features.coat.enabled);
ufbxt_assert(material->features.coat.is_explicit);
ufbxt_assert(material->features.sheen.enabled);
ufbxt_assert(material->features.sheen.is_explicit);
ufbxt_assert(material->features.specular.enabled);
ufbxt_assert(material->features.specular.is_explicit);
ufbxt_assert(material->features.transmission.enabled);
ufbxt_assert(material->features.transmission.is_explicit);
ufbxt_assert(material->features.ior.enabled);
ufbxt_assert(material->features.ior.is_explicit);
}
#endif
UFBXT_FILE_TEST(maya_shaderfx_pbs_material)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "StingrayPBS1");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_SHADERFX_GRAPH);
ufbxt_assert( 1 == (int)round(100.0f * material->pbr.base_color.value_vec3.x));
ufbxt_assert( 2 == (int)round(100.0f * material->pbr.base_color.value_vec3.y));
ufbxt_assert( 3 == (int)round(100.0f * material->pbr.base_color.value_vec3.z));
ufbxt_assert( 4 == (int)round(100.0f * material->pbr.metalness.value_vec3.x));
ufbxt_assert( 5 == (int)round(100.0f * material->pbr.roughness.value_vec3.x));
ufbxt_assert( 6 == (int)round(100.0f * material->pbr.emission_color.value_vec3.x));
ufbxt_assert( 7 == (int)round(100.0f * material->pbr.emission_color.value_vec3.y));
ufbxt_assert( 8 == (int)round(100.0f * material->pbr.emission_color.value_vec3.z));
ufbxt_assert( 9 == (int)round(100.0f * material->pbr.emission_factor.value_real));
ufbxt_assert_close_real(err, material->pbr.base_factor.value_real, 1.0f);
ufbxt_check_material_texture(scene, material->pbr.base_color.texture, "checkerboard_diffuse.png", true);
ufbxt_check_material_texture(scene, material->pbr.normal_map.texture, "checkerboard_normal.png", true);
ufbxt_check_material_texture(scene, material->pbr.metalness.texture, "checkerboard_metallic.png", true);
ufbxt_check_material_texture(scene, material->pbr.roughness.texture, "checkerboard_roughness.png", true);
ufbxt_check_material_texture(scene, material->pbr.emission_color.texture, "checkerboard_emissive.png", true);
ufbxt_check_material_texture(scene, material->pbr.ambient_occlusion.texture, "checkerboard_weight.png", true);
ufbxt_assert(material->pbr.base_color.texture_enabled == true);
ufbxt_assert(material->pbr.normal_map.texture_enabled == false);
ufbxt_assert(material->pbr.metalness.texture_enabled == true);
ufbxt_assert(material->pbr.roughness.texture_enabled == false);
ufbxt_assert(material->pbr.emission_color.texture_enabled == true);
ufbxt_assert(material->pbr.ambient_occlusion.texture_enabled == false);
ufbx_shader *shader = material->shader;
ufbxt_assert(shader);
if (scene->metadata.version >= 7000) {
ufbx_blob blob = ufbx_find_blob(&shader->props, "ShaderGraph", ufbx_empty_blob);
ufbxt_assert(blob.size == 32918);
uint32_t hash_ref = ufbxt_fnv1a(blob.data, blob.size);
ufbxt_assert(hash_ref == 0x7be121c5u);
}
}
#endif
UFBXT_FILE_TEST(blender_279_internal_textures)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "Material.001");
ufbxt_assert(material);
ufbxt_assert(material->textures.count == 5);
ufbxt_assert(material->shader_type == UFBX_SHADER_FBX_PHONG);
ufbxt_assert(!strcmp(material->fbx.diffuse_color.texture->relative_filename.data, "textures\\checkerboard_diffuse.png"));
ufbxt_assert(!strcmp(material->fbx.specular_color.texture->relative_filename.data, "textures\\checkerboard_specular.png"));
ufbxt_assert(!strcmp(material->fbx.specular_factor.texture->relative_filename.data, "textures\\checkerboard_weight.png"));
ufbxt_assert(!strcmp(material->fbx.ambient_factor.texture->relative_filename.data, "textures\\checkerboard_ambient.png"));
ufbxt_assert(!strcmp(material->fbx.emission_factor.texture->relative_filename.data, "textures\\checkerboard_emissive.png"));
}
#endif
UFBXT_FILE_TEST(blender_293_textures)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "Material.001");
ufbxt_assert(material);
ufbxt_assert(material->textures.count == 5);
ufbxt_assert(material->shader_type == UFBX_SHADER_BLENDER_PHONG);
ufbxt_assert(!strcmp(material->pbr.base_color.texture->relative_filename.data, "textures\\checkerboard_diffuse.png"));
ufbxt_assert(!strcmp(material->pbr.roughness.texture->relative_filename.data, "textures\\checkerboard_roughness.png"));
ufbxt_assert(!strcmp(material->pbr.metalness.texture->relative_filename.data, "textures\\checkerboard_metallic.png"));
ufbxt_assert(!strcmp(material->pbr.emission_color.texture->relative_filename.data, "textures\\checkerboard_emissive.png"));
ufbxt_assert(!strcmp(material->pbr.opacity.texture->relative_filename.data, "textures\\checkerboard_weight.png"));
}
#endif
UFBXT_FILE_TEST(blender_293_embedded_textures)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "Material.001");
ufbxt_assert(material);
ufbxt_assert(material->textures.count == 5);
ufbxt_assert(material->shader_type == UFBX_SHADER_BLENDER_PHONG);
ufbxt_check_texture_content(scene, material->pbr.base_color.texture, "checkerboard_diffuse.png");
ufbxt_check_texture_content(scene, material->pbr.roughness.texture, "checkerboard_roughness.png");
ufbxt_check_texture_content(scene, material->pbr.metalness.texture, "checkerboard_metallic.png");
ufbxt_check_texture_content(scene, material->pbr.emission_color.texture, "checkerboard_emissive.png");
ufbxt_check_texture_content(scene, material->pbr.opacity.texture, "checkerboard_weight.png");
}
#endif
UFBXT_FILE_TEST(blender_293_material_mapping)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "Material.001");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_BLENDER_PHONG);
ufbxt_assert_close_real(err, material->fbx.specular_exponent.value_vec3.x, 76.913f);
ufbxt_assert_close_real(err, material->fbx.transparency_factor.value_vec3.x, 0.544f);
ufbxt_assert_close_real(err, material->pbr.opacity.value_vec3.x, 0.456f);
ufbxt_assert_close_real(err, material->pbr.roughness.value_vec3.x, 0.123f);
}
#endif
UFBXT_FILE_TEST(maya_different_shaders)
#if UFBXT_IMPL
{
ufbx_material *lambert1 = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "lambert1");
ufbx_material *phong1 = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "phong1");
ufbx_material *arnold = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "aiStandardSurface1");
ufbxt_assert(lambert1 && phong1 && arnold);
ufbx_vec3 r = { 1.0f, 0.0f, 0.0f };
ufbx_vec3 g = { 0.0f, 1.0f, 0.0f };
ufbx_vec3 b = { 0.0f, 0.0f, 1.0f };
ufbxt_assert(lambert1->shader_type == UFBX_SHADER_FBX_LAMBERT);
ufbxt_assert(!strcmp(lambert1->shading_model_name.data, "lambert"));
ufbxt_assert_close_vec3(err, lambert1->fbx.diffuse_color.value_vec3, g);
ufbxt_assert_close_vec3(err, lambert1->pbr.base_color.value_vec3, g);
ufbxt_assert_close_real(err, lambert1->pbr.specular_factor.value_vec3.x, 0.0f);
ufbxt_assert(phong1->shader_type == UFBX_SHADER_FBX_PHONG);
ufbxt_assert(!strcmp(phong1->shading_model_name.data, "phong"));
ufbxt_assert_close_vec3(err, phong1->fbx.diffuse_color.value_vec3, b);
ufbxt_assert_close_vec3(err, phong1->pbr.base_color.value_vec3, b);
ufbxt_assert_close_real(err, phong1->pbr.specular_factor.value_vec3.x, 1.0f);
ufbxt_assert(arnold->shader_type == UFBX_SHADER_ARNOLD_STANDARD_SURFACE);
ufbxt_assert(!strcmp(arnold->shading_model_name.data, "unknown"));
ufbxt_assert_close_vec3(err, arnold->pbr.base_color.value_vec3, r);
}
#endif
UFBXT_TEST(blender_phong_quirks)
#if UFBXT_IMPL
{
for (int quirks = 0; quirks <= 1; quirks++) {
ufbx_load_opts opts = { 0 };
opts.disable_quirks = (quirks == 0);
char buf[512];
snprintf(buf, sizeof(buf), "%s%s", data_root, "blender_293_textures_7400_binary.fbx");
ufbx_scene *scene = ufbx_load_file(buf, &opts, NULL);
ufbxt_assert(scene);
// Exporter should be detected even with quirks off
ufbxt_assert(scene->metadata.exporter == UFBX_EXPORTER_BLENDER_BINARY);
ufbxt_assert(scene->metadata.exporter_version == ufbx_pack_version(4, 22, 0));
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "Material.001");
ufbxt_assert(material);
if (quirks) {
ufbxt_assert(material->shader_type == UFBX_SHADER_BLENDER_PHONG);
} else {
ufbxt_assert(material->shader_type == UFBX_SHADER_FBX_PHONG);
}
ufbx_free_scene(scene);
}
}
#endif
UFBXT_FILE_TEST(maya_phong_properties)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "phong1");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_FBX_PHONG);
ufbxt_assert( 1 == (int)round(100.0f * material->fbx.diffuse_color.value_vec3.x));
ufbxt_assert( 2 == (int)round(100.0f * material->fbx.diffuse_color.value_vec3.y));
ufbxt_assert( 3 == (int)round(100.0f * material->fbx.diffuse_color.value_vec3.z));
ufbxt_assert( 4 == (int)round(100.0f * material->fbx.transparency_color.value_vec3.x));
ufbxt_assert( 5 == (int)round(100.0f * material->fbx.transparency_color.value_vec3.y));
ufbxt_assert( 6 == (int)round(100.0f * material->fbx.transparency_color.value_vec3.z));
ufbxt_assert( 7 == (int)round(100.0f * material->fbx.ambient_color.value_vec3.x));
ufbxt_assert( 8 == (int)round(100.0f * material->fbx.ambient_color.value_vec3.y));
ufbxt_assert( 9 == (int)round(100.0f * material->fbx.ambient_color.value_vec3.z));
ufbxt_assert(10 == (int)round(100.0f * material->fbx.emission_color.value_vec3.x));
ufbxt_assert(11 == (int)round(100.0f * material->fbx.emission_color.value_vec3.y));
ufbxt_assert(12 == (int)round(100.0f * material->fbx.emission_color.value_vec3.z));
ufbxt_assert(13 == (int)round(100.0f * material->fbx.diffuse_factor.value_vec3.x));
ufbxt_assert(17 == (int)round( 1.0f * material->fbx.specular_exponent.value_vec3.x));
ufbxt_assert(18 == (int)round(100.0f * material->fbx.specular_color.value_vec3.x));
ufbxt_assert(19 == (int)round(100.0f * material->fbx.specular_color.value_vec3.y));
ufbxt_assert(20 == (int)round(100.0f * material->fbx.specular_color.value_vec3.z));
ufbxt_assert(21 == (int)round(100.0f * material->fbx.reflection_factor.value_vec3.x));
ufbxt_assert(22 == (int)round(100.0f * material->fbx.reflection_color.value_vec3.x));
ufbxt_assert(23 == (int)round(100.0f * material->fbx.reflection_color.value_vec3.y));
ufbxt_assert(24 == (int)round(100.0f * material->fbx.reflection_color.value_vec3.z));
ufbxt_assert( 1 == (int)round(100.0f * material->pbr.base_color.value_vec3.x));
ufbxt_assert( 2 == (int)round(100.0f * material->pbr.base_color.value_vec3.y));
ufbxt_assert( 3 == (int)round(100.0f * material->pbr.base_color.value_vec3.z));
ufbxt_assert(13 == (int)round(100.0f * material->pbr.base_factor.value_vec3.x));
ufbxt_assert_close_real(err, material->pbr.metalness.value_real, 0.0f);
ufbxt_assert_close_real(err, material->pbr.roughness.value_real, 0.587689f);
}
#endif
UFBXT_FILE_TEST(maya_arnold_properties)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "aiStandardSurface1");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_ARNOLD_STANDARD_SURFACE);
ufbxt_assert( 1 == (int)round(100.0f * material->pbr.base_factor.value_vec3.x));
ufbxt_assert( 2 == (int)round(100.0f * material->pbr.base_color.value_vec3.x));
ufbxt_assert( 3 == (int)round(100.0f * material->pbr.base_color.value_vec3.y));
ufbxt_assert( 4 == (int)round(100.0f * material->pbr.base_color.value_vec3.z));
ufbxt_assert( 5 == (int)round(100.0f * material->pbr.diffuse_roughness.value_vec3.x));
ufbxt_assert( 6 == (int)round(100.0f * material->pbr.metalness.value_vec3.x));
ufbxt_assert( 7 == (int)round(100.0f * material->pbr.specular_factor.value_vec3.x));
ufbxt_assert( 8 == (int)round(100.0f * material->pbr.specular_color.value_vec3.x));
ufbxt_assert( 9 == (int)round(100.0f * material->pbr.specular_color.value_vec3.y));
ufbxt_assert(10 == (int)round(100.0f * material->pbr.specular_color.value_vec3.z));
ufbxt_assert(11 == (int)round(100.0f * material->pbr.roughness.value_vec3.x));
ufbxt_assert(12 == (int)round(100.0f * material->pbr.specular_ior.value_vec3.x));
ufbxt_assert(13 == (int)round(100.0f * material->pbr.specular_anisotropy.value_vec3.x));
ufbxt_assert(14 == (int)round(100.0f * material->pbr.specular_rotation.value_vec3.x));
ufbxt_assert(15 == (int)round(100.0f * material->pbr.transmission_factor.value_vec3.x));
ufbxt_assert(16 == (int)round(100.0f * material->pbr.transmission_color.value_vec3.x));
ufbxt_assert(17 == (int)round(100.0f * material->pbr.transmission_color.value_vec3.y));
ufbxt_assert(18 == (int)round(100.0f * material->pbr.transmission_color.value_vec3.z));
ufbxt_assert(19 == (int)round(100.0f * material->pbr.transmission_depth.value_vec3.x));
ufbxt_assert(20 == (int)round(100.0f * material->pbr.transmission_scatter.value_vec3.x));
ufbxt_assert(21 == (int)round(100.0f * material->pbr.transmission_scatter.value_vec3.y));
ufbxt_assert(22 == (int)round(100.0f * material->pbr.transmission_scatter.value_vec3.z));
ufbxt_assert(23 == (int)round(100.0f * material->pbr.transmission_scatter_anisotropy.value_vec3.x));
ufbxt_assert(24 == (int)round(100.0f * material->pbr.transmission_dispersion.value_vec3.x));
ufbxt_assert(25 == (int)round(100.0f * material->pbr.transmission_extra_roughness.value_vec3.x));
ufbxt_assert(26 == (int)round(100.0f * material->pbr.subsurface_factor.value_vec3.x));
ufbxt_assert(27 == (int)round(100.0f * material->pbr.subsurface_color.value_vec3.x));
ufbxt_assert(28 == (int)round(100.0f * material->pbr.subsurface_color.value_vec3.y));
ufbxt_assert(29 == (int)round(100.0f * material->pbr.subsurface_color.value_vec3.z));
ufbxt_assert(30 == (int)round(100.0f * material->pbr.subsurface_radius.value_vec3.x));
ufbxt_assert(31 == (int)round(100.0f * material->pbr.subsurface_radius.value_vec3.y));
ufbxt_assert(32 == (int)round(100.0f * material->pbr.subsurface_radius.value_vec3.z));
ufbxt_assert(33 == (int)round(100.0f * material->pbr.subsurface_scale.value_vec3.x));
ufbxt_assert(34 == (int)round(100.0f * material->pbr.subsurface_anisotropy.value_vec3.x));
ufbxt_assert(35 == (int)round(100.0f * material->pbr.coat_factor.value_vec3.x));
ufbxt_assert(36 == (int)round(100.0f * material->pbr.coat_color.value_vec3.x));
ufbxt_assert(37 == (int)round(100.0f * material->pbr.coat_color.value_vec3.y));
ufbxt_assert(38 == (int)round(100.0f * material->pbr.coat_color.value_vec3.z));
ufbxt_assert(39 == (int)round(100.0f * material->pbr.coat_roughness.value_vec3.x));
ufbxt_assert(40 == (int)round(100.0f * material->pbr.coat_ior.value_vec3.x));
ufbxt_assert(41 == (int)round(100.0f * material->pbr.coat_anisotropy.value_vec3.x));
ufbxt_assert(42 == (int)round(100.0f * material->pbr.coat_rotation.value_vec3.x));
ufbxt_assert(43 == (int)round(100.0f * material->pbr.coat_normal.value_vec3.x));
ufbxt_assert(44 == (int)round(100.0f * material->pbr.coat_normal.value_vec3.y));
ufbxt_assert(45 == (int)round(100.0f * material->pbr.coat_normal.value_vec3.z));
ufbxt_assert(46 == (int)round(100.0f * material->pbr.sheen_factor.value_vec3.x));
ufbxt_assert(47 == (int)round(100.0f * material->pbr.sheen_color.value_vec3.x));
ufbxt_assert(48 == (int)round(100.0f * material->pbr.sheen_color.value_vec3.y));
ufbxt_assert(49 == (int)round(100.0f * material->pbr.sheen_color.value_vec3.z));
ufbxt_assert(50 == (int)round(100.0f * material->pbr.sheen_roughness.value_vec3.x));
ufbxt_assert(51 == (int)round(100.0f * material->pbr.emission_factor.value_vec3.x));
ufbxt_assert(52 == (int)round(100.0f * material->pbr.emission_color.value_vec3.x));
ufbxt_assert(53 == (int)round(100.0f * material->pbr.emission_color.value_vec3.y));
ufbxt_assert(54 == (int)round(100.0f * material->pbr.emission_color.value_vec3.z));
ufbxt_assert(55 == (int)round(100.0f * material->pbr.thin_film_thickness.value_vec3.x));
ufbxt_assert(56 == (int)round(100.0f * material->pbr.thin_film_ior.value_vec3.x));
ufbxt_assert(57 == (int)round(100.0f * material->pbr.opacity.value_vec3.x));
ufbxt_assert(58 == (int)round(100.0f * material->pbr.opacity.value_vec3.y));
ufbxt_assert(59 == (int)round(100.0f * material->pbr.opacity.value_vec3.z));
ufbxt_assert(60 == (int)round(100.0f * material->pbr.tangent_map.value_vec3.x));
ufbxt_assert(61 == (int)round(100.0f * material->pbr.tangent_map.value_vec3.y));
ufbxt_assert(62 == (int)round(100.0f * material->pbr.tangent_map.value_vec3.z));
ufbxt_assert(63 == (int)round(100.0f * material->pbr.indirect_diffuse.value_vec3.x));
ufbxt_assert(64 == (int)round(100.0f * material->pbr.indirect_specular.value_vec3.x));
ufbxt_assert(65 == (int)round(100.0f * material->pbr.matte_color.value_vec3.x));
ufbxt_assert(66 == (int)round(100.0f * material->pbr.matte_color.value_vec3.y));
ufbxt_assert(67 == (int)round(100.0f * material->pbr.matte_color.value_vec3.z));
ufbxt_assert(68 == (int)round(100.0f * material->pbr.matte_factor.value_vec3.x));
ufbxt_assert(69 == material->pbr.transmission_priority.value_int);
// Computed
ufbxt_assert_close_real(err, material->pbr.transmission_roughness.value_real, 0.36f); // 11+25
ufbxt_assert(material->pbr.base_factor.value_components == 1);
ufbxt_assert(material->pbr.base_color.value_components == 3);
ufbxt_assert(material->pbr.specular_factor.value_components == 1);
ufbxt_assert(material->pbr.specular_color.value_components == 3);
ufbxt_assert(material->pbr.roughness.value_components == 1);
ufbxt_assert(material->pbr.metalness.value_components == 1);
ufbxt_assert(material->pbr.diffuse_roughness.value_components == 1);
ufbxt_assert(material->pbr.specular_anisotropy.value_components == 1);
ufbxt_assert(material->pbr.specular_rotation.value_components == 1);
ufbxt_assert(material->pbr.transmission_factor.value_components == 1);
ufbxt_assert(material->pbr.transmission_color.value_components == 3);
ufbxt_assert(material->pbr.transmission_roughness.value_components == 0);
ufbxt_assert(material->pbr.specular_ior.value_components == 1);
ufbxt_assert(material->pbr.subsurface_factor.value_components == 1);
ufbxt_assert(material->pbr.subsurface_tint_color.value_components == 0);
ufbxt_assert(material->pbr.subsurface_color.value_components == 3);
ufbxt_assert(material->pbr.subsurface_radius.value_components == 3);
ufbxt_assert(material->pbr.subsurface_scale.value_components == 1);
ufbxt_assert(material->pbr.emission_factor.value_components == 1);
ufbxt_assert(material->pbr.emission_color.value_components == 3);
ufbxt_assert(material->pbr.coat_factor.value_components == 1);
ufbxt_assert(material->pbr.coat_color.value_components == 3);
ufbxt_assert(material->pbr.coat_roughness.value_components == 1);
ufbxt_assert(material->pbr.normal_map.value_components == 3);
ufbxt_assert(material->pbr.coat_normal.value_components == 3);
ufbxt_assert(material->pbr.displacement_map.value_components == 0);
ufbxt_assert(material->pbr.opacity.value_components == 3);
ufbxt_assert(material->pbr.subsurface_type.value_int == 1);
ufbxt_assert(material->pbr.transmission_enable_in_aov.value_int != 0);
ufbxt_assert(material->features.thin_walled.enabled);
ufbxt_assert(material->features.thin_walled.is_explicit);
ufbxt_assert(material->features.matte.enabled);
ufbxt_assert(material->features.matte.is_explicit);
ufbxt_assert(material->features.caustics.enabled);
ufbxt_assert(material->features.caustics.is_explicit);
ufbxt_assert(material->features.internal_reflections.enabled);
ufbxt_assert(material->features.internal_reflections.is_explicit);
ufbxt_assert(material->features.exit_to_background.enabled);
ufbxt_assert(material->features.exit_to_background.is_explicit);
}
#endif
UFBXT_FILE_TEST(maya_osl_properties)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "standardSurface2");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_OSL_STANDARD_SURFACE);
ufbxt_assert( 1 == (int)round(100.0f * material->pbr.base_factor.value_vec3.x));
ufbxt_assert( 2 == (int)round(100.0f * material->pbr.base_color.value_vec3.x));
ufbxt_assert( 3 == (int)round(100.0f * material->pbr.base_color.value_vec3.y));
ufbxt_assert( 4 == (int)round(100.0f * material->pbr.base_color.value_vec3.z));
ufbxt_assert( 5 == (int)round(100.0f * material->pbr.diffuse_roughness.value_vec3.x));
ufbxt_assert( 6 == (int)round(100.0f * material->pbr.metalness.value_vec3.x));
ufbxt_assert( 7 == (int)round(100.0f * material->pbr.specular_factor.value_vec3.x));
ufbxt_assert( 8 == (int)round(100.0f * material->pbr.specular_color.value_vec3.x));
ufbxt_assert( 9 == (int)round(100.0f * material->pbr.specular_color.value_vec3.y));
ufbxt_assert(10 == (int)round(100.0f * material->pbr.specular_color.value_vec3.z));
ufbxt_assert(11 == (int)round(100.0f * material->pbr.roughness.value_vec3.x));
ufbxt_assert(12 == (int)round(100.0f * material->pbr.specular_ior.value_vec3.x));
ufbxt_assert(13 == (int)round(100.0f * material->pbr.specular_anisotropy.value_vec3.x));
ufbxt_assert(14 == (int)round(100.0f * material->pbr.specular_rotation.value_vec3.x));
ufbxt_assert(15 == (int)round(100.0f * material->pbr.transmission_factor.value_vec3.x));
ufbxt_assert(16 == (int)round(100.0f * material->pbr.transmission_color.value_vec3.x));
ufbxt_assert(17 == (int)round(100.0f * material->pbr.transmission_color.value_vec3.y));
ufbxt_assert(18 == (int)round(100.0f * material->pbr.transmission_color.value_vec3.z));
ufbxt_assert(19 == (int)round(100.0f * material->pbr.transmission_depth.value_vec3.x));
ufbxt_assert(20 == (int)round(100.0f * material->pbr.transmission_scatter.value_vec3.x));
ufbxt_assert(21 == (int)round(100.0f * material->pbr.transmission_scatter.value_vec3.y));
ufbxt_assert(22 == (int)round(100.0f * material->pbr.transmission_scatter.value_vec3.z));
ufbxt_assert(23 == (int)round(100.0f * material->pbr.transmission_scatter_anisotropy.value_vec3.x));
ufbxt_assert(24 == (int)round(100.0f * material->pbr.transmission_dispersion.value_vec3.x));
ufbxt_assert(25 == (int)round(100.0f * material->pbr.transmission_extra_roughness.value_vec3.x));
ufbxt_assert(26 == (int)round(100.0f * material->pbr.subsurface_factor.value_vec3.x));
ufbxt_assert(27 == (int)round(100.0f * material->pbr.subsurface_color.value_vec3.x));
ufbxt_assert(28 == (int)round(100.0f * material->pbr.subsurface_color.value_vec3.y));
ufbxt_assert(29 == (int)round(100.0f * material->pbr.subsurface_color.value_vec3.z));
ufbxt_assert(30 == (int)round(100.0f * material->pbr.subsurface_radius.value_vec3.x));
ufbxt_assert(31 == (int)round(100.0f * material->pbr.subsurface_radius.value_vec3.y));
ufbxt_assert(32 == (int)round(100.0f * material->pbr.subsurface_radius.value_vec3.z));
ufbxt_assert(33 == (int)round(100.0f * material->pbr.subsurface_scale.value_vec3.x));
ufbxt_assert(34 == (int)round(100.0f * material->pbr.subsurface_anisotropy.value_vec3.x));
ufbxt_assert(35 == (int)round(100.0f * material->pbr.coat_factor.value_vec3.x));
ufbxt_assert(36 == (int)round(100.0f * material->pbr.coat_color.value_vec3.x));
ufbxt_assert(37 == (int)round(100.0f * material->pbr.coat_color.value_vec3.y));
ufbxt_assert(38 == (int)round(100.0f * material->pbr.coat_color.value_vec3.z));
ufbxt_assert(39 == (int)round(100.0f * material->pbr.coat_roughness.value_vec3.x));
ufbxt_assert(40 == (int)round(100.0f * material->pbr.coat_ior.value_vec3.x));
ufbxt_assert(41 == (int)round(100.0f * material->pbr.coat_anisotropy.value_vec3.x));
ufbxt_assert(42 == (int)round(100.0f * material->pbr.coat_rotation.value_vec3.x));
// Not used: ufbxt_assert(43 == (int)round(100.0f * material->pbr.coat_normal.value_vec3.x));
// Not used: ufbxt_assert(44 == (int)round(100.0f * material->pbr.coat_normal.value_vec3.y));
// Not used: ufbxt_assert(45 == (int)round(100.0f * material->pbr.coat_normal.value_vec3.z));
ufbxt_assert(46 == (int)round(100.0f * material->pbr.sheen_factor.value_vec3.x));
ufbxt_assert(47 == (int)round(100.0f * material->pbr.sheen_color.value_vec3.x));
ufbxt_assert(48 == (int)round(100.0f * material->pbr.sheen_color.value_vec3.y));
ufbxt_assert(49 == (int)round(100.0f * material->pbr.sheen_color.value_vec3.z));
ufbxt_assert(50 == (int)round(100.0f * material->pbr.sheen_roughness.value_vec3.x));
ufbxt_assert(51 == (int)round(100.0f * material->pbr.emission_factor.value_vec3.x));
ufbxt_assert(52 == (int)round(100.0f * material->pbr.emission_color.value_vec3.x));
ufbxt_assert(53 == (int)round(100.0f * material->pbr.emission_color.value_vec3.y));
ufbxt_assert(54 == (int)round(100.0f * material->pbr.emission_color.value_vec3.z));
ufbxt_assert(55 == (int)round(100.0f * material->pbr.thin_film_thickness.value_vec3.x));
ufbxt_assert(56 == (int)round(100.0f * material->pbr.thin_film_ior.value_vec3.x));
ufbxt_assert(57 == (int)round(100.0f * material->pbr.opacity.value_vec3.x));
ufbxt_assert(58 == (int)round(100.0f * material->pbr.opacity.value_vec3.y));
ufbxt_assert(59 == (int)round(100.0f * material->pbr.opacity.value_vec3.z));
// Computed
ufbxt_assert_close_real(err, material->pbr.transmission_roughness.value_real, 0.36f); // 11+25
ufbxt_assert(material->features.thin_walled.enabled);
ufbxt_assert(material->features.thin_walled.is_explicit);
}
#endif
UFBXT_FILE_TEST(maya_texture_layers)
#if UFBXT_IMPL
{
// TODO: Recover layered textures from <7000.....
if (scene->metadata.version < 7000) return;
ufbx_node *node = ufbx_find_node(scene, "pCube1");
ufbxt_assert(node && node->mesh && node->mesh->materials.count == 1);
ufbx_material *material = node->mesh->materials.data[0].material;
ufbx_texture *layered = material->fbx.diffuse_color.texture;
ufbxt_assert(layered);
ufbxt_assert(layered->type == UFBX_TEXTURE_LAYERED);
ufbxt_assert(layered->layers.count == 3);
ufbxt_assert(layered->layers.data[0].blend_mode == UFBX_BLEND_MULTIPLY);
ufbxt_assert_close_real(err, layered->layers.data[0].alpha, 0.75f);
ufbxt_assert(!strcmp(layered->layers.data[0].texture->relative_filename.data, "textures\\checkerboard_weight.png"));
ufbxt_assert(layered->layers.data[1].blend_mode == UFBX_BLEND_OVER);
ufbxt_assert_close_real(err, layered->layers.data[1].alpha, 0.5f);
ufbxt_assert(!strcmp(layered->layers.data[1].texture->relative_filename.data, "textures\\checkerboard_diffuse.png"));
ufbxt_assert(layered->layers.data[2].blend_mode == UFBX_BLEND_ADDITIVE);
ufbxt_assert_close_real(err, layered->layers.data[2].alpha, 1.0f);
ufbxt_assert(!strcmp(layered->layers.data[2].texture->relative_filename.data, "textures\\checkerboard_ambient.png"));
ufbxt_assert(layered->file_textures.count == 3);
for (size_t i = 0; i < 3; i++) {
ufbxt_assert(layered->file_textures.data[i] == layered->layers.data[i].texture);
}
{
ufbx_texture *texture = material->fbx.emission_color.texture;
ufbxt_assert(texture);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_emissive.png"));
ufbxt_assert_close_real(err, texture->uv_transform.translation.x, 1.0f);
ufbxt_assert_close_real(err, texture->uv_transform.translation.y, 2.0f);
ufbxt_assert_close_real(err, texture->uv_transform.translation.z, 0.0f);
ufbx_vec3 uv = { 0.5f, 0.5f, 0.0f };
uv = ufbx_transform_position(&texture->uv_to_texture, uv);
ufbxt_assert_close_real(err, uv.x, -0.5f);
ufbxt_assert_close_real(err, uv.y, -1.5f);
ufbxt_assert_close_real(err, uv.z, 0.0f);
}
{
ufbx_texture *texture = material->fbx.transparency_color.texture;
ufbxt_assert(texture);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_transparency.png"));
ufbxt_assert_close_real(err, texture->uv_transform.translation.x, 0.5f);
ufbxt_assert_close_real(err, texture->uv_transform.translation.y, -0.20710678f);
ufbxt_assert_close_real(err, texture->uv_transform.translation.z, 0.0f);
ufbx_vec3 euler = ufbx_quat_to_euler(texture->uv_transform.rotation, UFBX_ROTATION_ORDER_XYZ);
ufbxt_assert_close_real(err, euler.x, 0.0f);
ufbxt_assert_close_real(err, euler.y, 0.0f);
ufbxt_assert_close_real(err, euler.z, 45.0f);
{
ufbx_vec3 uv = { 0.5f, 0.5f, 0.0f };
uv = ufbx_transform_position(&texture->uv_to_texture, uv);
ufbxt_assert_close_real(err, uv.x, 0.5f);
ufbxt_assert_close_real(err, uv.y, 0.5f);
ufbxt_assert_close_real(err, uv.z, 0.0f);
}
{
ufbx_vec3 uv = { 1.0f, 0.5f, 0.0f };
uv = ufbx_transform_position(&texture->uv_to_texture, uv);
ufbxt_assert_close_real(err, uv.x, 0.853553f);
ufbxt_assert_close_real(err, uv.y, 0.146447f);
ufbxt_assert_close_real(err, uv.z, 0.0f);
}
}
}
#endif
UFBXT_FILE_TEST(maya_texture_blend_modes)
#if UFBXT_IMPL
{
// TODO: Recover layered textures from <7000.....
if (scene->metadata.version < 7000) return;
ufbx_node *node = ufbx_find_node(scene, "pCube1");
ufbxt_assert(node && node->mesh && node->mesh->materials.count == 1);
ufbx_material *material = node->mesh->materials.data[0].material;
ufbx_texture *layered = material->fbx.diffuse_color.texture;
ufbxt_assert(layered);
ufbxt_assert(layered->type == UFBX_TEXTURE_LAYERED);
ufbxt_assert(layered->layers.count == 14);
for (size_t i = 0; i < layered->layers.count; i++) {
ufbx_real alpha = i < 10 ? (ufbx_real)(i + 1) * 0.1f : 1.0f;
size_t ix = layered->layers.count - i - 1;
ufbxt_assert_close_real(err, layered->layers.data[ix].alpha, alpha);
}
// All point to the same texture and should be deduplicated
ufbxt_assert(layered->file_textures.count == 1);
for (size_t i = 0; i < 14; i++) {
ufbxt_assert(layered->layers.data[i].texture == layered->file_textures.data[0]);
}
ufbxt_assert(layered->layers.data[ 0].blend_mode == UFBX_BLEND_REPLACE); // "CPV Modulate" (unsupported)
ufbxt_assert(layered->layers.data[ 1].blend_mode == UFBX_BLEND_LUMINOSITY); // "Illuminate"
ufbxt_assert(layered->layers.data[ 2].blend_mode == UFBX_BLEND_REPLACE); // "Desaturate" (unsupported)
ufbxt_assert(layered->layers.data[ 3].blend_mode == UFBX_BLEND_SATURATION); // "Saturate"
ufbxt_assert(layered->layers.data[ 4].blend_mode == UFBX_BLEND_DARKEN); // "Darken"
ufbxt_assert(layered->layers.data[ 5].blend_mode == UFBX_BLEND_LIGHTEN); // "Lighten"
ufbxt_assert(layered->layers.data[ 6].blend_mode == UFBX_BLEND_DIFFERENCE); // "Difference"
ufbxt_assert(layered->layers.data[ 7].blend_mode == UFBX_BLEND_MULTIPLY); // "Multiply"
ufbxt_assert(layered->layers.data[ 8].blend_mode == UFBX_BLEND_SUBTRACT); // "Subtract"
ufbxt_assert(layered->layers.data[ 9].blend_mode == UFBX_BLEND_ADDITIVE); // "Add"
ufbxt_assert(layered->layers.data[10].blend_mode == UFBX_BLEND_REPLACE); // "Out" (unsupported)
ufbxt_assert(layered->layers.data[11].blend_mode == UFBX_BLEND_REPLACE); // "In" (unsupported)
ufbxt_assert(layered->layers.data[12].blend_mode == UFBX_BLEND_OVER); // "Over"
ufbxt_assert(layered->layers.data[13].blend_mode == UFBX_BLEND_REPLACE); // "None"
}
#endif
UFBXT_FILE_TEST(max_texture_mapping)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "01 - Default");
ufbxt_assert(material);
{
ufbx_texture *texture = material->pbr.base_factor.texture;
ufbxt_assert(texture && texture->shader);
ufbx_shader_texture *shader = texture->shader;
ufbxt_assert(texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_weight.png"));
ufbxt_assert(shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(shader->shader_name.data, "OSLBitmap2"));
uint32_t source_hash = ufbxt_fnv1a(shader->shader_source.data, shader->shader_source.length);
ufbxt_assert(source_hash == 0x599994a9u);
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(texture->file_textures.data[0] == texture);
}
{
ufbx_texture *texture = material->pbr.base_color.texture;
ufbxt_assert(texture && texture->shader);
ufbx_shader_texture *shader = texture->shader;
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(shader->shader_name.data, "RandomTilingBitmap"));
uint32_t source_hash = ufbxt_fnv1a(shader->shader_source.data, shader->shader_source.length);
ufbxt_assert(source_hash == 0x60186ba7u);
{
ufbx_shader_texture_input *input = ufbx_find_shader_texture_input(shader, "Filename");
ufbxt_assert(input);
ufbxt_assert(!strcmp(input->value_str.data, "D:\\Dev\\clean\\ufbx\\data\\textures\\checkerboard_diffuse.png"));
}
{
ufbx_shader_texture_input *input = ufbx_find_shader_texture_input(shader, "Scale");
ufbxt_assert(input);
ufbxt_assert_close_real(err, input->value_real, 0.25f);
}
ufbxt_assert(texture->file_textures.count == 0);
}
{
ufbx_texture *texture = material->pbr.roughness.texture;
ufbxt_assert(texture && texture->shader);
ufbx_shader_texture *shader = texture->shader;
ufbxt_assert(texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_roughness.png"));
ufbxt_assert(shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(shader->shader_name.data, "UberBitmap2"));
uint32_t source_hash = ufbxt_fnv1a(shader->shader_source.data, shader->shader_source.length);
ufbxt_assert(source_hash == 0x19833d47);
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(texture->file_textures.data[0] == texture);
}
{
ufbx_texture *texture = material->pbr.metalness.texture;
ufbxt_assert(texture && !texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_metallic.png"));
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(texture->file_textures.data[0] == texture);
}
{
ufbx_texture *texture = material->pbr.transmission_color.texture;
ufbxt_assert(texture && texture->shader);
ufbx_shader_texture *shader = texture->shader;
ufbxt_assert(texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_transparency.png"));
ufbxt_assert(shader->type == UFBX_SHADER_TEXTURE_UNKNOWN);
ufbxt_assert(!strcmp(shader->shader_name.data, "ai_image"));
ufbxt_assert(shader->shader_source.length == 0);
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(texture->file_textures.data[0] == texture);
}
{
ufbx_texture *texture = material->pbr.transmission_color.texture;
ufbxt_assert(texture && texture->shader);
ufbx_shader_texture *shader = texture->shader;
ufbxt_assert(texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_transparency.png"));
ufbxt_assert(shader->type == UFBX_SHADER_TEXTURE_UNKNOWN);
ufbxt_assert(shader->shader_source.length == 0);
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(texture->file_textures.data[0] == texture);
}
{
ufbx_texture *texture = material->pbr.emission_color.texture;
ufbxt_assert(texture && texture->shader);
ufbx_shader_texture *shader = texture->shader;
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(shader->shader_name.data, "ColorTweak"));
uint32_t source_hash = ufbxt_fnv1a(shader->shader_source.data, shader->shader_source.length);
ufbxt_assert(source_hash == 0xd2f4f86f);
ufbx_shader_texture_input *input = ufbx_find_shader_texture_input(shader, "Input");
ufbxt_assert(input);
ufbx_texture *input_texture = input->texture;
ufbxt_assert(input_texture);
ufbxt_assert(input_texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(texture->file_textures.data[0] == input_texture);
}
{
ufbx_texture *texture = material->pbr.normal_map.texture;
ufbxt_assert(texture && texture->shader);
ufbx_shader_texture *shader = texture->shader;
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(shader->type == UFBX_SHADER_TEXTURE_UNKNOWN);
ufbxt_assert(!strcmp(shader->shader_name.data, "ai_bump2d"));
ufbxt_assert(shader->shader_source.length == 0);
ufbx_shader_texture_input *bump_map = ufbx_find_shader_texture_input(shader, "bump_map");
ufbxt_assert(bump_map);
ufbx_texture *bump_texture = bump_map->texture;
ufbxt_assert(bump_texture);
ufbxt_assert(bump_texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(texture->file_textures.data[0] == bump_texture);
}
}
#endif
UFBXT_FILE_TEST(synthetic_missing_material_factor)
#if UFBXT_IMPL
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "phong1");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_FBX_PHONG);
ufbxt_assert_close_real(err, material->fbx.diffuse_factor.value_vec3.x, 1.0f);
ufbxt_assert_close_real(err, material->fbx.specular_factor.value_vec3.x, 1.0f);
ufbxt_assert_close_real(err, material->fbx.reflection_factor.value_vec3.x, 1.0f);
ufbxt_assert_close_real(err, material->fbx.transparency_factor.value_vec3.x, 1.0f);
ufbxt_assert_close_real(err, material->fbx.emission_factor.value_vec3.x, 1.0f);
ufbxt_assert_close_real(err, material->fbx.ambient_factor.value_vec3.x, 1.0f);
// TODO: Figure out how to map transmission/opacity
ufbxt_assert_close_real(err, material->pbr.base_factor.value_vec3.x, 1.0f);
ufbxt_assert_close_real(err, material->pbr.specular_factor.value_vec3.x, 1.0f);
ufbxt_assert_close_real(err, material->pbr.emission_factor.value_vec3.x, 1.0f);
}
#endif
UFBXT_FILE_TEST(max_instanced_material)
#if UFBXT_IMPL
{
ufbx_node *red_node = ufbx_find_node(scene, "Red");
ufbx_node *green_node = ufbx_find_node(scene, "Green");
ufbx_node *blue_node = ufbx_find_node(scene, "Blue");
ufbxt_assert(red_node && red_node->mesh);
ufbxt_assert(green_node && green_node->mesh);
ufbxt_assert(blue_node && blue_node->mesh);
ufbx_mesh *red_mesh = red_node->mesh;
ufbx_mesh *green_mesh = green_node->mesh;
ufbx_mesh *blue_mesh = blue_node->mesh;
ufbx_material *red_mat = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "RedMat");
ufbx_material *green_mat = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "GreenMat");
ufbx_material *blue_mat = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "BlueMat");
if (scene->metadata.version < 7000) {
ufbxt_assert(red_mesh != green_mesh);
ufbxt_assert(red_mesh != blue_mesh);
ufbxt_assert(green_mesh != blue_mesh);
// 6100 is a bit broken with materials?
ufbxt_assert(green_node->materials.count == 3);
ufbxt_assert(red_node->materials.count == 2);
ufbxt_assert(blue_node->materials.count == 1);
ufbxt_assert(green_mesh->materials.count == 3);
ufbxt_assert(red_mesh->materials.count == 2);
ufbxt_assert(blue_mesh->materials.count == 1);
} else {
ufbxt_assert(red_mesh == green_mesh);
ufbxt_assert(red_mesh == blue_mesh);
ufbxt_assert(green_mesh == blue_mesh);
ufbxt_assert(green_node->materials.count == 1);
ufbxt_assert(red_node->materials.count == 1);
ufbxt_assert(blue_node->materials.count == 1);
ufbxt_assert(green_node->materials.data[0] == green_mat);
ufbxt_assert(red_node->materials.data[0] == red_mat);
ufbxt_assert(blue_node->materials.data[0] == blue_mat);
ufbxt_assert(red_mesh->materials.data[0].material == green_mat);
}
}
#endif
#if UFBXT_IMPL
static bool ufbxt_has_texture(ufbx_texture_list list, const char *name)
{
for (size_t i = 0; i < list.count; i++) {
if (!strcmp(list.data[i]->relative_filename.data, name)) return true;
}
return false;
}
static void ufbxt_check_shader_input_map(ufbx_texture *texture, const char *name, const char *map, int64_t output_index)
{
ufbxt_assert(texture->shader);
ufbx_shader_texture_input *input = ufbx_find_shader_texture_input(texture->shader, name);
ufbxt_assert(input);
ufbxt_assert(input->texture);
ufbxt_assert(!strcmp(input->texture->name.data, map));
ufbxt_assert(input->texture_output_index == output_index);
}
#endif
UFBXT_FILE_TEST(max_shadergraph)
#if UFBXT_IMPL
{
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #1");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_UNKNOWN);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "ai_checkerboard"));
ufbxt_assert(texture->file_textures.count == 0);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #2");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_UNKNOWN);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "ai_add"));
ufbxt_assert(texture->file_textures.count == 0);
ufbxt_check_shader_input_map(texture, "input1", "Map #1", 0);
ufbxt_check_shader_input_map(texture, "input2", "Map #3", 0);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #3");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "Checker"));
ufbxt_assert(texture->file_textures.count == 0);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #6");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "ColorMul"));
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_diffuse.png"));
ufbxt_check_shader_input_map(texture, "A", "Map #2", 0);
ufbxt_check_shader_input_map(texture, "B", "Map #7", 0);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #7");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_diffuse.png"));
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "OSLBitmap2"));
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_diffuse.png"));
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #11");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_metallic.png"));
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_UNKNOWN);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "ai_image"));
ufbxt_assert(texture->file_textures.count == 2);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_diffuse.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_metallic.png"));
ufbxt_check_shader_input_map(texture, "offset", "Map #7", 2);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #13");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "ColorMax"));
ufbxt_assert(texture->file_textures.count == 2);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_diffuse.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_weight.png"));
ufbxt_check_shader_input_map(texture, "A", "Map #15", 0);
ufbxt_check_shader_input_map(texture, "B", "Map #6", 0);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #14");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_weight.png"));
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "UberBitmap2"));
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_weight.png"));
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #15");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "TriTone"));
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_weight.png"));
ufbxt_check_shader_input_map(texture, "Input_map", "Map #14", 0);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #16");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_UNKNOWN);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "ai_mix_rgba"));
ufbxt_assert(texture->file_textures.count == 3);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_diffuse.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_metallic.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_weight.png"));
ufbxt_check_shader_input_map(texture, "input1", "Map #13", 0);
ufbxt_check_shader_input_map(texture, "input2", "Map #11", 0);
ufbxt_check_shader_input_map(texture, "mix", "Map #7", 1);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #17");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_UNKNOWN);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "ai_dot"));
ufbxt_assert(texture->file_textures.count == 3);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_diffuse.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_metallic.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_weight.png"));
ufbxt_check_shader_input_map(texture, "input1", "Map #16", 0);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #19");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "ColorAdd"));
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_emissive.png"));
ufbxt_check_shader_input_map(texture, "A", "Map #20", 0);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #20");
ufbxt_assert(texture && !texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_emissive.png"));
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_emissive.png"));
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #21");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_UNKNOWN);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "ai_add"));
ufbxt_assert(texture->file_textures.count == 2);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_emissive.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_specular.png"));
ufbxt_check_shader_input_map(texture, "input1", "Map #22", 0);
ufbxt_check_shader_input_map(texture, "input2", "Map #19", 0);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #22");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_specular.png"));
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_UNKNOWN);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "ai_image"));
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_specular.png"));
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #26");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "VectorAdd"));
ufbxt_assert(texture->file_textures.count == 3);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_emissive.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_specular.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_transparency.png"));
ufbxt_check_shader_input_map(texture, "A", "Map #28", 0);
ufbxt_check_shader_input_map(texture, "B", "Map #21", 0);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #28");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_transparency.png"));
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "OSLBitmap2"));
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_transparency.png"));
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #29");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "ColorAdd"));
ufbxt_assert(texture->file_textures.count == 4);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_emissive.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_specular.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_transparency.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_ambient.png"));
ufbxt_check_shader_input_map(texture, "A", "Map #30", 0);
ufbxt_check_shader_input_map(texture, "B", "Map #26", 0);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #30");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_ambient.png"));
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_OSL);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, "UberBitmap2"));
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_ambient.png"));
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #31");
ufbxt_assert(texture && texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_SHADER);
ufbxt_assert(texture->shader->type == UFBX_SHADER_TEXTURE_UNKNOWN);
ufbxt_assert(!strcmp(texture->shader->shader_name.data, ""));
ufbxt_assert(texture->shader->shader_type_id == UINT64_C(0x0000023000000000));
ufbxt_assert(texture->file_textures.count == 5);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_emissive.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_specular.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_transparency.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_ambient.png"));
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_displacement.png"));
ufbxt_check_shader_input_map(texture, "map1", "Map #29", 0);
ufbxt_check_shader_input_map(texture, "map2", "Map #32", 0);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "Map #32");
ufbxt_assert(texture && !texture->shader);
ufbxt_assert(texture->type == UFBX_TEXTURE_FILE);
ufbxt_assert(!strcmp(texture->relative_filename.data, "textures\\checkerboard_displacement.png"));
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_displacement.png"));
}
{
ufbx_material *material = (ufbx_material*)ufbx_find_element(scene, UFBX_ELEMENT_MATERIAL, "Material #25");
ufbxt_assert(material);
ufbxt_assert(material->shader_type == UFBX_SHADER_OSL_STANDARD_SURFACE);
ufbxt_assert(material->pbr.base_factor.texture);
ufbxt_assert(!strcmp(material->pbr.base_factor.texture->name.data, "Map #17"));
ufbxt_assert(material->pbr.base_color.texture);
ufbxt_assert(!strcmp(material->pbr.base_color.texture->name.data, "Map #13"));
ufbxt_assert(material->pbr.emission_factor.texture);
ufbxt_assert(!strcmp(material->pbr.emission_factor.texture->name.data, "Map #31"));
{
ufbx_texture *texture = material->pbr.roughness.texture;
ufbxt_assert(texture);
ufbxt_assert(texture->shader);
ufbxt_assert(texture->file_textures.count == 1);
ufbxt_assert(ufbxt_has_texture(texture->file_textures, "textures\\checkerboard_ambient.png"));
ufbxt_assert(texture->shader->main_texture);
ufbxt_assert(texture->shader->main_texture_output_index == 6);
ufbxt_assert(!strcmp(texture->shader->main_texture->name.data, "Map #30"));
ufbxt_check_shader_input_map(texture, "sourceMap", "Map #30", 6);
}
}
}
#endif
UFBXT_FILE_TEST(maya_duplicated_texture)
#if UFBXT_IMPL
{
ufbxt_assert(scene->texture_files.count == 1);
ufbxt_assert(scene->textures.count == 4);
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "file1");
ufbxt_assert(texture->has_file);
ufbxt_assert(texture->file_index == 0);
ufbxt_assert(!strcmp(texture->uv_set.data, "map1"));
ufbxt_assert(!texture->has_uv_transform);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "file2");
ufbxt_assert(texture->has_file);
ufbxt_assert(texture->file_index == 0);
ufbxt_assert(!strcmp(texture->uv_set.data, "map1"));
ufbxt_assert(!texture->has_uv_transform);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "file3");
ufbxt_assert(texture->has_file);
ufbxt_assert(texture->file_index == 0);
ufbxt_assert(!strcmp(texture->uv_set.data, "map1"));
ufbxt_assert(texture->has_uv_transform);
ufbxt_assert_close_real(err, texture->uv_transform.scale.x, 2.0f);
ufbxt_assert_close_real(err, texture->uv_transform.scale.y, 2.0f);
}
{
ufbx_texture *texture = (ufbx_texture*)ufbx_find_element(scene, UFBX_ELEMENT_TEXTURE, "file4");
ufbxt_assert(texture->has_file);
ufbxt_assert(texture->file_index == 0);
ufbxt_assert(!strcmp(texture->uv_set.data, "second"));
ufbxt_assert(!texture->has_uv_transform);
}
}
#endif