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); }
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", }); }
public void ProcessOnMainThread(glTF gltf) { var textureType = TextureIO.GetglTFTextureType(gltf, m_textureIndex); var colorSpace = TextureIO.GetColorSpace(textureType); GetOrCreateTexture(colorSpace == RenderTextureReadWrite.Linear); SetSampler(gltf); }
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))); } }
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)); }
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); }
/// <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); }
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", }); }
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); } } } }
/// 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); }
/// 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; }); }
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, }); }
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); } } } }
/// 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); }