139 lines
4.4 KiB
C#
139 lines
4.4 KiB
C#
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();
|
|
}
|
|
}
|
|
} |