Пример #1
0
        public static async Awaitable <Texture2D> LoadTextureAsync(glTF gltf, IStorage storage, int textureIndex)
        {
            var imageBytes = await Awaitable.Run(() =>
            {
                var imageIndex = gltf.textures[textureIndex].source;
                var segments   = gltf.GetImageBytes(storage, imageIndex);
                return(ToArray(segments));
            });

            //
            // texture from image(png etc) bytes
            //
            var textureType = TextureIO.GetglTFTextureType(gltf, textureIndex);
            var colorSpace  = TextureIO.GetColorSpace(textureType);
            var isLinear    = colorSpace == RenderTextureReadWrite.Linear;
            var sampler     = gltf.GetSamplerFromTextureIndex(textureIndex);

            var texture = new Texture2D(2, 2, TextureFormat.ARGB32, false, isLinear);

            texture.name = gltf.textures[textureIndex].name;
            if (imageBytes != null)
            {
                texture.LoadImage(imageBytes);
            }
            if (sampler != null)
            {
                TextureSamplerUtil.SetSampler(texture, sampler);
            }
            return(texture);
        }
Пример #2
0
        static BytesWithMime GetBytesWithMime(Texture texture, glTFTextureTypes textureType)
        {
#if UNITY_EDITOR
            var path = UnityPath.FromAsset(texture);
            if (path.IsUnderAssetsFolder)
            {
                if (path.Extension == ".png")
                {
                    return(new BytesWithMime
                    {
                        Bytes = System.IO.File.ReadAllBytes(path.FullPath),
                        Mime = "image/png",
                    });
                }
                if (path.Extension == ".jpg")
                {
                    return(new BytesWithMime
                    {
                        Bytes = System.IO.File.ReadAllBytes(path.FullPath),
                        Mime = "image/jpeg",
                    });
                }
            }
#endif

            return(new BytesWithMime
            {
                Bytes = TextureItem.CopyTexture(texture, TextureIO.GetColorSpace(textureType), null).EncodeToPNG(),
                Mime = "image/png",
            });
        }
Пример #3
0
        public void ProcessOnMainThread(glTF gltf)
        {
            var textureType = TextureIO.GetglTFTextureType(gltf, m_textureIndex);
            var colorSpace  = TextureIO.GetColorSpace(textureType);

            GetOrCreateTexture(colorSpace == RenderTextureReadWrite.Linear);
            SetSampler(gltf);
        }
Пример #4
0
        public virtual (Byte[] bytes, string mine) GetBytesWithMime(Texture texture, glTFTextureTypes textureType)
        {
#if UNITY_EDITOR
            var path = UnityPath.FromAsset(texture);
            if (path.IsUnderAssetsFolder)
            {
                var textureImporter = AssetImporter.GetAtPath(path.Value) as TextureImporter;
                var getSizeMethod   = typeof(TextureImporter).GetMethod("GetWidthAndHeight", BindingFlags.NonPublic | BindingFlags.Instance);
                if (textureImporter != null && getSizeMethod != null)
                {
                    var args = new object[2] {
                        0, 0
                    };
                    getSizeMethod.Invoke(textureImporter, args);
                    var originalWidth  = (int)args[0];
                    var originalHeight = (int)args[1];

                    var originalSize    = Mathf.Max(originalWidth, originalHeight);
                    var requiredMaxSize = textureImporter.maxTextureSize;

                    // Resized exporting if MaxSize setting value is smaller than original image size.
                    if (originalSize > requiredMaxSize)
                    {
                        return
                            (
                            TextureConverter.CopyTexture(texture, GetColorSpace(textureType), null).EncodeToPNG(),
                            "image/png"
                            );
                    }
                }

                if (path.Extension == ".png")
                {
                    return
                        (
                        System.IO.File.ReadAllBytes(path.FullPath),
                        "image/png"
                        );
                }
                if (path.Extension == ".jpg")
                {
                    return
                        (
                        System.IO.File.ReadAllBytes(path.FullPath),
                        "image/jpeg"
                        );
                }
            }
#endif

            return
                (
                TextureConverter.CopyTexture(texture, TextureIO.GetColorSpace(textureType), null).EncodeToPNG(),
                "image/png"
                );
        }
 public IEnumerator ProcessOnMainThreadCoroutine(glTF gltf)
 {
     using (m_textureLoader)
     {
         var textureType = TextureIO.GetglTFTextureType(gltf, m_textureIndex);
         var colorSpace  = TextureIO.GetColorSpace(textureType);
         var isLinear    = colorSpace == RenderTextureReadWrite.Linear;
         yield return(m_textureLoader.ProcessOnMainThread(isLinear, gltf.GetSamplerFromTextureIndex(m_textureIndex)));
     }
 }
Пример #6
0
        public static Task <Texture2D> LoadTaskAsync(UnityPath m_assetPath,
                                                     glTF gltf, int textureIndex)
        {
            var textureType = TextureIO.GetglTFTextureType(gltf, textureIndex);
            var colorSpace  = TextureIO.GetColorSpace(textureType);
            var isLinear    = colorSpace == RenderTextureReadWrite.Linear;
            var sampler     = gltf.GetSamplerFromTextureIndex(textureIndex);

            //
            // texture from assets
            //
            m_assetPath.ImportAsset();
            var importer = m_assetPath.GetImporter <UnityEditor.TextureImporter>();

            if (importer == null)
            {
                Debug.LogWarningFormat("fail to get TextureImporter: {0}", m_assetPath);
            }
            else
            {
                importer.maxTextureSize = 8192;
                importer.sRGBTexture    = !isLinear;
                importer.SaveAndReimport();
            }

            var Texture = m_assetPath.LoadAsset <Texture2D>();

            if (Texture == null)
            {
                Debug.LogWarningFormat("fail to Load Texture2D: {0}", m_assetPath);
            }

            else
            {
                var maxSize = Mathf.Max(Texture.width, Texture.height);

                importer.maxTextureSize
                    = maxSize > 4096 ? 8192 :
                      maxSize > 2048 ? 4096 :
                      maxSize > 1024 ? 2048 :
                      maxSize > 512 ? 1024 :
                      512;

                importer.SaveAndReimport();
            }

            if (sampler != null)
            {
                TextureSamplerUtil.SetSampler(Texture, sampler);
            }

            return(Task.FromResult(Texture));
        }
Пример #7
0
        public static Texture2D Convert(Texture2D texture, glTFTextureTypes textureType, ColorConversion colorConversion, Material convertMaterial)
        {
            var copyTexture = CopyTexture(texture, TextureIO.GetColorSpace(textureType), convertMaterial);

            if (colorConversion != null)
            {
                copyTexture.SetPixels32(copyTexture.GetPixels32().Select(x => colorConversion(x)).ToArray());
                copyTexture.Apply();
            }
            copyTexture.name = texture.name;
            return(copyTexture);
        }
Пример #8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="prop"></param>
        /// <param name="smoothness">used only when converting MetallicRoughness maps</param>
        /// <returns></returns>
        public Texture2D ConvertTexture(string prop, float smoothnessOrRoughness = 1.0f)
        {
            var convertedTexture = Converts.FirstOrDefault(x => x.Key == prop);

            if (convertedTexture.Value != null)
            {
                return(convertedTexture.Value);
            }

            if (prop == "_BumpMap")
            {
                if (Application.isPlaying)
                {
                    var converted = new NormalConverter().GetImportTexture(Texture);
                    m_converts.Add(prop, converted);
                    return(converted);
                }
                else
                {
#if UNITY_EDITOR
                    var textureAssetPath = AssetDatabase.GetAssetPath(Texture);
                    if (!string.IsNullOrEmpty(textureAssetPath))
                    {
                        TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath);
                    }
                    else
                    {
                        Debug.LogWarningFormat("no asset for {0}", Texture);
                    }
#endif
                    return(Texture);
                }
            }

            if (prop == "_MetallicGlossMap")
            {
                var converted = new MetallicRoughnessConverter(smoothnessOrRoughness).GetImportTexture(Texture);
                m_converts.Add(prop, converted);
                return(converted);
            }

            if (prop == "_OcclusionMap")
            {
                var converted = new OcclusionConverter().GetImportTexture(Texture);
                m_converts.Add(prop, converted);
                return(converted);
            }

            return(null);
        }
Пример #9
0
 static BytesWithMime GetBytesWithMime(Texture texture, glTFTextureTypes textureType)
 {
     /*
      #if UNITY_EDITOR
      * var path = UnityPath.FromAsset(texture);
      * if (path.IsUnderAssetsFolder)
      * {
      *  if (path.Extension == ".png")
      *  {
      *      return new BytesWithMime
      *      {
      *          Bytes = System.IO.File.ReadAllBytes(path.FullPath),
      *          Mime = "image/png",
      *      };
      *  }
      * }
      #endif
      */
     return(new BytesWithMime
     {
         Bytes = TextureItem.CopyTexture(texture, TextureIO.GetColorSpace(textureType), null).EncodeToPNG(),
         Mime = "image/png",
     });
 }
Пример #10
0
        public void FromGameObject(glTF gltf, GameObject go, bool useSparseAccessorForMorphTarget = false)
        {
            var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
            var bufferIndex = gltf.AddBuffer(bytesBuffer);

            GameObject tmpParent = null;

            if (go.transform.childCount == 0)
            {
                tmpParent = new GameObject("tmpParent");
                go.transform.SetParent(tmpParent.transform, true);
                go = tmpParent;
            }

            try
            {
                Nodes = go.transform.Traverse()
                        .Skip(1) // exclude root object for the symmetry with the importer
                        .ToList();

                #region Materials and Textures
                Materials = Nodes.SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList();
                var unityTextures = Materials.SelectMany(x => TextureIO.GetTextures(x)).Where(x => x.Texture != null).Distinct().ToList();

                List <Texture> exportTextures = null;
                Textures = unityTextures.Select(y => y.Texture).ToList();
                var materialExporter = CreateMaterialExporter();
                gltf.materials = Materials.Select(x => materialExporter.ExportMaterial(x, Textures, out exportTextures)).ToList();

                for (int i = 0; i < unityTextures.Count; ++i)
                {
                    var unityTexture = unityTextures[i];
                    TextureIO.ExportTexture(gltf, bufferIndex, exportTextures[i], unityTexture.TextureType);
                }
                #endregion


                #region Meshes
                var unityMeshes = Nodes
                                  .Select(x => new MeshWithRenderer
                {
                    Mesh       = x.GetSharedMesh(),
                    Rendererer = x.GetComponent <Renderer>(),
                })
                                  .Where(x =>
                {
                    if (x.Mesh == null)
                    {
                        return(false);
                    }
                    if (x.Rendererer.sharedMaterials == null ||
                        x.Rendererer.sharedMaterials.Length == 0)
                    {
                        return(false);
                    }

                    return(true);
                })
                                  .ToList();
                ExportMeshes(gltf, bufferIndex, unityMeshes, Materials, useSparseAccessorForMorphTarget);
                Meshes = unityMeshes.Select(x => x.Mesh).ToList();
                #endregion

                #region Skins
                var unitySkins = Nodes
                                 .Select(x => x.GetComponent <SkinnedMeshRenderer>()).Where(x =>
                                                                                            x != null &&
                                                                                            x.bones != null &&
                                                                                            x.bones.Length > 0)
                                 .ToList();
                gltf.nodes  = Nodes.Select(x => ExportNode(x, Nodes, unityMeshes.Select(y => y.Mesh).ToList(), unitySkins)).ToList();
                gltf.scenes = new List <gltfScene>
                {
                    new gltfScene
                    {
                        nodes = go.transform.GetChildren().Select(x => Nodes.IndexOf(x)).ToArray(),
                    }
                };

                foreach (var x in unitySkins)
                {
                    var matrices = x.sharedMesh.bindposes.Select(y => y.ReverseZ()).ToArray();
                    var accessor = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE);

                    var skin = new glTFSkin
                    {
                        inverseBindMatrices = accessor,
                        joints   = x.bones.Select(y => Nodes.IndexOf(y)).ToArray(),
                        skeleton = Nodes.IndexOf(x.rootBone),
                    };
                    var skinIndex = gltf.skins.Count;
                    gltf.skins.Add(skin);

                    foreach (var z in Nodes.Where(y => y.Has(x)))
                    {
                        var nodeIndex = Nodes.IndexOf(z);
                        var node      = gltf.nodes[nodeIndex];
                        node.skin = skinIndex;
                    }
                }
                #endregion

#if UNITY_EDITOR
                #region Animations

                var clips     = new List <AnimationClip>();
                var animator  = go.GetComponent <Animator>();
                var animation = go.GetComponent <Animation>();
                if (animator != null)
                {
                    clips = AnimationExporter.GetAnimationClips(animator);
                }
                else if (animation != null)
                {
                    clips = AnimationExporter.GetAnimationClips(animation);
                }

                if (clips.Any())
                {
                    foreach (AnimationClip clip in clips)
                    {
                        var animationWithCurve = AnimationExporter.Export(clip, go.transform, Nodes);

                        foreach (var kv in animationWithCurve.SamplerMap)
                        {
                            var sampler = animationWithCurve.Animation.samplers[kv.Key];

                            var inputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Input);
                            sampler.input = inputAccessorIndex;

                            var outputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Output);
                            sampler.output = outputAccessorIndex;

                            // modify accessors
                            var outputAccessor = gltf.accessors[outputAccessorIndex];
                            var channel        = animationWithCurve.Animation.channels.First(x => x.sampler == kv.Key);
                            switch (glTFAnimationTarget.GetElementCount(channel.target.path))
                            {
                            case 1:
                                outputAccessor.type  = "SCALAR";
                                outputAccessor.count = 1;
                                break;

                            case 3:
                                outputAccessor.type   = "VEC3";
                                outputAccessor.count /= 3;
                                break;

                            case 4:
                                outputAccessor.type   = "VEC4";
                                outputAccessor.count /= 4;
                                break;

                            default:
                                throw new NotImplementedException();
                            }
                        }

                        gltf.animations.Add(animationWithCurve.Animation);
                    }
                }
                #endregion
#endif
            }
            finally
            {
                if (tmpParent != null)
                {
                    tmpParent.transform.GetChild(0).SetParent(null);
                    if (Application.isPlaying)
                    {
                        GameObject.Destroy(tmpParent);
                    }
                    else
                    {
                        GameObject.DestroyImmediate(tmpParent);
                    }
                }
            }
        }
Пример #11
0
        /// StandardShader vaiables
        ///
        /// _Color
        /// _MainTex
        /// _Cutoff
        /// _Glossiness
        /// _Metallic
        /// _MetallicGlossMap
        /// _BumpScale
        /// _BumpMap
        /// _Parallax
        /// _ParallaxMap
        /// _OcclusionStrength
        /// _OcclusionMap
        /// _EmissionColor
        /// _EmissionMap
        /// _DetailMask
        /// _DetailAlbedoMap
        /// _DetailNormalMapScale
        /// _DetailNormalMap
        /// _UVSec
        /// _EmissionScaleUI
        /// _EmissionColorUI
        /// _Mode
        /// _SrcBlend
        /// _DstBlend
        /// _ZWrite
        public virtual Material CreateMaterial(int i, glTFMaterial x)
        {
            var shader = m_shaderStore.GetShader(x);

            Debug.LogFormat("[{0}]{1}", i, shader.name);
            var material = new Material(shader);

            material.name = (x == null || string.IsNullOrEmpty(x.name))
                ? string.Format("material_{0:00}", i)
                : x.name
            ;

            if (x != null)
            {
                if (x.pbrMetallicRoughness != null)
                {
                    if (x.pbrMetallicRoughness.baseColorFactor != null && x.pbrMetallicRoughness.baseColorFactor.Length == 4)
                    {
                        var color = x.pbrMetallicRoughness.baseColorFactor;
                        material.color = new Color(color[0], color[1], color[2], color[3]);
                    }

                    if (x.pbrMetallicRoughness.baseColorTexture != null && x.pbrMetallicRoughness.baseColorTexture.index != -1)
                    {
                        var texture = m_context.GetTexture(x.pbrMetallicRoughness.baseColorTexture.index);
                        if (texture != null)
                        {
                            material.mainTexture = texture.Texture;
                        }
                    }

                    if (x.pbrMetallicRoughness.metallicRoughnessTexture != null && x.pbrMetallicRoughness.metallicRoughnessTexture.index != -1)
                    {
                        material.EnableKeyword("_METALLICGLOSSMAP");
                        var texture = Context.GetTexture(x.pbrMetallicRoughness.metallicRoughnessTexture.index);
                        if (texture != null)
                        {
                            texture.Converted = (new MetallicRoughnessConverter()).GetImportTexture(texture.Texture);
                            material.SetTexture("_MetallicGlossMap", texture.Converted);
                        }
                    }

                    material.SetFloat("_Metallic", x.pbrMetallicRoughness.metallicFactor);
                    material.SetFloat("_Glossiness", 1.0f - x.pbrMetallicRoughness.roughnessFactor);
                }

                if (x.normalTexture != null && x.normalTexture.index != -1)
                {
                    material.EnableKeyword("_NORMALMAP");
                    var texture = Context.GetTexture(x.normalTexture.index);
                    if (texture != null)
                    {
                        if (Application.isPlaying)
                        {
                            texture.Converted = (new NormalConverter()).GetImportTexture(texture.Texture);
                            material.SetTexture("_BumpMap", texture.Converted);
                        }
                        else
                        {
#if UNITY_EDITOR
                            var textureAssetPath = AssetDatabase.GetAssetPath(texture.Texture);
                            if (!string.IsNullOrEmpty(textureAssetPath))
                            {
                                TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath);
                            }
                            else
                            {
                                Debug.LogWarningFormat("no asset for {0}", texture.Texture);
                            }
                            material.SetTexture("_BumpMap", texture.Texture);
#endif
                        }

                        material.SetFloat("_BumpScale", x.normalTexture.scale);
                    }
                }

                if (x.occlusionTexture != null && x.occlusionTexture.index != -1)
                {
                    var texture = Context.GetTexture(x.occlusionTexture.index);
                    if (texture != null)
                    {
                        texture.Converted = (new OcclusionConverter()).GetImportTexture(texture.Texture);
                        material.SetTexture("_OcclusionMap", texture.Converted);
                        material.SetFloat("_OcclusionStrength", x.occlusionTexture.strength);
                    }
                }

                if (x.emissiveFactor != null ||
                    (x.emissiveTexture != null && x.emissiveTexture.index != -1))
                {
                    material.EnableKeyword("_EMISSION");
                    material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;

                    if (x.emissiveFactor != null && x.emissiveFactor.Length == 3)
                    {
                        material.SetColor("_EmissionColor", new Color(x.emissiveFactor[0], x.emissiveFactor[1], x.emissiveFactor[2]));
                    }

                    if (x.emissiveTexture.index != -1)
                    {
                        var texture = Context.GetTexture(x.emissiveTexture.index);
                        if (texture != null)
                        {
                            material.SetTexture("_EmissionMap", texture.Texture);
                        }
                    }
                }

                BlendMode blendMode = BlendMode.Opaque;
                // https://forum.unity.com/threads/standard-material-shader-ignoring-setfloat-property-_mode.344557/#post-2229980
                switch (x.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.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);
            }
            return(material);
        }
Пример #12
0
        /// StandardShader vaiables
        ///
        /// _Color
        /// _MainTex
        /// _Cutoff
        /// _Glossiness
        /// _Metallic
        /// _MetallicGlossMap
        /// _BumpScale
        /// _BumpMap
        /// _Parallax
        /// _ParallaxMap
        /// _OcclusionStrength
        /// _OcclusionMap
        /// _EmissionColor
        /// _EmissionMap
        /// _DetailMask
        /// _DetailAlbedoMap
        /// _DetailNormalMapScale
        /// _DetailNormalMap
        /// _UVSec
        /// _EmissionScaleUI
        /// _EmissionColorUI
        /// _Mode
        /// _SrcBlend
        /// _DstBlend
        /// _ZWrite
        public static CreateMaterialFunc CreateMaterialFuncFromShader(IShaderStore shaderStore)
        {
            if (shaderStore == null)
            {
                return(null);
            }

            return((ctx, i) =>
            {
                var material = new Material(shaderStore.GetShader(ctx, i));
                material.name = string.Format("material_{0:00}", i);

                if (i >= 0 && i < ctx.GLTF.materials.Count)
                {
                    var x = ctx.GLTF.materials[i];
                    if (x != null)
                    {
                        if (!string.IsNullOrEmpty(x.name))
                        {
                            material.name = ctx.GLTF.GetUniqueMaterialName(i);
                        }
                        //Debug.LogFormat("{0}: {1}", i, material.name);

                        if (x.pbrMetallicRoughness != null)
                        {
                            if (x.pbrMetallicRoughness.baseColorFactor != null)
                            {
                                var color = x.pbrMetallicRoughness.baseColorFactor;
                                material.color = new Color(color[0], color[1], color[2], color[3]);
                            }

                            if (x.pbrMetallicRoughness.baseColorTexture != null && x.pbrMetallicRoughness.baseColorTexture.index != -1)
                            {
                                var texture = ctx.Textures[x.pbrMetallicRoughness.baseColorTexture.index];
                                material.mainTexture = texture.Texture;
                            }

                            if (x.pbrMetallicRoughness.metallicRoughnessTexture != null && x.pbrMetallicRoughness.metallicRoughnessTexture.index != -1)
                            {
                                material.EnableKeyword("_METALLICGLOSSMAP");
                                var texture = ctx.Textures[x.pbrMetallicRoughness.metallicRoughnessTexture.index];
                                material.SetTexture("_MetallicGlossMap", texture.GetMetallicRoughnessOcclusionConverted());
                            }
                        }

                        if (x.normalTexture.index != -1)
                        {
                            material.EnableKeyword("_NORMALMAP");
                            var texture = ctx.Textures[x.normalTexture.index];
#if UNITY_EDITOR
                            var textureAssetPath = AssetDatabase.GetAssetPath(texture.Texture);
                            if (!string.IsNullOrEmpty(textureAssetPath))
                            {
                                TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath);
                            }
#endif
                            material.SetTexture("_BumpMap", texture.Texture);
                        }

                        if (x.occlusionTexture.index != -1)
                        {
                            var texture = ctx.Textures[x.occlusionTexture.index];
                            material.SetTexture("_OcclusionMap", texture.GetMetallicRoughnessOcclusionConverted());
                        }

                        if (x.emissiveFactor != null ||
                            x.emissiveTexture.index != -1)
                        {
                            material.EnableKeyword("_EMISSION");
                            material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;

                            if (x.emissiveFactor != null)
                            {
                                material.SetColor("_EmissionColor", new Color(x.emissiveFactor[0], x.emissiveFactor[1], x.emissiveFactor[2]));
                            }

                            if (x.emissiveTexture.index != -1)
                            {
                                var texture = ctx.Textures[x.emissiveTexture.index];
                                material.SetTexture("_EmissionMap", texture.Texture);
                            }
                        }
                    }
                }

                return material;
            });
        }
Пример #13
0
        public static Exported FromGameObject(glTF gltf, GameObject go, bool useSparseAccessorForMorphTarget = false)
        {
            var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
            var bufferIndex = gltf.AddBuffer(bytesBuffer);

            if (go.transform.childCount == 0)
            {
                throw new UniGLTFException("empty root GameObject required");
            }

            var unityNodes = go.transform.Traverse()
                             .Skip(1) // exclude root object for the symmetry with the importer
                             .ToList();

            #region Materials and Textures
            var unityMaterials = unityNodes.SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList();
            var unityTextures  = unityMaterials.SelectMany(x => x.GetTextures()).Where(x => x != null).Distinct().ToList();

            for (int i = 0; i < unityTextures.Count; ++i)
            {
                var texture = unityTextures[i];
                TextureIO.ExportTexture(gltf, bufferIndex, texture);
            }

            gltf.materials = unityMaterials.Select(x => MaterialIO.ExportMaterial(x, unityTextures)).ToList();
            #endregion

            #region Meshes
            var unityMeshes = unityNodes
                              .Select(x => new MeshWithRenderer
            {
                Mesh       = x.GetSharedMesh(),
                Rendererer = x.GetComponent <Renderer>(),
            })
                              .Where(x =>
            {
                if (x.Mesh == null)
                {
                    return(false);
                }
                if (x.Rendererer.sharedMaterials == null ||
                    x.Rendererer.sharedMaterials.Length == 0)
                {
                    return(false);
                }

                return(true);
            })
                              .ToList();
            ExportMeshes(gltf, bufferIndex, unityMeshes, unityMaterials, useSparseAccessorForMorphTarget);
            #endregion

            #region Skins
            var unitySkins = unityNodes
                             .Select(x => x.GetComponent <SkinnedMeshRenderer>()).Where(x => x != null)
                             .ToList();
            gltf.nodes  = unityNodes.Select(x => ExportNode(x, unityNodes, unityMeshes.Select(y => y.Mesh).ToList(), unitySkins)).ToList();
            gltf.scenes = new List <gltfScene>
            {
                new gltfScene
                {
                    nodes = go.transform.GetChildren().Select(x => unityNodes.IndexOf(x)).ToArray(),
                }
            };

            foreach (var x in unitySkins)
            {
                var matrices = x.sharedMesh.bindposes.Select(y => y.ReverseZ()).ToArray();
                var accessor = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE);

                var skin = new glTFSkin
                {
                    inverseBindMatrices = accessor,
                    joints   = x.bones.Select(y => unityNodes.IndexOf(y)).ToArray(),
                    skeleton = unityNodes.IndexOf(x.rootBone),
                };
                var skinIndex = gltf.skins.Count;
                gltf.skins.Add(skin);

                foreach (var z in unityNodes.Where(y => y.Has(x)))
                {
                    var nodeIndex = unityNodes.IndexOf(z);
                    var node      = gltf.nodes[nodeIndex];
                    node.skin = skinIndex;
                }
            }
            #endregion

#if UNITY_EDITOR
            #region Animations
            var animation = go.GetComponent <Animation>();
            if (animation != null)
            {
                foreach (AnimationState state in animation)
                {
                    var animationWithCurve = ExportAnimation(state.clip, go.transform, unityNodes);

                    foreach (var kv in animationWithCurve.SamplerMap)
                    {
                        var sampler = animationWithCurve.Animation.samplers[kv.Key];

                        var inputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Input);
                        sampler.input = inputAccessorIndex;

                        var outputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Output);
                        sampler.output = outputAccessorIndex;

                        // modify accessors
                        var outputAccessor = gltf.accessors[outputAccessorIndex];
                        var channel        = animationWithCurve.Animation.channels.First(x => x.sampler == kv.Key);
                        switch (glTFAnimationTarget.GetElementCount(channel.target.path))
                        {
                        case 3:
                            outputAccessor.type   = "VEC3";
                            outputAccessor.count /= 3;
                            break;

                        case 4:
                            outputAccessor.type   = "VEC4";
                            outputAccessor.count /= 4;
                            break;

                        default:
                            throw new NotImplementedException();
                        }
                    }

                    gltf.animations.Add(animationWithCurve.Animation);
                }
            }
            #endregion
#endif

            return(new Exported
            {
                Meshes = unityMeshes,
                Nodes = unityNodes.Select(x => x.transform).ToList(),
                Materials = unityMaterials,
                Textures = unityTextures,
            });
        }
Пример #14
0
        public virtual void Export(MeshExportSettings meshExportSettings)
        {
            var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
            var bufferIndex = glTF.AddBuffer(bytesBuffer);

            GameObject tmpParent = null;

            if (Copy.transform.childCount == 0)
            {
                tmpParent = new GameObject("tmpParent");
                Copy.transform.SetParent(tmpParent.transform, true);
                Copy = tmpParent;
            }

            try
            {
                Nodes = Copy.transform.Traverse()
                        .Skip(1) // exclude root object for the symmetry with the importer
                        .ToList();

                #region Materials and Textures
                Materials = Nodes.SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList();
                var unityTextures = Materials.SelectMany(x => TextureIO.GetTextures(x)).Where(x => x.Texture != null).Distinct().ToList();

                TextureManager = new TextureExportManager(unityTextures.Select(x => x.Texture));

                var materialExporter = CreateMaterialExporter();
                glTF.materials = Materials.Select(x => materialExporter.ExportMaterial(x, TextureManager)).ToList();

                for (int i = 0; i < unityTextures.Count; ++i)
                {
                    var unityTexture = unityTextures[i];
                    TextureIO.ExportTexture(glTF, bufferIndex, TextureManager.GetExportTexture(i), unityTexture.TextureType);
                }
                #endregion

                #region Meshes
                var unityMeshes = MeshWithRenderer.FromNodes(Nodes).ToList();

                MeshBlendShapeIndexMap = new Dictionary <Mesh, Dictionary <int, int> >();
                foreach (var(mesh, gltfMesh, blendShapeIndexMap) in MeshExporter.ExportMeshes(
                             glTF, bufferIndex, unityMeshes, Materials, meshExportSettings))
                {
                    glTF.meshes.Add(gltfMesh);
                    if (!MeshBlendShapeIndexMap.ContainsKey(mesh))
                    {
                        // 同じmeshが複数回現れた
                        MeshBlendShapeIndexMap.Add(mesh, blendShapeIndexMap);
                    }
                }
                Meshes = unityMeshes.Select(x => x.Mesh).ToList();
                #endregion

                #region Nodes and Skins
                var unitySkins = unityMeshes
                                 .Where(x => x.UniqueBones != null)
                                 .ToList();
                glTF.nodes  = Nodes.Select(x => ExportNode(x, Nodes, unityMeshes.Select(y => y.Renderer).ToList(), unitySkins.Select(y => y.Renderer as SkinnedMeshRenderer).ToList())).ToList();
                glTF.scenes = new List <gltfScene>
                {
                    new gltfScene
                    {
                        nodes = Copy.transform.GetChildren().Select(x => Nodes.IndexOf(x)).ToArray(),
                    }
                };

                foreach (var x in unitySkins)
                {
                    var matrices = x.GetBindPoses().Select(y => y.ReverseZ()).ToArray();
                    var accessor = glTF.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE);

                    var renderer = x.Renderer as SkinnedMeshRenderer;
                    var skin     = new glTFSkin
                    {
                        inverseBindMatrices = accessor,
                        joints   = x.UniqueBones.Select(y => Nodes.IndexOf(y)).ToArray(),
                        skeleton = Nodes.IndexOf(renderer.rootBone),
                    };
                    var skinIndex = glTF.skins.Count;
                    glTF.skins.Add(skin);

                    foreach (var z in Nodes.Where(y => y.Has(x.Renderer)))
                    {
                        var nodeIndex = Nodes.IndexOf(z);
                        var node      = glTF.nodes[nodeIndex];
                        node.skin = skinIndex;
                    }
                }
                #endregion

#if UNITY_EDITOR
                #region Animations

                var clips     = new List <AnimationClip>();
                var animator  = Copy.GetComponent <Animator>();
                var animation = Copy.GetComponent <Animation>();
                if (animator != null)
                {
                    clips = AnimationExporter.GetAnimationClips(animator);
                }
                else if (animation != null)
                {
                    clips = AnimationExporter.GetAnimationClips(animation);
                }

                if (clips.Any())
                {
                    foreach (AnimationClip clip in clips)
                    {
                        var animationWithCurve = AnimationExporter.Export(clip, Copy.transform, Nodes);

                        foreach (var kv in animationWithCurve.SamplerMap)
                        {
                            var sampler = animationWithCurve.Animation.samplers[kv.Key];

                            var inputAccessorIndex = glTF.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Input);
                            sampler.input = inputAccessorIndex;

                            var outputAccessorIndex = glTF.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Output);
                            sampler.output = outputAccessorIndex;

                            // modify accessors
                            var outputAccessor = glTF.accessors[outputAccessorIndex];
                            var channel        = animationWithCurve.Animation.channels.First(x => x.sampler == kv.Key);
                            switch (glTFAnimationTarget.GetElementCount(channel.target.path))
                            {
                            case 1:
                                outputAccessor.type = "SCALAR";
                                //outputAccessor.count = ;
                                break;

                            case 3:
                                outputAccessor.type   = "VEC3";
                                outputAccessor.count /= 3;
                                break;

                            case 4:
                                outputAccessor.type   = "VEC4";
                                outputAccessor.count /= 4;
                                break;

                            default:
                                throw new NotImplementedException();
                            }
                        }
                        animationWithCurve.Animation.name = clip.name;
                        glTF.animations.Add(animationWithCurve.Animation);
                    }
                }
                #endregion
#endif
            }
            finally
            {
                if (tmpParent != null)
                {
                    tmpParent.transform.GetChild(0).SetParent(null);
                    if (Application.isPlaying)
                    {
                        GameObject.Destroy(tmpParent);
                    }
                    else
                    {
                        GameObject.DestroyImmediate(tmpParent);
                    }
                }
            }
        }
Пример #15
0
        /// StandardShader vaiables
        ///
        /// _Color
        /// _MainTex
        /// _Cutoff
        /// _Glossiness
        /// _Metallic
        /// _MetallicGlossMap
        /// _BumpScale
        /// _BumpMap
        /// _Parallax
        /// _ParallaxMap
        /// _OcclusionStrength
        /// _OcclusionMap
        /// _EmissionColor
        /// _EmissionMap
        /// _DetailMask
        /// _DetailAlbedoMap
        /// _DetailNormalMapScale
        /// _DetailNormalMap
        /// _UVSec
        /// _EmissionScaleUI
        /// _EmissionColorUI
        /// _Mode
        /// _SrcBlend
        /// _DstBlend
        /// _ZWrite
        public virtual Material CreateMaterial(int i, glTFMaterial x)
        {
            var shader = m_shaderStore.GetShader(x);

            Debug.LogFormat("[{0}]{1}", i, shader.name);
            var material = new Material(shader);

            material.name = (x == null || string.IsNullOrEmpty(x.name))
                ? string.Format("material_{0:00}", i)
                : x.name
            ;

            if (x != null)
            {
                if (x.pbrMetallicRoughness != null)
                {
                    if (x.pbrMetallicRoughness.baseColorFactor != null)
                    {
                        var color = x.pbrMetallicRoughness.baseColorFactor;
                        material.color = new Color(color[0], color[1], color[2], color[3]);
                    }

                    if (x.pbrMetallicRoughness.baseColorTexture != null && x.pbrMetallicRoughness.baseColorTexture.index != -1)
                    {
                        var texture = m_context.GetTexture(x.pbrMetallicRoughness.baseColorTexture.index);
                        if (texture != null)
                        {
                            material.mainTexture = texture.Texture;
                        }
                    }

                    if (x.pbrMetallicRoughness.metallicRoughnessTexture != null && x.pbrMetallicRoughness.metallicRoughnessTexture.index != -1)
                    {
                        material.EnableKeyword("_METALLICGLOSSMAP");
                        var texture = Context.GetTexture(x.pbrMetallicRoughness.metallicRoughnessTexture.index);
                        if (texture != null)
                        {
                            material.SetTexture("_MetallicGlossMap", texture.GetMetallicRoughnessOcclusionConverted());
                        }
                    }
                }

                if (x.normalTexture != null && x.normalTexture.index != -1)
                {
                    material.EnableKeyword("_NORMALMAP");
                    var texture = Context.GetTexture(x.normalTexture.index);
                    if (texture != null)
                    {
#if UNITY_EDITOR
                        var textureAssetPath = AssetDatabase.GetAssetPath(texture.Texture);
                        if (!string.IsNullOrEmpty(textureAssetPath))
                        {
                            TextureIO.MarkTextureAssetAsNormalMap(textureAssetPath);
                        }
#endif
                        material.SetTexture("_BumpMap", texture.Texture);
                    }
                }

                if (x.occlusionTexture != null && x.occlusionTexture.index != -1)
                {
                    var texture = Context.GetTexture(x.occlusionTexture.index);
                    if (texture != null)
                    {
                        material.SetTexture("_OcclusionMap", texture.GetMetallicRoughnessOcclusionConverted());
                    }
                }

                if (x.emissiveFactor != null ||
                    (x.emissiveTexture != null && x.emissiveTexture.index != -1))
                {
                    material.EnableKeyword("_EMISSION");
                    material.globalIlluminationFlags &= ~MaterialGlobalIlluminationFlags.EmissiveIsBlack;

                    if (x.emissiveFactor != null)
                    {
                        material.SetColor("_EmissionColor", new Color(x.emissiveFactor[0], x.emissiveFactor[1], x.emissiveFactor[2]));
                    }

                    if (x.emissiveTexture.index != -1)
                    {
                        var texture = Context.GetTexture(x.emissiveTexture.index);
                        if (texture != null)
                        {
                            material.SetTexture("_EmissionMap", texture.Texture);
                        }
                    }
                }
            }

            return(material);
        }