Skip to content

Instantly share code, notes, and snippets.

@smkplus
Forked from nothke/ExportTexture.cs
Created July 1, 2020 16:54
Show Gist options
  • Save smkplus/71087b174167d0fc4fa28fbeb525892c to your computer and use it in GitHub Desktop.
Save smkplus/71087b174167d0fc4fa28fbeb525892c to your computer and use it in GitHub Desktop.
/// Texture exporter for Unity
///
/// IMPORTANT: Must be put into Editor folder to work
///
/// Right click on a texture in assets window and select one of 'Export/' options
/// - Use "RG Normal Map" to export normal maps as it will swap AG channels used by Unity shaders into typically used RG channels
///
/// Original script by Eric5h5
/// Rewritten to C# and updated by Nothke
///
using UnityEngine;
using UnityEditor;
public class ExportTexture
{
[MenuItem("Assets/Export Texture/Default")]
public static void ExportStandardChannels()
{
Export(false);
}
[MenuItem("Assets/Export Texture/RG Normal Map")]
public static void ExportWithSwappedChannels()
{
Export(true);
}
public static void Export(bool swapNormalmapChannels)
{
var tex = Selection.activeObject as Texture2D;
if (tex == null)
{
EditorUtility.DisplayDialog("No texture selected", "Please select a texture.", "Cancel");
return;
}
// We need to set some importer settings before we export the texture
string texPath = AssetDatabase.GetAssetPath(tex);
TextureImporter texImport = (TextureImporter)AssetImporter.GetAtPath(texPath);
// Save the original import settings
bool originalIsReadable = texImport.isReadable;
TextureImporterCompression originalCompression = texImport.textureCompression;
// Make sure it's readable so that we can read the pixels
texImport.isReadable = true;
// Remove all compression because we don't want to export compressed texture
texImport.textureCompression = TextureImporterCompression.Uncompressed;
// Reimport the asset
AssetDatabase.ImportAsset(texPath, ImportAssetOptions.ForceUpdate);
// Create the new texture
Texture2D newTexture = new Texture2D(tex.width, tex.height, TextureFormat.ARGB32, false);
Color[] colors = tex.GetPixels();
// Unity uses alpha channel for X component and green channel for Y,
// but usually normal maps are encoded as R for X and G for Y,
// so we need to SWAP CHANNELS:
if (swapNormalmapChannels)
{
for (int i = 0; i < colors.Length; i++)
{
colors[i].r = colors[i].a;
colors[i].a = 1;
colors[i].b = 1;
}
}
newTexture.SetPixels(colors);
newTexture.Apply();
// Encode to PNG
var bytes = newTexture.EncodeToPNG();
// Open Save panel and save it
var path = EditorUtility.SaveFilePanel("Save Texture", "", tex.name + "_normal.png", "png");
if (path != "")
{
System.IO.File.WriteAllBytes(path, bytes);
AssetDatabase.Refresh();
}
// Revert to original texutre importer settings afterwards:
texImport.isReadable = originalIsReadable;
texImport.textureCompression = originalCompression;
AssetDatabase.ImportAsset(texPath, ImportAssetOptions.ForceUpdate);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment