Created
April 9, 2020 09:03
-
-
Save RemyUnity/856f85bfe3ec7a8d845406415b426f87 to your computer and use it in GitHub Desktop.
Unity utility to convert 6 texture to a single cubemap texture
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEditor; | |
using System.Linq; | |
using System.IO; | |
public class CubemapTextureBuilder : EditorWindow | |
{ | |
[MenuItem("Tools/Cubemap Builder")] | |
public static void OpenWindow() | |
{ | |
GetWindow<CubemapTextureBuilder>(); | |
} | |
Texture2D[] textures = new Texture2D[6]; | |
string[] labels = new string[] { | |
"Right", "Left", | |
"Top", "Bottom", | |
"Front", "Back" | |
}; | |
TextureFormat[] HDRFormats = new TextureFormat[] { | |
TextureFormat.ASTC_HDR_10x10 , | |
TextureFormat.ASTC_HDR_12x12 , | |
TextureFormat.ASTC_HDR_4x4 , | |
TextureFormat.ASTC_HDR_5x5 , | |
TextureFormat.ASTC_HDR_6x6 , | |
TextureFormat.ASTC_HDR_8x8 , | |
TextureFormat.BC6H , | |
TextureFormat.RGBAFloat , | |
TextureFormat.RGBAHalf | |
}; | |
Vector2Int[] placementRects = new Vector2Int[] | |
{ | |
new Vector2Int(2, 1), | |
new Vector2Int(0, 1), | |
new Vector2Int(1, 2), | |
new Vector2Int(1, 0), | |
new Vector2Int(1, 1), | |
new Vector2Int(3, 1), | |
}; | |
private void OnGUI() | |
{ | |
for (int i=0; i<6; i++) | |
{ | |
textures[i] = EditorGUILayout.ObjectField(labels[i], textures[i], typeof(Texture2D), false) as Texture2D; | |
} | |
if (GUILayout.Button("Build Cubemap")) | |
{ | |
// Missing Texture | |
if (textures.Any( t => t == null ) ) | |
{ | |
EditorUtility.DisplayDialog("Cubemap Builder Error", "One or more texture is missing.", "Ok"); | |
return; | |
} | |
// Get size | |
var size = textures[0].width; | |
// Not all of the same size or square | |
if ( textures.Any( t => (t.width!=size) || (t.height!=size) ) ) | |
{ | |
EditorUtility.DisplayDialog("Cubemap Builder Error", "All the textures need to be the same size and square.", "Ok"); | |
return; | |
} | |
var isHDR = HDRFormats.Any(f => f == textures[0].format); | |
var texturePaths = textures.Select(t => AssetDatabase.GetAssetPath(t)).ToArray(); | |
// Should be ok, ask for the file path. | |
var path = EditorUtility.SaveFilePanel("Save Cubemap", Path.GetDirectoryName(texturePaths[0]), "Cubemap", isHDR ? "exr" : "png"); | |
if (string.IsNullOrEmpty(path)) return; | |
// Save the readable flag to restore it afterwards | |
var readableFlags = textures.Select(t => t.isReadable).ToArray(); | |
// Get the importer and mark the textures as readable | |
var importers = texturePaths.Select(p => TextureImporter.GetAtPath(p) as TextureImporter).ToArray(); | |
foreach (var importer in importers) | |
{ | |
importer.isReadable = true; | |
} | |
AssetDatabase.Refresh(); | |
foreach( var p in texturePaths) | |
{ | |
AssetDatabase.ImportAsset(p); | |
} | |
// Build the cubemap texture | |
var cubeTexture = new Texture2D(size * 4, size * 3, isHDR ? TextureFormat.RGBAFloat : TextureFormat.RGBA32, false); | |
for (int i=0; i<6; i++) | |
{ | |
cubeTexture.SetPixels(placementRects[i].x * size, placementRects[i].y * size, size, size, textures[i].GetPixels(0)); | |
} | |
cubeTexture.Apply(false); | |
// Save the texture to the specified path, and destroy the temporary object | |
var bytes = isHDR ? cubeTexture.EncodeToEXR() : cubeTexture.EncodeToPNG(); | |
File.WriteAllBytes(path, bytes); | |
DestroyImmediate(cubeTexture); | |
// Reset the read flags, and reimport everything | |
for (var i = 0; i<6; i++) | |
{ | |
importers[i].isReadable = readableFlags[i]; | |
} | |
path = path.Remove(0, Application.dataPath.Length-6); | |
AssetDatabase.ImportAsset(path); | |
var cubeImporter = AssetImporter.GetAtPath(path) as TextureImporter; | |
cubeImporter.textureShape = TextureImporterShape.TextureCube; | |
cubeImporter.sRGBTexture = false; | |
cubeImporter.generateCubemap = TextureImporterGenerateCubemap.FullCubemap; | |
foreach (var p in texturePaths) | |
{ | |
AssetDatabase.ImportAsset(p); | |
} | |
AssetDatabase.ImportAsset(path); | |
AssetDatabase.Refresh(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage
Limitations