Browse Source

Cache materials in gltf as the abstract class of Material

Use the abstract material class instead of BaseMaterial3D. This allows inserting ShaderMaterials into gltf. Like in VRM.
K. S. Ernest (iFire) Lee 2 years ago
parent
commit
baab97302a

+ 2 - 2
modules/gltf/doc_classes/GLTFState.xml

@@ -66,7 +66,7 @@
 			</description>
 		</method>
 		<method name="get_materials">
-			<return type="BaseMaterial3D[]" />
+			<return type="Material[]" />
 			<description>
 			</description>
 		</method>
@@ -169,7 +169,7 @@
 		</method>
 		<method name="set_materials">
 			<return type="void" />
-			<param index="0" name="materials" type="BaseMaterial3D[]" />
+			<param index="0" name="materials" type="Material[]" />
 			<description>
 			</description>
 		</method>

+ 189 - 181
modules/gltf/gltf_document.cpp

@@ -2484,12 +2484,12 @@ Error GLTFDocument::_serialize_meshes(Ref<GLTFState> state) {
 			if (surface_i < instance_materials.size()) {
 				v = instance_materials.get(surface_i);
 			}
-			Ref<BaseMaterial3D> mat = v;
+			Ref<Material> mat = v;
 			if (!mat.is_valid()) {
 				mat = import_mesh->get_surface_material(surface_i);
 			}
 			if (mat.is_valid()) {
-				HashMap<Ref<BaseMaterial3D>, GLTFMaterialIndex>::Iterator material_cache_i = state->material_cache.find(mat);
+				HashMap<Ref<Material>, GLTFMaterialIndex>::Iterator material_cache_i = state->material_cache.find(mat);
 				if (material_cache_i && material_cache_i->value != -1) {
 					primitive["material"] = material_cache_i->value;
 				} else {
@@ -2937,16 +2937,18 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
 				}
 			}
 
-			Ref<BaseMaterial3D> mat;
+			Ref<Material> mat;
 			String mat_name;
 			if (!state->discard_meshes_and_materials) {
 				if (p.has("material")) {
 					const int material = p["material"];
 					ERR_FAIL_INDEX_V(material, state->materials.size(), ERR_FILE_CORRUPT);
-					Ref<BaseMaterial3D> mat3d = state->materials[material];
+					Ref<Material> mat3d = state->materials[material];
 					ERR_FAIL_NULL_V(mat3d, ERR_FILE_CORRUPT);
-					if (has_vertex_color) {
-						mat3d->set_flag(BaseMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+
+					Ref<BaseMaterial3D> base_material = mat3d;
+					if (has_vertex_color && base_material.is_valid()) {
+						base_material->set_flag(BaseMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
 					}
 					mat = mat3d;
 
@@ -2954,7 +2956,7 @@ Error GLTFDocument::_parse_meshes(Ref<GLTFState> state) {
 					Ref<StandardMaterial3D> mat3d;
 					mat3d.instantiate();
 					if (has_vertex_color) {
-						mat3d->set_flag(BaseMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
+						mat3d->set_flag(StandardMaterial3D::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
 					}
 					mat = mat3d;
 				}
@@ -3382,8 +3384,7 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
 	Array materials;
 	for (int32_t i = 0; i < state->materials.size(); i++) {
 		Dictionary d;
-
-		Ref<BaseMaterial3D> material = state->materials[i];
+		Ref<Material> material = state->materials[i];
 		if (material.is_null()) {
 			materials.push_back(d);
 			continue;
@@ -3391,11 +3392,12 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
 		if (!material->get_name().is_empty()) {
 			d["name"] = _gen_unique_name(state, material->get_name());
 		}
-		{
+		Ref<BaseMaterial3D> base_material = material;
+		if (base_material.is_valid()) {
 			Dictionary mr;
 			{
 				Array arr;
-				const Color c = material->get_albedo().srgb_to_linear();
+				const Color c = base_material->get_albedo().srgb_to_linear();
 				arr.push_back(c.r);
 				arr.push_back(c.g);
 				arr.push_back(c.b);
@@ -3404,167 +3406,169 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
 			}
 			{
 				Dictionary bct;
-				Ref<Texture2D> albedo_texture = material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO);
-				GLTFTextureIndex gltf_texture_index = -1;
+				if (base_material.is_valid()) {
+					Ref<Texture2D> albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO);
+					GLTFTextureIndex gltf_texture_index = -1;
 
-				if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) {
-					albedo_texture->set_name(material->get_name() + "_albedo");
-					gltf_texture_index = _set_texture(state, albedo_texture, material->get_texture_filter(), material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
-				}
-				if (gltf_texture_index != -1) {
-					bct["index"] = gltf_texture_index;
-					Dictionary extensions = _serialize_texture_transform_uv1(material);
-					if (!extensions.is_empty()) {
-						bct["extensions"] = extensions;
-						state->use_khr_texture_transform = true;
+					if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) {
+						albedo_texture->set_name(material->get_name() + "_albedo");
+						gltf_texture_index = _set_texture(state, albedo_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
+					}
+					if (gltf_texture_index != -1) {
+						bct["index"] = gltf_texture_index;
+						Dictionary extensions = _serialize_texture_transform_uv1(material);
+						if (!extensions.is_empty()) {
+							bct["extensions"] = extensions;
+							state->use_khr_texture_transform = true;
+						}
+						mr["baseColorTexture"] = bct;
 					}
-					mr["baseColorTexture"] = bct;
 				}
 			}
-
-			mr["metallicFactor"] = material->get_metallic();
-			mr["roughnessFactor"] = material->get_roughness();
-			bool has_roughness = material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS).is_valid() && material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS)->get_image().is_valid();
-			bool has_ao = material->get_feature(BaseMaterial3D::FEATURE_AMBIENT_OCCLUSION) && material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION).is_valid();
-			bool has_metalness = material->get_texture(BaseMaterial3D::TEXTURE_METALLIC).is_valid() && material->get_texture(BaseMaterial3D::TEXTURE_METALLIC)->get_image().is_valid();
-			if (has_ao || has_roughness || has_metalness) {
-				Dictionary mrt;
-				Ref<Texture2D> roughness_texture = material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS);
-				BaseMaterial3D::TextureChannel roughness_channel = material->get_roughness_texture_channel();
-				Ref<Texture2D> metallic_texture = material->get_texture(BaseMaterial3D::TEXTURE_METALLIC);
-				BaseMaterial3D::TextureChannel metalness_channel = material->get_metallic_texture_channel();
-				Ref<Texture2D> ao_texture = material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION);
-				BaseMaterial3D::TextureChannel ao_channel = material->get_ao_texture_channel();
-				Ref<ImageTexture> orm_texture;
-				orm_texture.instantiate();
-				Ref<Image> orm_image;
-				orm_image.instantiate();
-				int32_t height = 0;
-				int32_t width = 0;
-				Ref<Image> ao_image;
-				if (has_ao) {
-					height = ao_texture->get_height();
-					width = ao_texture->get_width();
-					ao_image = ao_texture->get_image();
-					Ref<ImageTexture> img_tex = ao_image;
-					if (img_tex.is_valid()) {
-						ao_image = img_tex->get_image();
+			if (base_material.is_valid()) {
+				mr["metallicFactor"] = base_material->get_metallic();
+				mr["roughnessFactor"] = base_material->get_roughness();
+				bool has_roughness = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS)->get_image().is_valid();
+				bool has_ao = base_material->get_feature(BaseMaterial3D::FEATURE_AMBIENT_OCCLUSION) && base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION).is_valid();
+				bool has_metalness = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC).is_valid() && base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC)->get_image().is_valid();
+				if (has_ao || has_roughness || has_metalness) {
+					Dictionary mrt;
+					Ref<Texture2D> roughness_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ROUGHNESS);
+					BaseMaterial3D::TextureChannel roughness_channel = base_material->get_roughness_texture_channel();
+					Ref<Texture2D> metallic_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_METALLIC);
+					BaseMaterial3D::TextureChannel metalness_channel = base_material->get_metallic_texture_channel();
+					Ref<Texture2D> ao_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_AMBIENT_OCCLUSION);
+					BaseMaterial3D::TextureChannel ao_channel = base_material->get_ao_texture_channel();
+					Ref<ImageTexture> orm_texture;
+					orm_texture.instantiate();
+					Ref<Image> orm_image;
+					orm_image.instantiate();
+					int32_t height = 0;
+					int32_t width = 0;
+					Ref<Image> ao_image;
+					if (has_ao) {
+						height = ao_texture->get_height();
+						width = ao_texture->get_width();
+						ao_image = ao_texture->get_image();
+						Ref<ImageTexture> img_tex = ao_image;
+						if (img_tex.is_valid()) {
+							ao_image = img_tex->get_image();
+						}
+						if (ao_image->is_compressed()) {
+							ao_image->decompress();
+						}
 					}
-					if (ao_image->is_compressed()) {
-						ao_image->decompress();
+					Ref<Image> roughness_image;
+					if (has_roughness) {
+						height = roughness_texture->get_height();
+						width = roughness_texture->get_width();
+						roughness_image = roughness_texture->get_image();
+						Ref<ImageTexture> img_tex = roughness_image;
+						if (img_tex.is_valid()) {
+							roughness_image = img_tex->get_image();
+						}
+						if (roughness_image->is_compressed()) {
+							roughness_image->decompress();
+						}
 					}
-				}
-				Ref<Image> roughness_image;
-				if (has_roughness) {
-					height = roughness_texture->get_height();
-					width = roughness_texture->get_width();
-					roughness_image = roughness_texture->get_image();
-					Ref<ImageTexture> img_tex = roughness_image;
-					if (img_tex.is_valid()) {
-						roughness_image = img_tex->get_image();
+					Ref<Image> metallness_image;
+					if (has_metalness) {
+						height = metallic_texture->get_height();
+						width = metallic_texture->get_width();
+						metallness_image = metallic_texture->get_image();
+						Ref<ImageTexture> img_tex = metallness_image;
+						if (img_tex.is_valid()) {
+							metallness_image = img_tex->get_image();
+						}
+						if (metallness_image->is_compressed()) {
+							metallness_image->decompress();
+						}
 					}
-					if (roughness_image->is_compressed()) {
-						roughness_image->decompress();
+					Ref<Texture2D> albedo_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO);
+					if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) {
+						height = albedo_texture->get_height();
+						width = albedo_texture->get_width();
 					}
-				}
-				Ref<Image> metallness_image;
-				if (has_metalness) {
-					height = metallic_texture->get_height();
-					width = metallic_texture->get_width();
-					metallness_image = metallic_texture->get_image();
-					Ref<ImageTexture> img_tex = metallness_image;
-					if (img_tex.is_valid()) {
-						metallness_image = img_tex->get_image();
+					orm_image->initialize_data(width, height, false, Image::FORMAT_RGBA8);
+					if (ao_image.is_valid() && ao_image->get_size() != Vector2(width, height)) {
+						ao_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
 					}
-					if (metallness_image->is_compressed()) {
-						metallness_image->decompress();
+					if (roughness_image.is_valid() && roughness_image->get_size() != Vector2(width, height)) {
+						roughness_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
 					}
-				}
-				Ref<Texture2D> albedo_texture = material->get_texture(BaseMaterial3D::TEXTURE_ALBEDO);
-				if (albedo_texture.is_valid() && albedo_texture->get_image().is_valid()) {
-					height = albedo_texture->get_height();
-					width = albedo_texture->get_width();
-				}
-				orm_image->initialize_data(width, height, false, Image::FORMAT_RGBA8);
-				if (ao_image.is_valid() && ao_image->get_size() != Vector2(width, height)) {
-					ao_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
-				}
-				if (roughness_image.is_valid() && roughness_image->get_size() != Vector2(width, height)) {
-					roughness_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
-				}
-				if (metallness_image.is_valid() && metallness_image->get_size() != Vector2(width, height)) {
-					metallness_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
-				}
-				for (int32_t h = 0; h < height; h++) {
-					for (int32_t w = 0; w < width; w++) {
-						Color c = Color(1.0f, 1.0f, 1.0f);
-						if (has_ao) {
-							if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == ao_channel) {
-								c.r = ao_image->get_pixel(w, h).r;
-							} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == ao_channel) {
-								c.r = ao_image->get_pixel(w, h).g;
-							} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == ao_channel) {
-								c.r = ao_image->get_pixel(w, h).b;
-							} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == ao_channel) {
-								c.r = ao_image->get_pixel(w, h).a;
+					if (metallness_image.is_valid() && metallness_image->get_size() != Vector2(width, height)) {
+						metallness_image->resize(width, height, Image::INTERPOLATE_LANCZOS);
+					}
+					for (int32_t h = 0; h < height; h++) {
+						for (int32_t w = 0; w < width; w++) {
+							Color c = Color(1.0f, 1.0f, 1.0f);
+							if (has_ao) {
+								if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == ao_channel) {
+									c.r = ao_image->get_pixel(w, h).r;
+								} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == ao_channel) {
+									c.r = ao_image->get_pixel(w, h).g;
+								} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == ao_channel) {
+									c.r = ao_image->get_pixel(w, h).b;
+								} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == ao_channel) {
+									c.r = ao_image->get_pixel(w, h).a;
+								}
 							}
-						}
-						if (has_roughness) {
-							if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == roughness_channel) {
-								c.g = roughness_image->get_pixel(w, h).r;
-							} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == roughness_channel) {
-								c.g = roughness_image->get_pixel(w, h).g;
-							} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == roughness_channel) {
-								c.g = roughness_image->get_pixel(w, h).b;
-							} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == roughness_channel) {
-								c.g = roughness_image->get_pixel(w, h).a;
+							if (has_roughness) {
+								if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == roughness_channel) {
+									c.g = roughness_image->get_pixel(w, h).r;
+								} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == roughness_channel) {
+									c.g = roughness_image->get_pixel(w, h).g;
+								} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == roughness_channel) {
+									c.g = roughness_image->get_pixel(w, h).b;
+								} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == roughness_channel) {
+									c.g = roughness_image->get_pixel(w, h).a;
+								}
 							}
-						}
-						if (has_metalness) {
-							if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == metalness_channel) {
-								c.b = metallness_image->get_pixel(w, h).r;
-							} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == metalness_channel) {
-								c.b = metallness_image->get_pixel(w, h).g;
-							} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == metalness_channel) {
-								c.b = metallness_image->get_pixel(w, h).b;
-							} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == metalness_channel) {
-								c.b = metallness_image->get_pixel(w, h).a;
+							if (has_metalness) {
+								if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_RED == metalness_channel) {
+									c.b = metallness_image->get_pixel(w, h).r;
+								} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_GREEN == metalness_channel) {
+									c.b = metallness_image->get_pixel(w, h).g;
+								} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_BLUE == metalness_channel) {
+									c.b = metallness_image->get_pixel(w, h).b;
+								} else if (BaseMaterial3D::TextureChannel::TEXTURE_CHANNEL_ALPHA == metalness_channel) {
+									c.b = metallness_image->get_pixel(w, h).a;
+								}
 							}
+							orm_image->set_pixel(w, h, c);
 						}
-						orm_image->set_pixel(w, h, c);
 					}
-				}
-				orm_image->generate_mipmaps();
-				orm_texture->set_image(orm_image);
-				GLTFTextureIndex orm_texture_index = -1;
-				if (has_ao || has_roughness || has_metalness) {
-					orm_texture->set_name(material->get_name() + "_orm");
-					orm_texture_index = _set_texture(state, orm_texture, material->get_texture_filter(), material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
-				}
-				if (has_ao) {
-					Dictionary occt;
-					occt["index"] = orm_texture_index;
-					d["occlusionTexture"] = occt;
-				}
-				if (has_roughness || has_metalness) {
-					mrt["index"] = orm_texture_index;
-					Dictionary extensions = _serialize_texture_transform_uv1(material);
-					if (!extensions.is_empty()) {
-						mrt["extensions"] = extensions;
-						state->use_khr_texture_transform = true;
+					orm_image->generate_mipmaps();
+					orm_texture->set_image(orm_image);
+					GLTFTextureIndex orm_texture_index = -1;
+					if (has_ao || has_roughness || has_metalness) {
+						orm_texture->set_name(material->get_name() + "_orm");
+						orm_texture_index = _set_texture(state, orm_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
+					}
+					if (has_ao) {
+						Dictionary occt;
+						occt["index"] = orm_texture_index;
+						d["occlusionTexture"] = occt;
+					}
+					if (has_roughness || has_metalness) {
+						mrt["index"] = orm_texture_index;
+						Dictionary extensions = _serialize_texture_transform_uv1(material);
+						if (!extensions.is_empty()) {
+							mrt["extensions"] = extensions;
+							state->use_khr_texture_transform = true;
+						}
+						mr["metallicRoughnessTexture"] = mrt;
 					}
-					mr["metallicRoughnessTexture"] = mrt;
 				}
 			}
 			d["pbrMetallicRoughness"] = mr;
 		}
-
-		if (material->get_feature(BaseMaterial3D::FEATURE_NORMAL_MAPPING)) {
+		if (base_material->get_feature(BaseMaterial3D::FEATURE_NORMAL_MAPPING)) {
 			Dictionary nt;
 			Ref<ImageTexture> tex;
 			tex.instantiate();
 			{
-				Ref<Texture2D> normal_texture = material->get_texture(BaseMaterial3D::TEXTURE_NORMAL);
+				Ref<Texture2D> normal_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_NORMAL);
 				if (normal_texture.is_valid()) {
 					// Code for uncompressing RG normal maps
 					Ref<Image> img = normal_texture->get_image();
@@ -3594,30 +3598,30 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
 			GLTFTextureIndex gltf_texture_index = -1;
 			if (tex.is_valid() && tex->get_image().is_valid()) {
 				tex->set_name(material->get_name() + "_normal");
-				gltf_texture_index = _set_texture(state, tex, material->get_texture_filter(), material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
+				gltf_texture_index = _set_texture(state, tex, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
 			}
-			nt["scale"] = material->get_normal_scale();
+			nt["scale"] = base_material->get_normal_scale();
 			if (gltf_texture_index != -1) {
 				nt["index"] = gltf_texture_index;
 				d["normalTexture"] = nt;
 			}
 		}
 
-		if (material->get_feature(BaseMaterial3D::FEATURE_EMISSION)) {
-			const Color c = material->get_emission().linear_to_srgb();
+		if (base_material->get_feature(BaseMaterial3D::FEATURE_EMISSION)) {
+			const Color c = base_material->get_emission().linear_to_srgb();
 			Array arr;
 			arr.push_back(c.r);
 			arr.push_back(c.g);
 			arr.push_back(c.b);
 			d["emissiveFactor"] = arr;
 		}
-		if (material->get_feature(BaseMaterial3D::FEATURE_EMISSION)) {
+		if (base_material->get_feature(BaseMaterial3D::FEATURE_EMISSION)) {
 			Dictionary et;
-			Ref<Texture2D> emission_texture = material->get_texture(BaseMaterial3D::TEXTURE_EMISSION);
+			Ref<Texture2D> emission_texture = base_material->get_texture(BaseMaterial3D::TEXTURE_EMISSION);
 			GLTFTextureIndex gltf_texture_index = -1;
 			if (emission_texture.is_valid() && emission_texture->get_image().is_valid()) {
 				emission_texture->set_name(material->get_name() + "_emission");
-				gltf_texture_index = _set_texture(state, emission_texture, material->get_texture_filter(), material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
+				gltf_texture_index = _set_texture(state, emission_texture, base_material->get_texture_filter(), base_material->get_flag(BaseMaterial3D::FLAG_USE_TEXTURE_REPEAT));
 			}
 
 			if (gltf_texture_index != -1) {
@@ -3625,14 +3629,14 @@ Error GLTFDocument::_serialize_materials(Ref<GLTFState> state) {
 				d["emissiveTexture"] = et;
 			}
 		}
-		const bool ds = material->get_cull_mode() == BaseMaterial3D::CULL_DISABLED;
+		const bool ds = base_material->get_cull_mode() == BaseMaterial3D::CULL_DISABLED;
 		if (ds) {
 			d["doubleSided"] = ds;
 		}
-		if (material->get_transparency() == BaseMaterial3D::TRANSPARENCY_ALPHA_SCISSOR) {
+		if (base_material->get_transparency() == BaseMaterial3D::TRANSPARENCY_ALPHA_SCISSOR) {
 			d["alphaMode"] = "MASK";
-			d["alphaCutoff"] = material->get_alpha_scissor_threshold();
-		} else if (material->get_transparency() != BaseMaterial3D::TRANSPARENCY_DISABLED) {
+			d["alphaCutoff"] = base_material->get_alpha_scissor_threshold();
+		} else if (base_material->get_transparency() != BaseMaterial3D::TRANSPARENCY_DISABLED) {
 			d["alphaMode"] = "BLEND";
 		}
 		materials.push_back(d);
@@ -3838,29 +3842,37 @@ void GLTFDocument::_set_texture_transform_uv1(const Dictionary &d, Ref<BaseMater
 	if (d.has("extensions")) {
 		const Dictionary &extensions = d["extensions"];
 		if (extensions.has("KHR_texture_transform")) {
-			const Dictionary &texture_transform = extensions["KHR_texture_transform"];
-			const Array &offset_arr = texture_transform["offset"];
-			if (offset_arr.size() == 2) {
-				const Vector3 offset_vector3 = Vector3(offset_arr[0], offset_arr[1], 0.0f);
-				material->set_uv1_offset(offset_vector3);
-			}
+			if (material.is_valid()) {
+				const Dictionary &texture_transform = extensions["KHR_texture_transform"];
+				const Array &offset_arr = texture_transform["offset"];
+				if (offset_arr.size() == 2) {
+					const Vector3 offset_vector3 = Vector3(offset_arr[0], offset_arr[1], 0.0f);
+					material->set_uv1_offset(offset_vector3);
+				}
 
-			const Array &scale_arr = texture_transform["scale"];
-			if (scale_arr.size() == 2) {
-				const Vector3 scale_vector3 = Vector3(scale_arr[0], scale_arr[1], 1.0f);
-				material->set_uv1_scale(scale_vector3);
+				const Array &scale_arr = texture_transform["scale"];
+				if (scale_arr.size() == 2) {
+					const Vector3 scale_vector3 = Vector3(scale_arr[0], scale_arr[1], 1.0f);
+					material->set_uv1_scale(scale_vector3);
+				}
 			}
 		}
 	}
 }
 
 void GLTFDocument::spec_gloss_to_rough_metal(Ref<GLTFSpecGloss> r_spec_gloss, Ref<BaseMaterial3D> p_material) {
+	if (r_spec_gloss.is_null()) {
+		return;
+	}
 	if (r_spec_gloss->spec_gloss_img.is_null()) {
 		return;
 	}
 	if (r_spec_gloss->diffuse_img.is_null()) {
 		return;
 	}
+	if (p_material.is_null()) {
+		return;
+	}
 	bool has_roughness = false;
 	bool has_metal = false;
 	p_material->set_roughness(1.0f);
@@ -6657,21 +6669,17 @@ Dictionary _serialize_texture_transform_uv(Vector2 p_offset, Vector2 p_scale) {
 }
 
 Dictionary GLTFDocument::_serialize_texture_transform_uv1(Ref<BaseMaterial3D> p_material) {
-	if (p_material.is_valid()) {
-		Vector3 offset = p_material->get_uv1_offset();
-		Vector3 scale = p_material->get_uv1_scale();
-		return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y));
-	}
-	return Dictionary();
+	ERR_FAIL_NULL_V(p_material, Dictionary());
+	Vector3 offset = p_material->get_uv1_offset();
+	Vector3 scale = p_material->get_uv1_scale();
+	return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y));
 }
 
 Dictionary GLTFDocument::_serialize_texture_transform_uv2(Ref<BaseMaterial3D> p_material) {
-	if (p_material.is_valid()) {
-		Vector3 offset = p_material->get_uv2_offset();
-		Vector3 scale = p_material->get_uv2_scale();
-		return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y));
-	}
-	return Dictionary();
+	ERR_FAIL_NULL_V(p_material, Dictionary());
+	Vector3 offset = p_material->get_uv2_offset();
+	Vector3 scale = p_material->get_uv2_scale();
+	return _serialize_texture_transform_uv(Vector2(offset.x, offset.y), Vector2(scale.x, scale.y));
 }
 
 Error GLTFDocument::_serialize_version(Ref<GLTFState> state) {

+ 2 - 2
modules/gltf/gltf_state.cpp

@@ -209,11 +209,11 @@ void GLTFState::set_meshes(TypedArray<GLTFMesh> p_meshes) {
 	GLTFTemplateConvert::set_from_array(meshes, p_meshes);
 }
 
-TypedArray<BaseMaterial3D> GLTFState::get_materials() {
+TypedArray<Material> GLTFState::get_materials() {
 	return GLTFTemplateConvert::to_array(materials);
 }
 
-void GLTFState::set_materials(TypedArray<BaseMaterial3D> p_materials) {
+void GLTFState::set_materials(TypedArray<Material> p_materials) {
 	GLTFTemplateConvert::set_from_array(materials, p_materials);
 }
 

+ 4 - 4
modules/gltf/gltf_state.h

@@ -72,8 +72,8 @@ class GLTFState : public Resource {
 	Vector<Ref<GLTFMesh>> meshes; // meshes are loaded directly, no reason not to.
 
 	Vector<AnimationPlayer *> animation_players;
-	HashMap<Ref<BaseMaterial3D>, GLTFMaterialIndex> material_cache;
-	Vector<Ref<BaseMaterial3D>> materials;
+	HashMap<Ref<Material>, GLTFMaterialIndex> material_cache;
+	Vector<Ref<Material>> materials;
 
 	String scene_name;
 	Vector<int> root_nodes;
@@ -138,8 +138,8 @@ public:
 	TypedArray<GLTFMesh> get_meshes();
 	void set_meshes(TypedArray<GLTFMesh> p_meshes);
 
-	TypedArray<BaseMaterial3D> get_materials();
-	void set_materials(TypedArray<BaseMaterial3D> p_materials);
+	TypedArray<Material> get_materials();
+	void set_materials(TypedArray<Material> p_materials);
 
 	String get_scene_name();
 	void set_scene_name(String p_scene_name);