/// <summary> /// glTF 全体で使うテクスチャーを列挙。 /// </summary> private static IEnumerable <(SubAssetKey, TextureDescriptor)> EnumerateAllTextures(GltfData data) { for (int i = 0; i < data.GLTF.materials.Count; ++i) { foreach (var kv in GltfPbrTextureImporter.EnumerateAllTextures(data, i)) { yield return(kv); } } }
public static bool TryCreateParam(GltfData data, int i, out MaterialDescriptor matDesc) { if (i < 0 || i >= data.GLTF.materials.Count) { matDesc = default; return(false); } var textureSlots = new Dictionary <string, TextureDescriptor>(); var floatValues = new Dictionary <string, float>(); var colors = new Dictionary <string, Color>(); var vectors = new Dictionary <string, Vector4>(); var actions = new List <Action <Material> >(); var src = data.GLTF.materials[i]; var standardTexDesc = default(TextureDescriptor); if (src.pbrMetallicRoughness != null || src.occlusionTexture != null) { if (src.pbrMetallicRoughness.metallicRoughnessTexture != null || src.occlusionTexture != null) { SubAssetKey key; (key, standardTexDesc) = GltfPbrTextureImporter.StandardTexture(data, src); } if (src.pbrMetallicRoughness.baseColorFactor != null && src.pbrMetallicRoughness.baseColorFactor.Length == 4) { // from _Color ! colors.Add("_BaseColor", src.pbrMetallicRoughness.baseColorFactor.ToColor4(ColorSpace.Linear, ColorSpace.sRGB) ); } if (src.pbrMetallicRoughness.baseColorTexture != null && src.pbrMetallicRoughness.baseColorTexture.index != -1) { var(key, textureParam) = GltfPbrTextureImporter.BaseColorTexture(data, src); // from _MainTex ! textureSlots.Add("_BaseMap", textureParam); } if (src.pbrMetallicRoughness.metallicRoughnessTexture != null && src.pbrMetallicRoughness.metallicRoughnessTexture.index != -1) { actions.Add(material => material.EnableKeyword("_METALLICGLOSSMAP")); textureSlots.Add("_MetallicGlossMap", standardTexDesc); // Set 1.0f as hard-coded. See: https://github.com/dwango/UniVRM/issues/212. floatValues.Add("_Metallic", 1.0f); floatValues.Add("_GlossMapScale", 1.0f); // default value is 0.5 ! floatValues.Add("_Smoothness", 1.0f); } else { floatValues.Add("_Metallic", src.pbrMetallicRoughness.metallicFactor); // from _Glossiness ! floatValues.Add("_Smoothness", 1.0f - src.pbrMetallicRoughness.roughnessFactor); } } if (src.normalTexture != null && src.normalTexture.index != -1) { actions.Add(material => material.EnableKeyword("_NORMALMAP")); var(key, textureParam) = GltfPbrTextureImporter.NormalTexture(data, src); textureSlots.Add("_BumpMap", textureParam); floatValues.Add("_BumpScale", src.normalTexture.scale); } if (src.occlusionTexture != null && src.occlusionTexture.index != -1) { textureSlots.Add("_OcclusionMap", standardTexDesc); floatValues.Add("_OcclusionStrength", src.occlusionTexture.strength); } if (src.emissiveFactor != null || (src.emissiveTexture != null && src.emissiveTexture.index != -1)) { actions.Add(material => { material.EnableKeyword("_EMISSION"); material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack; }); if (src.emissiveFactor != null && src.emissiveFactor.Length == 3) { var emissiveFactor = src.emissiveFactor.ToColor3(ColorSpace.Linear, ColorSpace.Linear); if (UniGLTF.glTF_KHR_materials_emissive_strength.TryGet(src.extensions, out UniGLTF.glTF_KHR_materials_emissive_strength emissiveStrength)) { emissiveFactor *= emissiveStrength.emissiveStrength; } else if (UniGLTF.Extensions.VRMC_materials_hdr_emissiveMultiplier.GltfDeserializer.TryGet(src.extensions, out UniGLTF.Extensions.VRMC_materials_hdr_emissiveMultiplier.VRMC_materials_hdr_emissiveMultiplier ex)) { emissiveFactor *= ex.EmissiveMultiplier.Value; } colors.Add("_EmissionColor", emissiveFactor); } if (src.emissiveTexture != null && src.emissiveTexture.index != -1) { var(key, textureParam) = GltfPbrTextureImporter.EmissiveTexture(data, src); textureSlots.Add("_EmissionMap", textureParam); } } actions.Add(material => { BlendMode blendMode = BlendMode.Opaque; // https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980 switch (src.alphaMode) { case "BLEND": blendMode = BlendMode.Fade; material.SetOverrideTag("RenderType", "Transparent"); material.SetInt(SrcBlend, (int)UnityEngine.Rendering.BlendMode.SrcAlpha); material.SetInt(DstBlend, (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.SetInt(ZWrite, 0); material.DisableKeyword("_ALPHATEST_ON"); material.EnableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 3000; break; case "MASK": blendMode = BlendMode.Cutout; material.SetOverrideTag("RenderType", "TransparentCutout"); material.SetInt(SrcBlend, (int)UnityEngine.Rendering.BlendMode.One); material.SetInt(DstBlend, (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt(ZWrite, 1); material.SetFloat(Cutoff, src.alphaCutoff); material.EnableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 2450; break; default: // OPAQUE blendMode = BlendMode.Opaque; material.SetOverrideTag("RenderType", ""); material.SetInt(SrcBlend, (int)UnityEngine.Rendering.BlendMode.One); material.SetInt(DstBlend, (int)UnityEngine.Rendering.BlendMode.Zero); material.SetInt(ZWrite, 1); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = -1; break; } material.SetFloat("_Mode", (float)blendMode); }); matDesc = new MaterialDescriptor( GltfMaterialDescriptorGenerator.GetMaterialName(i, src), ShaderName, null, textureSlots, floatValues, colors, vectors, actions); return(true); }