diff --git a/UnityGLTF/Assets/Resources/MetalGlossChannelSwap.shader b/UnityGLTF/Assets/Resources/MetalGlossChannelSwap.shader new file mode 100644 index 000000000..b0393d81a --- /dev/null +++ b/UnityGLTF/Assets/Resources/MetalGlossChannelSwap.shader @@ -0,0 +1,61 @@ +Shader "Hidden/MetalGlossChannelSwap" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + } + SubShader + { + // No culling or depth + Cull Off ZWrite Off ZTest Always + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + + struct appdata + { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + }; + + struct v2f + { + float2 uv : TEXCOORD0; + float4 vertex : SV_POSITION; + }; + + v2f vert (appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + return o; + } + + sampler2D _MainTex; + + float4 frag (v2f i) : SV_Target + { + float4 col = tex2D(_MainTex, i.uv); + // From the GLTF 2.0 spec + // The metallic-roughness texture. The metalness values are sampled from the B channel. + // The roughness values are sampled from the G channel. These values are linear. + // If other channels are present (R or A), they are ignored for metallic-roughness calculations. + // + // Unity, by default, puts metallic in R channel and glossiness in A channel. + // Unity uses a metallic-gloss texture so we need to invert the value in the g channel. + // + // Conversion Summary + // Unity R channel goes into B channel + // Unity A channel goes into G channel, then inverted + return float4(1, 1 - col.a, col.r, 1); + } + ENDCG + } + } +} diff --git a/UnityGLTF/Assets/Resources/MetalGlossChannelSwap.shader.meta b/UnityGLTF/Assets/Resources/MetalGlossChannelSwap.shader.meta new file mode 100644 index 000000000..093f9163e --- /dev/null +++ b/UnityGLTF/Assets/Resources/MetalGlossChannelSwap.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 200d9689f5dda4633867345ba978a8dd +timeCreated: 1520799759 +licenseType: Pro +ShaderImporter: + externalObjects: {} + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityGLTF/Assets/Resources/NormalChannel.shader b/UnityGLTF/Assets/Resources/NormalChannel.shader new file mode 100644 index 000000000..5910efdb0 --- /dev/null +++ b/UnityGLTF/Assets/Resources/NormalChannel.shader @@ -0,0 +1,52 @@ +Shader "Hidden/NormalChannel" +{ + Properties + { + _MainTex ("Texture", 2D) = "white" {} + } + SubShader + { + // No culling or depth + Cull Off ZWrite Off ZTest Always + + Pass + { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + + struct appdata + { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + }; + + struct v2f + { + float2 uv : TEXCOORD0; + float4 vertex : SV_POSITION; + }; + + v2f vert (appdata v) + { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = v.uv; + return o; + } + + sampler2D _MainTex; + + fixed4 frag (v2f i) : SV_Target + { + float4 col = tex2D(_MainTex, i.uv); + // If a texture is marked as a normal map + // the values are stored in the A and G channel. + return float4(col.a, col.g, 1, 1); + } + ENDCG + } + } +} diff --git a/UnityGLTF/Assets/Resources/NormalChannel.shader.meta b/UnityGLTF/Assets/Resources/NormalChannel.shader.meta new file mode 100644 index 000000000..336633f95 --- /dev/null +++ b/UnityGLTF/Assets/Resources/NormalChannel.shader.meta @@ -0,0 +1,10 @@ +fileFormatVersion: 2 +guid: 12e0e6f24241d4f38811bfce257ae65d +timeCreated: 1520804883 +licenseType: Pro +ShaderImporter: + externalObjects: {} + defaultTextures: [] + userData: + assetBundleName: + assetBundleVariant: diff --git a/UnityGLTF/Assets/UnityGLTF/Examples/GLTFExporterTest.cs b/UnityGLTF/Assets/UnityGLTF/Examples/GLTFExporterTest.cs index d12d4b801..5898880b8 100644 --- a/UnityGLTF/Assets/UnityGLTF/Examples/GLTFExporterTest.cs +++ b/UnityGLTF/Assets/UnityGLTF/Examples/GLTFExporterTest.cs @@ -5,10 +5,15 @@ namespace UnityGLTF.Examples { public class GLTFExporterTest : MonoBehaviour { + public string RetrieveTexturePath(UnityEngine.Texture texture) + { + return texture.name; + } + // Use this for initialization void Awake() { - var exporter = new GLTFSceneExporter(new[] {transform}); + var exporter = new GLTFSceneExporter(new[] {transform}, RetrieveTexturePath); var appPath = Application.dataPath; var wwwPath = appPath.Substring(0, appPath.LastIndexOf("Assets")) + "www"; exporter.SaveGLTFandBin(Path.Combine(wwwPath, "TestScene"), "TestScene"); diff --git a/UnityGLTF/Assets/UnityGLTF/Plugins/Newtonsoft.Json.xml b/UnityGLTF/Assets/UnityGLTF/Plugins/Newtonsoft.Json.xml new file mode 100755 index 000000000..e69de29bb diff --git a/UnityGLTF/Assets/UnityGLTF/Plugins/Newtonsoft.Json.xml.meta b/UnityGLTF/Assets/UnityGLTF/Plugins/Newtonsoft.Json.xml.meta new file mode 100644 index 000000000..e69de29bb diff --git a/UnityGLTF/Assets/UnityGLTF/Scripts/Editor/GLTFExportMenu.cs b/UnityGLTF/Assets/UnityGLTF/Scripts/Editor/GLTFExportMenu.cs index a0471a031..5ae43f165 100644 --- a/UnityGLTF/Assets/UnityGLTF/Scripts/Editor/GLTFExportMenu.cs +++ b/UnityGLTF/Assets/UnityGLTF/Scripts/Editor/GLTFExportMenu.cs @@ -5,6 +5,11 @@ public class GLTFExportMenu { + public static string RetrieveTexturePath(UnityEngine.Texture texture) + { + return AssetDatabase.GetAssetPath (texture); + } + [MenuItem("GLTF/Export Selected")] static void ExportSelected() { @@ -16,9 +21,12 @@ static void ExportSelected() else throw new Exception("No objects selected, cannot export."); - var exporter = new GLTFSceneExporter(Selection.transforms); + var exporter = new GLTFSceneExporter(Selection.transforms, RetrieveTexturePath); + var path = EditorUtility.OpenFolderPanel("glTF Export Path", "", ""); - exporter.SaveGLTFandBin(path, name); + if (!string.IsNullOrEmpty(path)) { + exporter.SaveGLTFandBin (path, name); + } } [MenuItem("GLTF/Export Scene")] @@ -28,8 +36,10 @@ static void ExportScene() var gameObjects = scene.GetRootGameObjects(); var transforms = Array.ConvertAll(gameObjects, gameObject => gameObject.transform); - var exporter = new GLTFSceneExporter(transforms); + var exporter = new GLTFSceneExporter(transforms, RetrieveTexturePath); var path = EditorUtility.OpenFolderPanel("glTF Export Path", "", ""); - exporter.SaveGLTFandBin(path, scene.name); + if (path != "") { + exporter.SaveGLTFandBin (path, scene.name); + } } } \ No newline at end of file diff --git a/UnityGLTF/Assets/UnityGLTF/Scripts/Editor/PbrShaderGUI.cs b/UnityGLTF/Assets/UnityGLTF/Scripts/Editor/PbrShaderGUI.cs index c4d16495e..8961e51ca 100644 --- a/UnityGLTF/Assets/UnityGLTF/Scripts/Editor/PbrShaderGUI.cs +++ b/UnityGLTF/Assets/UnityGLTF/Scripts/Editor/PbrShaderGUI.cs @@ -56,8 +56,6 @@ private static class Styles MaterialProperty bumpMap = null; MaterialProperty occlusionStrength = null; MaterialProperty occlusionMap = null; - MaterialProperty heigtMapScale = null; - MaterialProperty heightMap = null; MaterialProperty emissionColor = null; MaterialProperty emissionMap = null; diff --git a/UnityGLTF/Assets/UnityGLTF/Scripts/GLTFComponent.cs b/UnityGLTF/Assets/UnityGLTF/Scripts/GLTFComponent.cs index b030f8f60..4300cb790 100644 --- a/UnityGLTF/Assets/UnityGLTF/Scripts/GLTFComponent.cs +++ b/UnityGLTF/Assets/UnityGLTF/Scripts/GLTFComponent.cs @@ -26,11 +26,11 @@ IEnumerator Start() ILoader loader = null; if (UseStream) - { - // Path.Combine treats paths that start with the separator character - // as absolute paths, ignoring the first path passed in. This removes - // that character to properly handle a filename written with it. - GLTFUri = GLTFUri.TrimStart(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); + { + // Path.Combine treats paths that start with the separator character + // as absolute paths, ignoring the first path passed in. This removes + // that character to properly handle a filename written with it. + GLTFUri = GLTFUri.TrimStart(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); string fullPath = Path.Combine(Application.streamingAssetsPath, GLTFUri); string directoryPath = URIHelper.GetDirectoryName(fullPath); loader = new FileLoader(directoryPath); diff --git a/UnityGLTF/Assets/UnityGLTF/Scripts/GLTFSceneExporter.cs b/UnityGLTF/Assets/UnityGLTF/Scripts/GLTFSceneExporter.cs index 5541cc21c..fd2b12e20 100644 --- a/UnityGLTF/Assets/UnityGLTF/Scripts/GLTFSceneExporter.cs +++ b/UnityGLTF/Assets/UnityGLTF/Scripts/GLTFSceneExporter.cs @@ -9,15 +9,51 @@ namespace UnityGLTF { public class GLTFSceneExporter { + public delegate string RetrieveTexturePathDelegate(UnityEngine.Texture texture); + + private enum IMAGETYPE + { + RGB, + RGBA, + R, + G, + B, + A, + G_INVERT + } + + private enum TextureMapType + { + Main, + Bump, + SpecGloss, + Emission, + MetallicGloss, + Light, + Occlusion} + + ; + + private struct ImageInfo + { + public Texture2D texture; + public TextureMapType textureMapType; + }; + private Transform[] _rootTransforms; private GLTFRoot _root; private BufferId _bufferId; private GLTF.Schema.Buffer _buffer; private BinaryWriter _bufferWriter; - private List _images; + private List _imageInfos; private List _textures; private List _materials; + private RetrieveTexturePathDelegate _retrieveTexturePathDelegate; + + private UnityEngine.Material _metalGlossChannelSwapMaterial; + private UnityEngine.Material _normalChannelMaterial; + protected struct PrimKey { public UnityEngine.Mesh Mesh; @@ -32,8 +68,16 @@ protected struct PrimKey /// Create a GLTFExporter that exports out a transform /// /// Root transform of object to export - public GLTFSceneExporter(Transform[] rootTransforms) + public GLTFSceneExporter(Transform[] rootTransforms, RetrieveTexturePathDelegate retrieveTexturePathDelegate) { + _retrieveTexturePathDelegate = retrieveTexturePathDelegate; + + var metalGlossChannelSwapShader = Resources.Load ("MetalGlossChannelSwap", typeof(UnityEngine.Shader)) as UnityEngine.Shader; + _metalGlossChannelSwapMaterial = new UnityEngine.Material (metalGlossChannelSwapShader); + + var normalChannelShader = Resources.Load ("NormalChannel", typeof(UnityEngine.Shader)) as UnityEngine.Shader; + _normalChannelMaterial = new UnityEngine.Material (normalChannelShader); + _rootTransforms = rootTransforms; _root = new GLTFRoot{ Accessors = new List(), @@ -51,16 +95,16 @@ public GLTFSceneExporter(Transform[] rootTransforms) Textures = new List(), }; - _images = new List(); - _materials = new List(); - _textures = new List(); + _imageInfos = new List (); + _materials = new List (); + _textures = new List (); - _buffer = new GLTF.Schema.Buffer(); + _buffer = new GLTF.Schema.Buffer (); _bufferId = new BufferId { Id = _root.Buffers.Count, Root = _root }; - _root.Buffers.Add(_buffer); + _root.Buffers.Add (_buffer); } /// @@ -93,39 +137,118 @@ public void SaveGLTFandBin(string path, string fileName) gltfFile.Dispose(); binFile.Dispose(); #else - gltfFile.Close(); - binFile.Close(); + gltfFile.Close (); + binFile.Close (); #endif + ExportImages (path); + + } - foreach (var image in _images) - { - Debug.Log(image.name); - var renderTexture = RenderTexture.GetTemporary(image.width, image.height); - Graphics.Blit(image, renderTexture); - RenderTexture.active = renderTexture; - var exportTexture = new Texture2D(image.width, image.height); - exportTexture.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); - exportTexture.Apply(); - File.WriteAllBytes(Path.Combine(path, image.name + ".png"), exportTexture.EncodeToPNG()); + private void ExportImages (string outputPath) + { + for (int t = 0; t < _imageInfos.Count; ++t) { + var image = _imageInfos [t].texture; + int height = image.height; + int width = image.width; + + switch (_imageInfos [t].textureMapType) { + case TextureMapType.MetallicGloss: + ExportMetallicGlossTexture (image, outputPath); + break; + case TextureMapType.Bump: + ExportNormalTexture (image, outputPath); + break; + default: + ExportTexture (image, outputPath); + break; + } } } - private SceneId ExportScene(string name, Transform[] rootObjTransforms) + /// + /// This converts Unity's metallic-gloss texture representation into GLTF's metallic-roughness specifications. + /// Unity's metallic-gloss A channel (glossiness) is inverted and goes into GLTF's metallic-roughness G channel (roughness). + /// Unity's metallic-gloss R channel (metallic) goes into GLTF's metallic-roughess B channel. + /// + /// Unity's metallic-gloss texture to be exported + /// The location to export the texture + private void ExportMetallicGlossTexture (Texture2D texture, string outputPath) { - var scene = new Scene(); + var destRenderTexture = RenderTexture.GetTemporary(texture.width, texture.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); - if (ExportNames) + Graphics.Blit (texture, destRenderTexture, _metalGlossChannelSwapMaterial); + + var exportTexture = new Texture2D (texture.width, texture.height); + exportTexture.ReadPixels (new Rect (0, 0, destRenderTexture.width, destRenderTexture.height), 0, 0); + exportTexture.Apply (); + + var finalFilenamePath = ConstructImageFilenamePath (texture, outputPath); + File.WriteAllBytes (finalFilenamePath, exportTexture.EncodeToPNG ()); + + destRenderTexture.Release(); + } + + /// + /// This export's the normal texture. If a texture is marked as a normal map, the values are stored in the A and G channel. + /// To output the correct normal texture, the A channel is put into the R channel. + /// + /// Unity's normal texture to be exported + /// The location to export the texture + private void ExportNormalTexture (Texture2D texture, string outputPath) + { + var destRenderTexture = RenderTexture.GetTemporary(texture.width, texture.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); + + Graphics.Blit (texture, destRenderTexture, _normalChannelMaterial); + + var exportTexture = new Texture2D (texture.width, texture.height); + exportTexture.ReadPixels (new Rect (0, 0, destRenderTexture.width, destRenderTexture.height), 0, 0); + exportTexture.Apply (); + + var finalFilenamePath = ConstructImageFilenamePath (texture, outputPath); + File.WriteAllBytes (finalFilenamePath, exportTexture.EncodeToPNG ()); + + destRenderTexture.Release(); + } + + private void ExportTexture (Texture2D texture, string outputPath) + { + var destRenderTexture = new RenderTexture (texture.width, texture.height, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB); + + Graphics.Blit (texture, destRenderTexture); + + var exportTexture = new Texture2D (texture.width, texture.height); + exportTexture.ReadPixels (new Rect (0, 0, destRenderTexture.width, destRenderTexture.height), 0, 0); + exportTexture.Apply (); + + var finalFilenamePath = ConstructImageFilenamePath (texture, outputPath); + File.WriteAllBytes (finalFilenamePath, exportTexture.EncodeToPNG ()); + } + + private string ConstructImageFilenamePath (Texture2D texture, string outputPath) + { + var imagePath = _retrieveTexturePathDelegate(texture); + var fullFilenamePath = Path.Combine (outputPath, imagePath); + var file = new System.IO.FileInfo (fullFilenamePath); + file.Directory.Create (); + return Path.ChangeExtension (fullFilenamePath, ".png"); + } + + private SceneId ExportScene (string name, Transform[] rootObjTransforms) + { + var scene = new Scene (); + + if (ExportNames) { scene.Name = name; } - scene.Nodes = new List(rootObjTransforms.Length); - foreach (var transform in rootObjTransforms) + scene.Nodes = new List (rootObjTransforms.Length); + foreach (var transform in rootObjTransforms) { - scene.Nodes.Add(ExportNode(transform)); + scene.Nodes.Add (ExportNode (transform)); } - _root.Scenes.Add(scene); + _root.Scenes.Add (scene); return new SceneId { Id = _root.Scenes.Count - 1, @@ -408,7 +531,7 @@ private MaterialId ExportMaterial(UnityEngine.Material materialObj) if (emissionTex != null) { - material.EmissiveTexture = ExportTextureInfo(emissionTex); + material.EmissiveTexture = ExportTextureInfo(emissionTex, TextureMapType.Emission); ExportTextureTransform(material.EmissiveTexture, materialObj, "_EmissionMap"); @@ -421,7 +544,7 @@ private MaterialId ExportMaterial(UnityEngine.Material materialObj) if (normalTex != null) { - material.NormalTexture = ExportNormalTextureInfo(normalTex, materialObj); + material.NormalTexture = ExportNormalTextureInfo(normalTex, TextureMapType.Bump, materialObj); ExportTextureTransform(material.NormalTexture, materialObj, "_BumpMap"); } } @@ -431,20 +554,18 @@ private MaterialId ExportMaterial(UnityEngine.Material materialObj) var occTex = materialObj.GetTexture("_OcclusionMap"); if (occTex != null) { - material.OcclusionTexture = ExportOcclusionTextureInfo(occTex, materialObj); + material.OcclusionTexture = ExportOcclusionTextureInfo(occTex, TextureMapType.Occlusion, materialObj); ExportTextureTransform(material.OcclusionTexture, materialObj, "_OcclusionMap"); } } - switch (materialObj.shader.name) + if (IsPBRMetallicRoughness (materialObj)) { - case "Standard": - case "GLTF/GLTFStandard": - material.PbrMetallicRoughness = ExportPBRMetallicRoughness(materialObj); - break; - case "GLTF/GLTFConstant": - material.CommonConstant = ExportCommonConstant(materialObj); - break; + material.PbrMetallicRoughness = ExportPBRMetallicRoughness (materialObj); + } + else if (IsCommonConstant (materialObj)) + { + material.CommonConstant = ExportCommonConstant (materialObj); } _materials.Add(materialObj); @@ -458,6 +579,18 @@ private MaterialId ExportMaterial(UnityEngine.Material materialObj) return id; } + private bool IsPBRMetallicRoughness (UnityEngine.Material material) + { + return material.HasProperty ("_Metallic") && material.HasProperty ("_MetallicGlossMap"); + } + + private bool IsCommonConstant (UnityEngine.Material material) + { + return material.HasProperty ("_AmbientFactor") && + material.HasProperty ("_LightMap") && + material.HasProperty ("_LightFactor"); + } + private void ExportTextureTransform(TextureInfo def, UnityEngine.Material mat, string texName) { Vector2 offset = mat.GetTextureOffset(texName); @@ -486,29 +619,33 @@ private void ExportTextureTransform(TextureInfo def, UnityEngine.Material mat, s ); } - private NormalTextureInfo ExportNormalTextureInfo(UnityEngine.Texture texture, UnityEngine.Material material) + private NormalTextureInfo ExportNormalTextureInfo ( + UnityEngine.Texture texture, + TextureMapType textureMapType, + UnityEngine.Material material) { - var info = new NormalTextureInfo(); + var info = new NormalTextureInfo (); - info.Index = ExportTexture(texture); + info.Index = ExportTexture (texture, textureMapType); - if (material.HasProperty("_BumpScale")) - { - info.Scale = material.GetFloat("_BumpScale"); + if (material.HasProperty ("_BumpScale")) { + info.Scale = material.GetFloat ("_BumpScale"); } return info; } - private OcclusionTextureInfo ExportOcclusionTextureInfo(UnityEngine.Texture texture, UnityEngine.Material material) + private OcclusionTextureInfo ExportOcclusionTextureInfo ( + UnityEngine.Texture texture, + TextureMapType textureMapType, + UnityEngine.Material material) { - var info = new OcclusionTextureInfo(); + var info = new OcclusionTextureInfo (); - info.Index = ExportTexture(texture); + info.Index = ExportTexture (texture, textureMapType); - if (material.HasProperty("_OcclusionStrength")) - { - info.Strength = material.GetFloat("_OcclusionStrength"); + if (material.HasProperty ("_OcclusionStrength")) { + info.Strength = material.GetFloat ("_OcclusionStrength"); } return info; @@ -529,43 +666,41 @@ private PbrMetallicRoughness ExportPBRMetallicRoughness(UnityEngine.Material mat if (mainTex != null) { - pbr.BaseColorTexture = ExportTextureInfo(mainTex); + pbr.BaseColorTexture = ExportTextureInfo(mainTex, TextureMapType.Main); ExportTextureTransform(pbr.BaseColorTexture, material, "_MainTex"); } } - if (material.HasProperty("_Metallic")) + if (material.HasProperty ("_Metallic")) { - pbr.MetallicFactor = material.GetFloat("_Metallic"); + var metallicGlossMap = material.GetTexture ("_MetallicGlossMap"); + pbr.MetallicFactor = (metallicGlossMap != null) ? 1.0 : material.GetFloat ("_Metallic"); } - if (material.HasProperty("_Roughness")) + if (material.HasProperty ("_Glossiness")) { - pbr.RoughnessFactor = material.GetFloat("_Roughness"); - } - else if (material.HasProperty("_Glossiness")) - { - pbr.RoughnessFactor = 1 - material.GetFloat("_Glossiness"); + var metallicGlossMap = material.GetTexture ("_MetallicGlossMap"); + pbr.RoughnessFactor = (metallicGlossMap != null) ? 1.0 : material.GetFloat ("_Glossiness"); } - if (material.HasProperty("_MetallicRoughnessMap")) + if (material.HasProperty("_MetallicGlossMap")) { - var mrTex = material.GetTexture("_MetallicRoughnessMap"); + var mrTex = material.GetTexture("_MetallicGlossMap"); if (mrTex != null) { - pbr.MetallicRoughnessTexture = ExportTextureInfo(mrTex); - ExportTextureTransform(pbr.MetallicRoughnessTexture, material, "_MetallicRoughnessMap"); + pbr.MetallicRoughnessTexture = ExportTextureInfo(mrTex, TextureMapType.MetallicGloss); + ExportTextureTransform(pbr.MetallicRoughnessTexture, material, "_MetallicGlossMap"); } } - else if (material.HasProperty("_MetallicGlossMap")) + else if (material.HasProperty("_SpecGlossMap")) { - var mgTex = material.GetTexture("_MetallicGlossMap"); + var mgTex = material.GetTexture("_SpecGlossMap"); if (mgTex != null) { - pbr.MetallicRoughnessTexture = ExportTextureInfo(mgTex); - ExportTextureTransform(pbr.MetallicRoughnessTexture, material, "_MetallicGlossMap"); + pbr.MetallicRoughnessTexture = ExportTextureInfo(mgTex, TextureMapType.SpecGloss); + ExportTextureTransform(pbr.MetallicRoughnessTexture, material, "_SpecGlossMap"); } } @@ -594,7 +729,7 @@ private MaterialCommonConstant ExportCommonConstant(UnityEngine.Material materia if (lmTex != null) { - constant.LightmapTexture = ExportTextureInfo(lmTex); + constant.LightmapTexture = ExportTextureInfo(lmTex, TextureMapType.Light); ExportTextureTransform(constant.LightmapTexture, materialObj, "_LightMap"); } @@ -608,16 +743,16 @@ private MaterialCommonConstant ExportCommonConstant(UnityEngine.Material materia return constant; } - private TextureInfo ExportTextureInfo(UnityEngine.Texture texture) + private TextureInfo ExportTextureInfo(UnityEngine.Texture texture, TextureMapType textureMapType) { var info = new TextureInfo(); - info.Index = ExportTexture(texture); + info.Index = ExportTexture(texture, textureMapType); return info; } - private TextureId ExportTexture(UnityEngine.Texture textureObj) + private TextureId ExportTexture(UnityEngine.Texture textureObj, TextureMapType textureMapType) { TextureId id = GetTextureId(_root, textureObj); if (id != null) @@ -638,7 +773,7 @@ private TextureId ExportTexture(UnityEngine.Texture textureObj) texture.Name = textureObj.name; } - texture.Source = ExportImage(textureObj); + texture.Source = ExportImage(textureObj, textureMapType); texture.Sampler = ExportSampler(textureObj); _textures.Add(textureObj); @@ -653,7 +788,7 @@ private TextureId ExportTexture(UnityEngine.Texture textureObj) return id; } - private ImageId ExportImage(UnityEngine.Texture texture) + private ImageId ExportImage(UnityEngine.Texture texture, TextureMapType texturMapType) { ImageId id = GetImageId(_root, texture); if(id != null) @@ -668,9 +803,14 @@ private ImageId ExportImage(UnityEngine.Texture texture) image.Name = texture.name; } - _images.Add(texture as Texture2D); + _imageInfos.Add (new ImageInfo { + texture = texture as Texture2D, + textureMapType = texturMapType + }); - image.Uri = Uri.EscapeUriString(texture.name + ".png"); + var path = _retrieveTexturePathDelegate(texture); + var newPath = Path.ChangeExtension (path, ".png"); + image.Uri = Uri.EscapeUriString(newPath); id = new ImageId { Id = _root.Images.Count, @@ -1190,9 +1330,9 @@ public TextureId GetTextureId(GLTFRoot root, UnityEngine.Texture textureObj) public ImageId GetImageId(GLTFRoot root, UnityEngine.Texture imageObj) { - for (var i = 0; i < _images.Count; i++) + for (var i = 0; i < _imageInfos.Count; i++) { - if (_images[i] == imageObj) + if (_imageInfos[i].texture == imageObj) { return new ImageId { diff --git a/UnityGLTF/Assets/UnityGLTF/Scripts/Tests/Integration/GLTFExporterIntegrationTest.cs b/UnityGLTF/Assets/UnityGLTF/Scripts/Tests/Integration/GLTFExporterIntegrationTest.cs index 928218e6a..bfb0c0013 100644 --- a/UnityGLTF/Assets/UnityGLTF/Scripts/Tests/Integration/GLTFExporterIntegrationTest.cs +++ b/UnityGLTF/Assets/UnityGLTF/Scripts/Tests/Integration/GLTFExporterIntegrationTest.cs @@ -4,9 +4,14 @@ namespace UnityGLTF.Tests.Integration { public class GLTFExporterIntegrationTest : MonoBehaviour { + public string RetrieveTexturePath(UnityEngine.Texture texture) + { + return texture.name; + } + void Start() { - var exporter = new GLTFSceneExporter(new[] {transform}); + var exporter = new GLTFSceneExporter(new[] {transform}, RetrieveTexturePath); exporter.SaveGLTFandBin("tempDir", "test"); var root = exporter.GetRoot();