/// <summary>
        /// Converts the given GLTF 2 material to a Unity Material.
        /// This is "best effort": we only interpret SOME, but not all GLTF material parameters.
        /// We try to be robust, and will always try to return *some* material rather than fail,
        /// even if crucial fields are missing or can't be parsed.
        /// </summary>
        /// <param name="gltfMat">The GLTF 2 material to convert.</param>
        /// <returns>The result of the conversion</returns>
        private UnityMaterial?ConvertGltf2Material(Gltf2Material gltfMat)
        {
            Material baseMaterial; {
                string alphaMode = gltfMat.alphaMode == null ? null : gltfMat.alphaMode.ToUpperInvariant();

                switch (alphaMode)
                {
                case Gltf2Material.kAlphaModeOpaque:
                    baseMaterial = gltfMat.doubleSided
            ? TbtSettings.Instance.m_BasePbrOpaqueDoubleSidedMaterial
            : TbtSettings.Instance.m_BasePbrOpaqueSingleSidedMaterial;
                    break;

                case Gltf2Material.kAlphaModeBlend:
                    baseMaterial = gltfMat.doubleSided
            ? TbtSettings.Instance.m_BasePbrBlendDoubleSidedMaterial
            : TbtSettings.Instance.m_BasePbrBlendSingleSidedMaterial;
                    break;

                default:
                    Debug.LogWarning($"Not yet supported: alphaMode={alphaMode}");
                    goto case Gltf2Material.kAlphaModeOpaque;
                }
            }

            if (gltfMat.pbrMetallicRoughness == null)
            {
                Debug.LogWarningFormat("Material #{0} has no PBR info.", gltfMat.gltfIndex);
                return(null);
            }

            return(CreateNewPbrMaterial(baseMaterial, gltfMat.name, gltfMat.pbrMetallicRoughness));
        }
        /// <summary>
        /// Converts the given GLTF 2 material to a Unity Material.
        /// This is "best effort": we only interpret SOME, but not all GLTF material parameters.
        /// We try to be robust, and will always try to return *some* material rather than fail,
        /// even if crucial fields are missing or can't be parsed.
        /// </summary>
        /// <param name="gltfMat">The GLTF 2 material to convert.</param>
        /// <returns>The result of the conversion</returns>
        private UnityMaterial?ConvertGltf2Material(Gltf2Material gltfMat)
        {
            TbtSettings.PbrMaterialInfo pbrInfo;

            string alphaMode = gltfMat.alphaMode == null ? null : gltfMat.alphaMode.ToUpperInvariant();

            switch (alphaMode)
            {
            case null:
            case "":
            case Gltf2Material.kAlphaModeOpaque:
                pbrInfo = gltfMat.doubleSided
            ? TbtSettings.Instance.m_PbrOpaqueDoubleSided
            : TbtSettings.Instance.m_PbrOpaqueSingleSided;
                break;

            case Gltf2Material.kAlphaModeBlend:
                pbrInfo = gltfMat.doubleSided
            ? TbtSettings.Instance.m_PbrBlendDoubleSided
            : TbtSettings.Instance.m_PbrBlendSingleSided;
                break;

            default:
                Debug.LogWarning($"Not yet supported: alphaMode={alphaMode}");
                goto case Gltf2Material.kAlphaModeOpaque;
            }

            if (gltfMat.pbrMetallicRoughness == null)
            {
                var specGloss = gltfMat.extensions?.KHR_materials_pbrSpecularGlossiness;
                if (specGloss != null)
                {
                    // Try and make the best of pbrSpecularGlossiness.
                    // Maybe it would be better to support "extensionsRequired" and raise an error
                    // if the asset requires pbrSpecularGlossiness.
                    gltfMat.pbrMetallicRoughness = new Gltf2Material.PbrMetallicRoughness {
                        baseColorFactor  = specGloss.diffuseFactor,
                        baseColorTexture = specGloss.diffuseTexture,
                        roughnessFactor  = 1f - specGloss.glossinessFactor
                    };
                }
                else
                {
                    Debug.LogWarningFormat("Material #{0} has no PBR info.", gltfMat.gltfIndex);
                    return(null);
                }
            }

            return(CreateNewPbrMaterial(pbrInfo, gltfMat.name, gltfMat.pbrMetallicRoughness));
        }
示例#3
0
        /// <summary>
        /// Converts the given GLTF 2 material to a Unity Material.
        /// This is "best effort": we only interpret SOME, but not all GLTF material parameters.
        /// We try to be robust, and will always try to return *some* material rather than fail,
        /// even if crucial fields are missing or can't be parsed.
        /// </summary>
        /// <param name="gltfMat">The GLTF 2 material to convert.</param>
        /// <returns>The result of the conversion</returns>
        private UnityMaterial?ConvertGltf2Material(Gltf2Material gltfMat)
        {
            TbtSettings.PbrMaterialInfo pbrInfo;

#if TILT_BRUSH
            if (!gltfMat.doubleSided)
            {
                // TBT supports importing single-sided materials, forcing TB to try.
                // TB will import them but can't export single-sided because it lacks single-sided BD.
                // Single-sided BD
                // TB's copy of TbtSettings uses our double-sided BrushDescriptor for these single-sided
                // materials, so they'll export as double-sided.
                // TODO: create single-sided BrushDescriptors, push out to TBT, PT, Poly, ...
                Debug.LogWarning($"Not fully supported: single-sided");
            }
#endif

            string alphaMode = gltfMat.alphaMode == null ? null : gltfMat.alphaMode.ToUpperInvariant();
            switch (alphaMode)
            {
            case null:
            case "":
            case Gltf2Material.kAlphaModeOpaque:
                pbrInfo = gltfMat.doubleSided
            ? TbtSettings.Instance.m_PbrOpaqueDoubleSided
            : TbtSettings.Instance.m_PbrOpaqueSingleSided;
                break;

            case Gltf2Material.kAlphaModeBlend:
                pbrInfo = gltfMat.doubleSided
            ? TbtSettings.Instance.m_PbrBlendDoubleSided
            : TbtSettings.Instance.m_PbrBlendSingleSided;
                break;

            default:
                Debug.LogWarning($"Not yet supported: alphaMode={alphaMode}");
                goto case Gltf2Material.kAlphaModeOpaque;
            }

            if (gltfMat.pbrMetallicRoughness == null)
            {
                var specGloss = gltfMat.extensions?.KHR_materials_pbrSpecularGlossiness;
                if (specGloss != null)
                {
                    // Try and make the best of pbrSpecularGlossiness.
                    // Maybe it would be better to support "extensionsRequired" and raise an error
                    // if the asset requires pbrSpecularGlossiness.
                    gltfMat.pbrMetallicRoughness = new Gltf2Material.PbrMetallicRoughness {
                        baseColorFactor  = specGloss.diffuseFactor,
                        baseColorTexture = specGloss.diffuseTexture,
                        roughnessFactor  = 1f - specGloss.glossinessFactor
                    };
                }
                else
                {
                    Debug.LogWarningFormat("Material #{0} has no PBR info.", gltfMat.gltfIndex);
                    return(null);
                }
            }

            return(CreateNewPbrMaterial(pbrInfo, gltfMat.name, gltfMat.pbrMetallicRoughness));
        }
示例#4
0
        /// <summary>
        /// Looks up a built-in global material that corresponds to the given GLTF material.
        /// This will NOT create new materials; it will only look up global ones.
        /// </summary>
        /// <param name="gltfMaterial">The material to look up.</param>
        /// <param name="materialGuid">The guid parsed from the material name, or Guid.None</param>
        /// <returns>The global material that corresponds to the given GLTF material,
        /// if found. If not found, null.</returns>
        private static UnityMaterial?LookUpGlobalMaterial(GltfMaterialBase gltfMaterial)
        {
#if TILT_BRUSH
            // Is this a Gltf1 blocks material?
            if (gltfMaterial.TechniqueExtras != null)
            {
                string surfaceShader = null;
                gltfMaterial.TechniqueExtras.TryGetValue("gvrss", out surfaceShader);

                if (surfaceShader != null)
                {
                    // Blocks material. Look up the mapping in TbtSettings.
                    if (TbtSettings.Instance.LookupSurfaceShaderMaterial(surfaceShader) is UnityMaterial um)
                    {
                        return(um);
                    }
                    else
                    {
                        Debug.LogWarningFormat("Unknown gvrss surface shader {0}", surfaceShader);
                    }
                }
            }

            // This method of building Guid from a name is flimsy, and proven so by b/109698832.
            // As a patch fix, look specifically for Blocks material names.

            // Is this a Gltf2 Blocks material?
            Gltf2Material gltf2 = gltfMaterial as Gltf2Material;
            if (gltf2 != null)
            {
                if (gltfMaterial.name != null)
                {
                    string url = "https://vr.google.com/shaders/w/gvrss/";
                    if (gltfMaterial.name.Equals("BlocksGem"))
                    {
                        return(TbtSettings.Instance.LookupSurfaceShaderMaterial(url + "gem.json"));
                    }
                    if (gltfMaterial.name.Equals("BlocksGlass"))
                    {
                        return(TbtSettings.Instance.LookupSurfaceShaderMaterial(url + "glass.json"));
                    }
                    if (gltfMaterial.name.Equals("BlocksPaper"))
                    {
                        return(TbtSettings.Instance.LookupSurfaceShaderMaterial(url + "paper.json"));
                    }
                }
            }
#endif

            // Check if it's a Tilt Brush material.
            Guid guid = ParseGuidFromMaterial(gltfMaterial);
            if (guid != Guid.Empty)
            {
                // Tilt Brush global material. PBR materials will use unrecognized guids;
                // these will be handled by the caller.
                BrushDescriptor desc;
                if (TbtSettings.Instance.TryGetBrush(guid, out desc))
                {
                    return(new UnityMaterial {
                        material = desc.Material,
#if TILT_BRUSH
                        exportableMaterial = desc,
#endif
                        template = desc.Material
                    });
                }
            }
            return(null);
        }
示例#5
0
 /// Map gltfIndex values (ie, int indices) names to the objects they refer to
 public override void Dereference(IUriLoader uriLoader = null, PolyFormat gltfFormat = null)
 {
     // "dereference" all the indices
     scenePtr = scenes[scene];
     for (int i = 0; i < buffers.Count; i++)
     {
         Gltf2Buffer buffer = buffers[i];
         buffer.gltfIndex = i;
         if (uriLoader != null)
         {
             // Only id 0 may lack a URI; this indicates that it is the binary chunk.
             Debug.Assert(!(i != 0 && buffer.uri == null));
             buffer.data = uriLoader.Load(buffer.uri);
         }
         else if (gltfFormat != null)
         {
             // Runtime import case; the uris refer to resource files in the PolyFormat.
             foreach (PolyFile resource in gltfFormat.resources)
             {
                 if (resource.relativePath == buffer.uri)
                 {
                     buffer.data = new Reader(resource.contents);
                     break;
                 }
             }
         }
     }
     for (int i = 0; i < accessors.Count; i++)
     {
         accessors[i].gltfIndex     = i;
         accessors[i].bufferViewPtr = bufferViews[accessors[i].bufferView];
     }
     for (int i = 0; i < bufferViews.Count; i++)
     {
         bufferViews[i].gltfIndex = i;
         bufferViews[i].bufferPtr = buffers[bufferViews[i].buffer];
     }
     for (int i = 0; i < meshes.Count; i++)
     {
         meshes[i].gltfIndex = i;
         foreach (var prim in meshes[i].primitives)
         {
             prim.attributePtrs = prim.attributes.ToDictionary(
                 elt => elt.Key,
                 elt => accessors[elt.Value]);
             prim.indicesPtr  = accessors[prim.indices];
             prim.materialPtr = materials[prim.material];
         }
     }
     if (images != null)
     {
         for (int i = 0; i < images.Count; i++)
         {
             images[i].gltfIndex = i;
         }
     }
     if (textures != null)
     {
         for (int i = 0; i < textures.Count; i++)
         {
             textures[i].gltfIndex = i;
             textures[i].sourcePtr = images[textures[i].source];
         }
     }
     for (int i = 0; i < materials.Count; i++)
     {
         Gltf2Material mat = materials[i];
         mat.gltfIndex = i;
         DereferenceTextureInfo(mat.emissiveTexture);
         DereferenceTextureInfo(mat.normalTexture);
         if (mat.pbrMetallicRoughness != null)
         {
             DereferenceTextureInfo(mat.pbrMetallicRoughness.baseColorTexture);
             DereferenceTextureInfo(mat.pbrMetallicRoughness.metallicRoughnessTexture);
         }
     }
     for (int i = 0; i < nodes.Count; i++)
     {
         nodes[i].gltfIndex = i;
         Gltf2Node node = nodes[i];
         if (node.mesh >= 0)
         {
             node.meshPtr = meshes[node.mesh];
         }
         if (node.children != null)
         {
             node.childPtrs = node.children.Select(id => nodes[id]).ToList();
         }
     }
     for (int i = 0; i < scenes.Count; i++)
     {
         scenes[i].gltfIndex = i;
         var thisScene = scenes[i];
         if (thisScene.nodes != null)
         {
             thisScene.nodePtrs = thisScene.nodes.Select(index => nodes[index]).ToList();
         }
     }
 }
示例#6
0
        /// Map gltfIndex values (ie, int indices) names to the objects they refer to
        public override void Dereference(bool isGlb, IUriLoader uriLoader = null)
        {
            // "dereference" all the indices
            scenePtr = scenes[scene];
            for (int i = 0; i < buffers.Count; i++)
            {
                Gltf2Buffer buffer = buffers[i];
                buffer.gltfIndex = i;
                if (buffer.uri == null && !(i == 0 && isGlb))
                {
                    Debug.LogErrorFormat("Buffer {0} isGlb {1} has null uri", i, isGlb);
                    // leave the data buffer null
                    return;
                }

                if (uriLoader != null)
                {
                    buffer.data = uriLoader.Load(buffer.uri);
                }
            }
            for (int i = 0; i < accessors.Count; i++)
            {
                accessors[i].gltfIndex     = i;
                accessors[i].bufferViewPtr = bufferViews[accessors[i].bufferView];
            }
            for (int i = 0; i < bufferViews.Count; i++)
            {
                bufferViews[i].gltfIndex = i;
                bufferViews[i].bufferPtr = buffers[bufferViews[i].buffer];
            }
            for (int i = 0; i < meshes.Count; i++)
            {
                meshes[i].gltfIndex = i;
                foreach (var prim in meshes[i].primitives)
                {
                    prim.attributePtrs = prim.attributes.ToDictionary(
                        elt => elt.Key,
                        elt => accessors[elt.Value]);
                    prim.indicesPtr  = accessors[prim.indices];
                    prim.materialPtr = materials[prim.material];
                }
            }
            if (images != null)
            {
                for (int i = 0; i < images.Count; i++)
                {
                    images[i].gltfIndex = i;
                }
            }
            if (textures != null)
            {
                for (int i = 0; i < textures.Count; i++)
                {
                    textures[i].gltfIndex = i;
                    textures[i].sourcePtr = images[textures[i].source];
                }
            }
            for (int i = 0; i < materials.Count; i++)
            {
                Gltf2Material mat = materials[i];
                mat.gltfIndex = i;
                DereferenceTextureInfo(mat.emissiveTexture);
                DereferenceTextureInfo(mat.normalTexture);
                if (mat.pbrMetallicRoughness != null)
                {
                    DereferenceTextureInfo(mat.pbrMetallicRoughness.baseColorTexture);
                    DereferenceTextureInfo(mat.pbrMetallicRoughness.metallicRoughnessTexture);
                }
                DereferenceTextureInfo(mat.extensions?.KHR_materials_pbrSpecularGlossiness?.diffuseTexture);
            }
            for (int i = 0; i < nodes.Count; i++)
            {
                nodes[i].gltfIndex = i;
                Gltf2Node node = nodes[i];
                if (node.mesh >= 0)
                {
                    node.meshPtr = meshes[node.mesh];
                }
                if (node.children != null)
                {
                    node.childPtrs = node.children.Select(id => nodes[id]).ToList();
                }
            }
            for (int i = 0; i < scenes.Count; i++)
            {
                scenes[i].gltfIndex = i;
                var thisScene = scenes[i];
                if (thisScene.nodes != null)
                {
                    thisScene.nodePtrs = thisScene.nodes.Select(index => nodes[index]).ToList();
                }
            }
        }