private static async Task ConstructMaterialAsync(this GltfObject gltfObject, GltfMaterial gltfMaterial, int materialId) { if (gltfObject.UseBackgroundThread) { await Update; } Material material = await CreateMRTKShaderMaterial(gltfObject, gltfMaterial, materialId); if (material == null) { Debug.LogWarning("The Mixed Reality Toolkit/Standard Shader was not found. Falling back to Standard Shader"); material = await CreateStandardShaderMaterial(gltfObject, gltfMaterial, materialId); } if (material == null) { Debug.LogWarning("The Standard Shader was not found. Failed to create material for glTF object"); } else { gltfMaterial.Material = material; } if (gltfObject.UseBackgroundThread) { await BackgroundThread; } }
static void LoadCommonParams(this Material self, GltfMaterial material, List <Texture> textures) { var pbr = material.pbrMetallicRoughness; if (pbr != null) { if (pbr.baseColorFactor != null) { self.BaseColorFactor = LinearColor.FromLiner( pbr.baseColorFactor[0], pbr.baseColorFactor[1], pbr.baseColorFactor[2], pbr.baseColorFactor[3]); } var baseColorTexture = pbr.baseColorTexture; if (baseColorTexture != null) { self.BaseColorTexture = new TextureInfo(textures[baseColorTexture.index]); } } self.AlphaMode = (VrmLib.AlphaModeType)material.alphaMode; self.AlphaCutoff = material.alphaCutoff; self.DoubleSided = material.doubleSided; }
private Material readMaterial(int index) { if (_materialMap.TryGetValue(index, out Material material)) { return(material); } GltfMaterial gltfMaterial = _root.Materials[index]; material = new Material(gltfMaterial.Name); _materialMap.Add(index, material); //TODO: implement gltf material reader if (gltfMaterial.PbrMetallicRoughness != null) { byte r = (byte)(gltfMaterial.PbrMetallicRoughness.BaseColorFactor[0] * 255); byte g = (byte)(gltfMaterial.PbrMetallicRoughness.BaseColorFactor[1] * 255); byte b = (byte)(gltfMaterial.PbrMetallicRoughness.BaseColorFactor[2] * 255); byte a = (byte)(gltfMaterial.PbrMetallicRoughness.BaseColorFactor[3] * 255); material.AmbientColor = new Color(r, g, b, a); material.DiffuseColor = new Color(r, g, b, a); material.SpecularColor = new Color(r, g, b, a); } return(material); }
public static UnlitMaterial UnlitFromGltf(GltfMaterial material, List <Texture> textures) { var unlit = new UnlitMaterial(material.name); unlit.LoadCommonParams(material, textures); return(unlit); }
public static Material FromGltf(this GltfMaterial x, List <Texture> textures) { return(x.IsUnlit() ? (Material)UnlitFromGltf(x, textures) : (Material)PBRFromGltf(x, textures) ); }
static GltfImage GetNormalImage(GltfSerialization.GltfStorage storage, GltfMaterial m) { if (m.normalTexture == null) { return(null); } return(GetTexture(storage, m.normalTexture.index)); }
public static PBRMaterial PBRFromGltf(GltfMaterial material, List <Texture> textures) { var self = new PBRMaterial(material.name); self.LoadCommonParams(material, textures); // // pbr // var pbr = material.pbrMetallicRoughness; // metallic roughness self.MetallicFactor = pbr.metallicFactor; self.RoughnessFactor = pbr.roughnessFactor; var metallicRoughnessTexture = pbr.metallicRoughnessTexture; if (metallicRoughnessTexture != null) { self.MetallicRoughnessTexture = textures[metallicRoughnessTexture.index]; } // // emissive // if (material.emissiveFactor != null) { self.EmissiveFactor = new Vector3( material.emissiveFactor[0], material.emissiveFactor[1], material.emissiveFactor[2]); } var emissiveTexture = material.emissiveTexture; if (emissiveTexture != null) { self.EmissiveTexture = textures[emissiveTexture.index]; } // // normal // var normalTexture = material.normalTexture; if (normalTexture != null) { self.NormalTexture = textures[normalTexture.index]; } // // occlusion // var occlusionTexture = material.occlusionTexture; if (occlusionTexture != null) { self.OcclusionTexture = textures[occlusionTexture.index]; } return(self); }
static GltfImage GetColorImage(GltfSerialization.GltfStorage storage, GltfMaterial m) { if (m.pbrMetallicRoughness == null) { return(null); } if (m.pbrMetallicRoughness.baseColorTexture == null) { return(null); } return(GetTexture(storage, m.pbrMetallicRoughness.baseColorTexture.index)); }
/// Glb interface. bin is binary chunk public GltfStorage(FileInfo path, ArraySegment <byte> json, Memory <byte> bin) { OriginalJson = json; Gltf = Generated.GltfDeserializer.Deserialize(json.ParseAsJson()); Path = path; Json = new Utf8String(json); if (!bin.IsEmpty) { // glb MemoryMarshal.TryGetArray(bin, out ArraySegment <byte> segment); Buffers.Add(new SimpleBuffer(segment)); } else { // gltf var baseDir = path.Directory.FullName; Buffers.AddRange(Gltf.buffers.Select(x => new UriByteBuffer(baseDir, x.uri))); } if (Gltf.extensions != null && Gltf.extensions.VRM != null) { // VRM if (Gltf.extensions.VRM.humanoid != null) { Gltf.extensions.VRM.humanoid.humanBones = Gltf.extensions.VRM.humanoid.humanBones.OrderBy(x => x.bone).ToList(); } } if (!Gltf.materials.Any()) { // default material Gltf.materials.Add(GltfMaterial.CreateDefault("__default__")); } }
private static async Task ConstructMaterialAsync(this GltfObject gltfObject, GltfMaterial gltfMaterial, int materialId) { if (Application.isPlaying) { await Update; } Shader shader = Shader.Find("Standard"); if (shader == null) { Debug.LogWarning("No Standard shader found. Falling back to Legacy Diffuse"); shader = Shader.Find("Legacy Shaders/Diffuse"); } var material = new Material(shader) { name = string.IsNullOrEmpty(gltfMaterial.name) ? $"Gltf Material {materialId}" : gltfMaterial.name }; if (gltfMaterial.pbrMetallicRoughness.baseColorTexture.index >= 0) { material.mainTexture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.baseColorTexture.index].Texture; } material.color = gltfMaterial.pbrMetallicRoughness.baseColorFactor.GetColorValue(); if (shader.name == "Standard") { if (gltfMaterial.alphaMode == "MASK") { material.SetInt(SrcBlend, (int)BlendMode.One); material.SetInt(DstBlend, (int)BlendMode.Zero); material.SetInt(ZWrite, 1); material.SetInt(Mode, 3); material.SetOverrideTag("RenderType", "Cutout"); material.EnableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 2450; } else if (gltfMaterial.alphaMode == "BLEND") { material.SetInt(SrcBlend, (int)BlendMode.One); material.SetInt(DstBlend, (int)BlendMode.OneMinusSrcAlpha); material.SetInt(ZWrite, 0); material.SetInt(Mode, 3); material.SetOverrideTag("RenderType", "Transparency"); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 3000; } } if (gltfMaterial.emissiveTexture.index >= 0 && material.HasProperty("_EmissionMap")) { material.EnableKeyword("_EmissionMap"); material.EnableKeyword("_EMISSION"); material.SetTexture(EmissionMap, gltfObject.images[gltfMaterial.emissiveTexture.index].Texture); material.SetColor(EmissionColor, gltfMaterial.emissiveFactor.GetColorValue()); } if (gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index >= 0 && material.HasProperty("_MetallicGlossMap")) { var texture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index].Texture; if (texture.isReadable) { var pixels = texture.GetPixels(); if (Application.isPlaying) { await BackgroundThread; } var pixelCache = new Color[pixels.Length]; for (int c = 0; c < pixels.Length; c++) { // Unity only looks for metal in R channel, and smoothness in A. pixelCache[c].r = pixels[c].g; pixelCache[c].g = 0f; pixelCache[c].b = 0f; pixelCache[c].a = pixels[c].b; } if (Application.isPlaying) { await Update; } texture.SetPixels(pixelCache); texture.Apply(); material.SetTexture(MetallicGlossMap, gltfObject.images[gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index].Texture); } material.SetFloat(Glossiness, Mathf.Abs((float)gltfMaterial.pbrMetallicRoughness.roughnessFactor - 1f)); material.SetFloat(Metallic, (float)gltfMaterial.pbrMetallicRoughness.metallicFactor); material.EnableKeyword("_MetallicGlossMap"); material.EnableKeyword("_METALLICGLOSSMAP"); } if (gltfMaterial.normalTexture.index >= 0 && material.HasProperty("_BumpMap")) { material.SetTexture(BumpMap, gltfObject.images[gltfMaterial.normalTexture.index].Texture); material.EnableKeyword("_BumpMap"); } material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.RealtimeEmissive; gltfMaterial.Material = material; if (Application.isPlaying) { await BackgroundThread; } }
private static async Task <Material> CreateStandardShaderMaterial(GltfObject gltfObject, GltfMaterial gltfMaterial, int materialId) { var shader = Shader.Find("Standard"); if (shader == null) { return(null); } var material = new Material(shader) { name = string.IsNullOrEmpty(gltfMaterial.name) ? $"glTF Material {materialId}" : gltfMaterial.name }; if (gltfMaterial.pbrMetallicRoughness.baseColorTexture.index >= 0) { material.mainTexture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.baseColorTexture.index].Texture; } material.color = gltfMaterial.pbrMetallicRoughness.baseColorFactor.GetColorValue(); if (gltfMaterial.alphaMode == "MASK") { material.SetInt(SrcBlendId, (int)BlendMode.One); material.SetInt(DstBlendId, (int)BlendMode.Zero); material.SetInt(ZWriteId, 1); material.SetInt(ModeId, 3); material.SetOverrideTag("RenderType", "Cutout"); material.EnableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 2450; } else if (gltfMaterial.alphaMode == "BLEND") { material.SetInt(SrcBlendId, (int)BlendMode.One); material.SetInt(DstBlendId, (int)BlendMode.OneMinusSrcAlpha); material.SetInt(ZWriteId, 0); material.SetInt(ModeId, 3); material.SetOverrideTag("RenderType", "Transparency"); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 3000; } if (gltfMaterial.emissiveTexture.index >= 0) { material.EnableKeyword("_EmissionMap"); material.EnableKeyword("_EMISSION"); material.SetTexture(EmissionMapId, gltfObject.images[gltfMaterial.emissiveTexture.index].Texture); material.SetColor(EmissionColorId, gltfMaterial.emissiveFactor.GetColorValue()); } if (gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index >= 0) { var texture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index].Texture; if (texture.isReadable) { var pixels = texture.GetPixels(); if (gltfObject.UseBackgroundThread) { await BackgroundThread; } var pixelCache = new Color[pixels.Length]; for (int c = 0; c < pixels.Length; c++) { // Unity only looks for metal in R channel, and smoothness in A. pixelCache[c].r = pixels[c].g; pixelCache[c].g = 0f; pixelCache[c].b = 0f; pixelCache[c].a = pixels[c].b; } if (gltfObject.UseBackgroundThread) { await Update; } texture.SetPixels(pixelCache); texture.Apply(); material.SetTexture(MetallicGlossMapId, texture); } material.SetFloat(GlossinessId, Mathf.Abs((float)gltfMaterial.pbrMetallicRoughness.roughnessFactor - 1f)); material.SetFloat(MetallicId, (float)gltfMaterial.pbrMetallicRoughness.metallicFactor); material.EnableKeyword("_MetallicGlossMap"); material.EnableKeyword("_METALLICGLOSSMAP"); } if (gltfMaterial.normalTexture.index >= 0) { material.SetTexture(BumpMapId, gltfObject.images[gltfMaterial.normalTexture.index].Texture); material.EnableKeyword("_BumpMap"); } material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.RealtimeEmissive; return(material); }
private static async Task <Material> CreateMRTKShaderMaterial(GltfObject gltfObject, GltfMaterial gltfMaterial, int materialId) { var shader = Shader.Find("Mixed Reality Toolkit/Standard"); if (shader == null) { return(null); } var material = new Material(shader) { name = string.IsNullOrEmpty(gltfMaterial.name) ? $"glTF Material {materialId}" : gltfMaterial.name }; if (gltfMaterial.pbrMetallicRoughness.baseColorTexture.index >= 0) { material.mainTexture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.baseColorTexture.index].Texture; } material.color = gltfMaterial.pbrMetallicRoughness.baseColorFactor.GetColorValue(); if (gltfMaterial.alphaMode == "MASK") { material.SetInt(SrcBlendId, (int)BlendMode.One); material.SetInt(DstBlendId, (int)BlendMode.Zero); material.SetInt(ZWriteId, 1); material.SetInt(ModeId, 3); material.SetOverrideTag("RenderType", "Cutout"); material.EnableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 2450; } else if (gltfMaterial.alphaMode == "BLEND") { material.SetInt(SrcBlendId, (int)BlendMode.One); material.SetInt(DstBlendId, (int)BlendMode.OneMinusSrcAlpha); material.SetInt(ZWriteId, 0); material.SetInt(ModeId, 3); material.SetOverrideTag("RenderType", "Transparency"); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 3000; } if (gltfMaterial.emissiveTexture.index >= 0 && material.HasProperty("_EmissionMap")) { material.EnableKeyword("_EMISSION"); material.SetColor(EmissiveColorId, gltfMaterial.emissiveFactor.GetColorValue()); } if (gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index >= 0) { var texture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index].Texture; Texture2D occlusionTexture = null; if (gltfMaterial.occlusionTexture.index >= 0) { occlusionTexture = gltfObject.images[gltfMaterial.occlusionTexture.index].Texture; } if (texture.isReadable) { var pixels = texture.GetPixels(); Color[] occlusionPixels = null; if (occlusionTexture != null && occlusionTexture.isReadable) { occlusionPixels = occlusionTexture.GetPixels(); } if (gltfObject.UseBackgroundThread) { await BackgroundThread; } var pixelCache = new Color[pixels.Length]; for (int c = 0; c < pixels.Length; c++) { pixelCache[c].r = pixels[c].b; // MRTK standard shader metallic value, glTF metallic value pixelCache[c].g = occlusionPixels?[c].r ?? 1.0f; // MRTK standard shader occlusion value, glTF occlusion value if available pixelCache[c].b = 0f; // MRTK standard shader emission value pixelCache[c].a = (1.0f - pixels[c].g); // MRTK standard shader smoothness value, invert of glTF roughness value } if (gltfObject.UseBackgroundThread) { await Update; } texture.SetPixels(pixelCache); texture.Apply(); material.SetTexture(ChannelMapId, texture); material.EnableKeyword("_CHANNEL_MAP"); } else { material.DisableKeyword("_CHANNEL_MAP"); } material.SetFloat(SmoothnessId, Mathf.Abs((float)gltfMaterial.pbrMetallicRoughness.roughnessFactor - 1f)); material.SetFloat(MetallicId, (float)gltfMaterial.pbrMetallicRoughness.metallicFactor); } if (gltfMaterial.normalTexture.index >= 0) { material.SetTexture(NormalMapId, gltfObject.images[gltfMaterial.normalTexture.index].Texture); material.SetFloat(NormalMapScaleId, (float)gltfMaterial.normalTexture.scale); material.EnableKeyword("_NORMAL_MAP"); } if (gltfMaterial.doubleSided) { material.SetFloat(CullModeId, (float)UnityEngine.Rendering.CullMode.Off); } material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.RealtimeEmissive; return(material); }
private static void ConstructMaterial(this GltfObject gltfObject, GltfMaterial gltfMaterial, int materialId) { Shader shader = Shader.Find("Standard"); if (shader == null) { Debug.LogWarning("No Standard shader found. Falling back to Legacy Diffuse"); shader = Shader.Find("Legacy Shaders/Diffuse"); } var material = new Material(shader) { name = string.IsNullOrEmpty(gltfMaterial.name) ? $"Gltf Material {materialId}" : gltfMaterial.name }; if (gltfMaterial.pbrMetallicRoughness.baseColorTexture.index >= 0) { material.mainTexture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.baseColorTexture.index].Texture; } material.color = gltfMaterial.pbrMetallicRoughness.baseColorFactor.GetColorValue(); if (shader.name == "Standard") { if (gltfMaterial.alphaMode == "MASK") { material.SetInt("_SrcBlend", (int)BlendMode.One); material.SetInt("_DstBlend", (int)BlendMode.Zero); material.SetInt("_ZWrite", 1); material.SetInt("_Mode", 3); material.SetOverrideTag("RenderType", "Cutout"); material.EnableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 2450; } else if (gltfMaterial.alphaMode == "BLEND") { material.SetInt("_SrcBlend", (int)BlendMode.One); material.SetInt("_DstBlend", (int)BlendMode.OneMinusSrcAlpha); material.SetInt("_ZWrite", 0); material.SetInt("_Mode", 3); material.SetOverrideTag("RenderType", "Transparency"); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); material.renderQueue = 3000; } } if (material.HasProperty("_MetallicGlossMap")) { // TODO if using extension handle it appropriately. if (gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index >= 0) { var texture = gltfObject.images[gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index].Texture; var pixels = texture.GetPixels(); var newPixels = new Color[pixels.Length]; for (int c = 0; c < pixels.Length; c++) { // Unity only looks for metal in R channel, and smoothness in A. newPixels[c] = new Color(pixels[c].g, 0f, 0f, pixels[c].b); } texture.SetPixels(newPixels); texture.Apply(); material.SetTexture("_MetallicGlossMap", gltfObject.images[gltfMaterial.pbrMetallicRoughness.metallicRoughnessTexture.index].Texture); } material.SetFloat("_Glossiness", Mathf.Abs((float)gltfMaterial.pbrMetallicRoughness.roughnessFactor - 1f)); material.SetFloat("_Metallic", (float)gltfMaterial.pbrMetallicRoughness.metallicFactor); material.EnableKeyword("_MetallicGlossMap"); } if (gltfMaterial.normalTexture.index >= 0 && material.HasProperty("_BumpMap")) { material.SetTexture("_BumpMap", gltfObject.images[gltfMaterial.normalTexture.index].Texture); material.EnableKeyword("_BumpMap"); material.EnableKeyword("_NORMALMAP"); } if (material.HasProperty("_EmissionMap") && material.HasProperty("_EMISSION")) { var enable = false; if (gltfMaterial.emissiveTexture.index >= 0) { material.SetTexture("_EmissionMap", gltfObject.images[gltfMaterial.emissiveTexture.index].Texture); material.EnableKeyword("_EmissionMap"); enable = true; } var emissiveColor = gltfMaterial.emissiveFactor.GetColorValue(); if (gltfMaterial.emissiveFactor != null && emissiveColor != Color.black) { material.SetColor("_EmissionColor", emissiveColor); enable = true; } if (enable) { material.EnableKeyword("_EMISSION"); } } gltfMaterial.Material = material; }