| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- using System.Collections.Generic;
- using System.Globalization;
- using System.IO;
- using System.Text;
- using UnityEngine;
- namespace UnityEditor.Rendering.PostProcessing
- {
- sealed class CubeLutAssetImporter : AssetPostprocessor
- {
- static List<string> s_Excluded = new List<string>()
- {
- "Linear to sRGB r1",
- "Linear to Unity Log r1",
- "sRGB to Linear r1",
- "sRGB to Unity Log r1",
- "Unity Log to Linear r1",
- "Unity Log to sRGB r1"
- };
- static void OnPostprocessAllAssets(string[] imported, string[] deleted, string[] moved, string[] movedFrom)
- {
- foreach (string path in imported)
- {
- string ext = Path.GetExtension(path);
- string filename = Path.GetFileNameWithoutExtension(path);
- if (string.IsNullOrEmpty(ext) || s_Excluded.Contains(filename))
- continue;
- ext = ext.ToLowerInvariant();
- if (ext.Equals(".cube"))
- ImportCubeLut(path);
- }
- }
- // Basic CUBE lut parser
- // Specs: http://wwwimages.adobe.com/content/dam/Adobe/en/products/speedgrade/cc/pdfs/cube-lut-specification-1.0.pdf
- static void ImportCubeLut(string path)
- {
- // Remove the 'Assets' part of the path & build absolute path
- string fullpath = path.Substring(7);
- fullpath = Path.Combine(Application.dataPath, fullpath);
- // Read the lut data
- string[] lines = File.ReadAllLines(fullpath);
- // Start parsing
- int i = 0;
- int size = -1;
- int sizeCube = -1;
- var table = new List<Color>();
- var domainMin = Color.black;
- var domainMax = Color.white;
- while (true)
- {
- if (i >= lines.Length)
- {
- if (table.Count != sizeCube)
- Debug.LogError("Premature end of file");
- break;
- }
- string line = FilterLine(lines[i]);
- if (string.IsNullOrEmpty(line))
- goto next;
- // Header data
- if (line.StartsWith("TITLE"))
- goto next; // Skip the title tag, we don't need it
- if (line.StartsWith("LUT_3D_SIZE"))
- {
- string sizeStr = line.Substring(11).TrimStart();
- if (!int.TryParse(sizeStr, out size))
- {
- Debug.LogError("Invalid data on line " + i);
- break;
- }
- if (size < 2 || size > 256)
- {
- Debug.LogError("LUT size out of range");
- break;
- }
- sizeCube = size * size * size;
- goto next;
- }
- if (line.StartsWith("DOMAIN_MIN"))
- {
- if (!ParseDomain(i, line, ref domainMin)) break;
- goto next;
- }
- if (line.StartsWith("DOMAIN_MAX"))
- {
- if (!ParseDomain(i, line, ref domainMax)) break;
- goto next;
- }
- // Table
- string[] row = line.Split();
- if (row.Length != 3)
- {
- Debug.LogError("Invalid data on line " + i);
- break;
- }
- var color = Color.black;
- for (int j = 0; j < 3; j++)
- {
- float d;
- if (!float.TryParse(row[j], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out d))
- {
- Debug.LogError("Invalid data on line " + i);
- break;
- }
- color[j] = d;
- }
- table.Add(color);
- next:
- i++;
- }
- if (sizeCube != table.Count)
- {
- Debug.LogError("Wrong table size - Expected " + sizeCube + " elements, got " + table.Count);
- return;
- }
- // Check if the Texture3D already exists, update it in this case (better workflow for
- // the user)
- string assetPath = Path.ChangeExtension(path, ".asset");
- var tex = AssetDatabase.LoadAssetAtPath<Texture3D>(assetPath);
- if (tex != null)
- {
- tex.SetPixels(table.ToArray(), 0);
- tex.Apply();
- }
- else
- {
- // Generate a new Texture3D
- tex = new Texture3D(size, size, size, TextureFormat.RGBAHalf, false)
- {
- anisoLevel = 0,
- filterMode = FilterMode.Bilinear,
- wrapMode = TextureWrapMode.Clamp,
- };
- tex.SetPixels(table.ToArray(), 0);
- tex.Apply();
- // Save to disk
- AssetDatabase.CreateAsset(tex, assetPath);
- }
- AssetDatabase.SaveAssets();
- AssetDatabase.Refresh();
- }
- static string FilterLine(string line)
- {
- var filtered = new StringBuilder();
- line = line.TrimStart().TrimEnd();
- int len = line.Length;
- int i = 0;
- while (i < len)
- {
- char c = line[i];
- if (c == '#') // Filters comment out
- break;
- filtered.Append(c);
- i++;
- }
- return filtered.ToString();
- }
- static bool ParseDomain(int i, string line, ref Color domain)
- {
- string[] domainStrs = line.Substring(10).TrimStart().Split();
- if (domainStrs.Length != 3)
- {
- Debug.LogError("Invalid data on line " + i);
- return false;
- }
- for (int j = 0; j < 3; j++)
- {
- float d;
- if (!float.TryParse(domainStrs[j], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out d))
- {
- Debug.LogError("Invalid data on line " + i);
- return false;
- }
- domain[j] = d;
- }
- return true;
- }
- }
- }
|