Skip to content

Commit

Permalink
texture remapping on import to allow for storing in-project reference…
Browse files Browse the repository at this point in the history
…s properly
  • Loading branch information
hybridherbst committed Jul 14, 2023
1 parent 7a11e1f commit 3eaa1b8
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 5 deletions.
3 changes: 2 additions & 1 deletion UnityGLTF/Assets/UnityGLTF/Editor/Scripts/GLTFImporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ private static void EnsureShadersAreLoaded()

// TODO make internal and allow access for relevant assemblies
public Material[] ImportedMaterials => m_Materials;
public Texture[] ImportedTextures => m_Textures;

[Serializable]
internal class ExtensionInfo
Expand Down Expand Up @@ -502,7 +503,7 @@ string GetUniqueName(string desiredName)
}
return matTextures;
}).Distinct().ToArray();

// texture asset remapping
foreach (var entry in texMaterialMap)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,36 @@ private static void OnImmutableMaterialChanged(Material material)
exporter.SaveGLTFandBin(path, name);
AssetDatabase.ImportAsset(path);

// add texture remaps, so that the textures we just exported with stay valid.
// We want to always have default paths in the file, and remapping is done on the Unity side to a project specific path,
// to avoid breaking references all the time when paths change.
var exportedTextures = exporter.GetRoot().Textures;
var importedTextures = importer.ImportedTextures;
// If these don't match, we could only try by name... not ideal.
// They may not match due to different sampler settings etc.
if (exportedTextures.Count == importedTextures.Length)
{
for (int i = 0; i < exportedTextures.Count; i++)
{
var exported = exportedTextures[i];
var imported = importedTextures[i];
// TODO could we also use the imported texture definitions instead of the actual imported textures?
// Then we wouldn't need to create mock textures on import for all missing/remapped ones.
if (exported.Name != imported.name)
{
Debug.LogWarning($"Texture name mismatch: {exported.Name} != {imported.name}");
}

var sourceTextureForExportedTexture = exporter.GetSourceTextureForExportedTexture(exported);

// we should not remap if that is actually the same texture
if (imported == sourceTextureForExportedTexture) continue;

importer.AddRemap(new AssetImporter.SourceAssetIdentifier(imported), sourceTextureForExportedTexture);
}
importer.SaveAndReimport();
}

// TODO we should get rid of this, but without it currently the inspector doesn't repaint
// after importing a changed material, which can be confusing. Could be caching inside PBRGraphGUI
AssetDatabase.Refresh();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,9 @@ public Stream LoadStream(string relativeFilePath)
{
if (relativeFilePath.ToLowerInvariant().EndsWith(".bin"))
throw new FileNotFoundException("Buffer file " + relativeFilePath + " not found in " + _rootDirectoryPath + ", complete path: " + pathToLoad, relativeFilePath);


// One exception here: we don't want to log an error if we're already knowing that the texture
// has been remapped on import - that's fine! A missing texture can be remapped to a valid one.
UnityEngine.Debug.LogError("Buffer file " + relativeFilePath + " not found in " + _rootDirectoryPath + ", complete path: " + pathToLoad);
return InvalidStream;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -929,5 +929,12 @@ private MaterialCommonConstant ExportCommonConstant(Material materialObj)

return constant;
}

// TODO make internal
public Texture GetSourceTextureForExportedTexture(GLTFTexture exported)
{
var textureIndex = _root.Textures.FindIndex(x => x == exported);
return _textures[textureIndex].Texture;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,13 @@ protected virtual async Task ConstructUnityTexture(Stream stream, bool markGpuOn
return;
}
#endif
Texture2D texture = new Texture2D(0, 0, TextureFormat.RGBA32, GenerateMipMapsForTextures, isLinear);
Texture2D texture = new Texture2D(4, 4, TextureFormat.RGBA32, GenerateMipMapsForTextures, isLinear);
texture.name = string.IsNullOrEmpty(image.Name) ? Path.GetFileNameWithoutExtension(image.Uri) : image.Name;

if (stream == FileLoader.InvalidStream)
{
// ignore
texture = null;
// ignore - we still need a valid texture so that we can properly remap
// texture = null;
}
else if (stream is MemoryStream)
{
Expand Down

0 comments on commit 3eaa1b8

Please sign in to comment.