Skip to content

Instantly share code, notes, and snippets.

@ChrisTowles
Created July 6, 2016 03:20
Show Gist options
  • Save ChrisTowles/e2ff48624afc223a72fb094f43d0aaa0 to your computer and use it in GitHub Desktop.
Save ChrisTowles/e2ff48624afc223a72fb094f43d0aaa0 to your computer and use it in GitHub Desktop.
Updated Unity 5.3 Bake Material to Texture.
// This doesn't work or at least it didn't for the shader i was trying to use it with.
// Just Sharing Becasue i got farther with this than other version I found around the internet.
//
// Quit working on this because the shader i was trying to convert to a Standard Unity Shader
// Really could not be done as it was based reflections of orginal object (PolyWorld).
//orginal - http://wiki.unity3d.com/index.php/Bake_Material_to_Texture
using UnityEngine;
using UnityEditor;
using System.Collections;
using UnityEngine;
using UnityEditor;
using System.Collections;
public class BakeMaterialSettings
{
private static string kEditorPrefsName = "BakeMaterialSettings";
public static int kBakingLayerShouldBeUnusedInScene = 30;
public static string[] kStandardTexNames = { "_MainTex", "_BumpMap", "_Detail", "_ParallaxMap", "_Parallax" };
public bool bakeAlpha = false;
public bool bakeMainTexAsWhite = false;
public int minTextureResolution = 8;
public int maxTextureResolution = 2048;
public bool emptyScene = false;
public bool useCustomLights = false;
public Color ambient = Color.black;
public static int kLights = 3;
public bool[] enableLight = new bool[kLights];
public Color[] colorLight = new Color[kLights];
public Vector2[] dirLight = new Vector2[kLights];
public BakeMaterialSettings()
{
Load();
}
public void Load()
{
bakeAlpha = EditorPrefs.GetBool(kEditorPrefsName + ".bakeAlpha");
bakeMainTexAsWhite = EditorPrefs.GetBool(kEditorPrefsName + ".bakeMainTexAsWhite");
minTextureResolution = EditorPrefs.GetInt(kEditorPrefsName + ".minTextureResolution", 8);
maxTextureResolution = EditorPrefs.GetInt(kEditorPrefsName + ".maxTextureResolution", 2048);
emptyScene = EditorPrefs.GetBool(kEditorPrefsName + ".emptyScene");
useCustomLights = EditorPrefs.GetBool(kEditorPrefsName + ".useCustomLights");
ambient.r = EditorPrefs.GetFloat(kEditorPrefsName + ".ambient.r");
ambient.g = EditorPrefs.GetFloat(kEditorPrefsName + ".ambient.g");
ambient.b = EditorPrefs.GetFloat(kEditorPrefsName + ".ambient.b");
ambient.a = EditorPrefs.GetFloat(kEditorPrefsName + ".ambient.a", 1.0f);
for (int q = 0; q < kLights; ++q)
{
enableLight[q] = EditorPrefs.GetBool(kEditorPrefsName + ".enableLight" + q);
colorLight[q].r = EditorPrefs.GetFloat(kEditorPrefsName + ".color.r" + q, 0.5f);
colorLight[q].g = EditorPrefs.GetFloat(kEditorPrefsName + ".color.g" + q, 0.5f);
colorLight[q].b = EditorPrefs.GetFloat(kEditorPrefsName + ".color.b" + q, 0.5f);
colorLight[q].a = EditorPrefs.GetFloat(kEditorPrefsName + ".color.a" + q, 1.0f);
dirLight[q].x = EditorPrefs.GetFloat(kEditorPrefsName + ".dir.x" + q);
dirLight[q].y = EditorPrefs.GetFloat(kEditorPrefsName + ".dir.y" + q);
}
}
public void Save()
{
EditorPrefs.SetBool(kEditorPrefsName + ".bakeAlpha", bakeAlpha);
EditorPrefs.SetBool(kEditorPrefsName + ".bakeMainTexAsWhite", bakeMainTexAsWhite);
EditorPrefs.SetInt(kEditorPrefsName + ".minTextureResolution", minTextureResolution);
EditorPrefs.SetInt(kEditorPrefsName + ".maxTextureResolution", maxTextureResolution);
EditorPrefs.GetBool(kEditorPrefsName + ".emptyScene", emptyScene);
EditorPrefs.SetBool(kEditorPrefsName + ".useCustomLights", useCustomLights);
EditorPrefs.SetFloat(kEditorPrefsName + ".ambient.r", ambient.r);
EditorPrefs.SetFloat(kEditorPrefsName + ".ambient.g", ambient.g);
EditorPrefs.SetFloat(kEditorPrefsName + ".ambient.b", ambient.b);
EditorPrefs.SetFloat(kEditorPrefsName + ".ambient.a", ambient.a);
for (int q = 0; q < kLights; ++q)
{
EditorPrefs.SetBool(kEditorPrefsName + ".enableLight" + q, enableLight[q]);
EditorPrefs.SetFloat(kEditorPrefsName + ".color.r" + q, colorLight[q].r);
EditorPrefs.SetFloat(kEditorPrefsName + ".color.g" + q, colorLight[q].g);
EditorPrefs.SetFloat(kEditorPrefsName + ".color.b" + q, colorLight[q].b);
EditorPrefs.SetFloat(kEditorPrefsName + ".color.a" + q, colorLight[q].a);
EditorPrefs.SetFloat(kEditorPrefsName + ".dir.x" + q, dirLight[q].x);
EditorPrefs.SetFloat(kEditorPrefsName + ".dir.y" + q, dirLight[q].y);
}
}
}
public class BakeMaterial : EditorWindow
{
private static string kMateriBakeNodeName = "__MateriaBakeSetup";
private static Vector2 kWindowMinSize = new Vector2(300, 386);
private BakeMaterialSettings settings;
private static bool visible = false;
private GameObject camera;
private GameObject plane;
private Texture previewTexture;
private GameObject[] lights = new GameObject[BakeMaterialSettings.kLights];
private bool stateChanged = false;
private Vector2 texViewScrollPosition = Vector2.zero;
private Material lastMaterial;
private string originalScene = "";
private bool scheduleBakeOnNextUpdate = false;
private void SetupScene()
{
DestroyScene();
GameObject oldGo = GameObject.Find(kMateriBakeNodeName);
if (oldGo)
DestroyImmediate(oldGo);
camera = new GameObject(kMateriBakeNodeName, typeof(Camera));
plane = GameObject.CreatePrimitive(PrimitiveType.Plane);
Camera cam = camera.GetComponent<Camera>();
cam.backgroundColor = Color.black;
cam.clearFlags = CameraClearFlags.SolidColor;
cam.orthographic = true;
cam.orthographicSize = 5.0f;
cam.cullingMask = 1 << BakeMaterialSettings.kBakingLayerShouldBeUnusedInScene;
plane.transform.parent = cam.transform;
plane.transform.position = Vector3.forward * 10.0f;
plane.transform.rotation = Quaternion.Euler(0, 0, 180) * Quaternion.Euler(-90, 0, 0);
plane.layer = BakeMaterialSettings.kBakingLayerShouldBeUnusedInScene;
for(int i = 0; i < lights.Length; i++)
{
lights[i] = new GameObject();
lights[i].AddComponent<Light>();
var light = lights[i].GetComponent<Light>();
light.type = LightType.Directional;
light.cullingMask = 1 << BakeMaterialSettings.kBakingLayerShouldBeUnusedInScene;
lights[i].transform.parent = cam.transform;
lights[i].SetActive(false);
}
}
private void UpdateScene(Material m)
{
for (int q = 0; q < BakeMaterialSettings.kLights; ++q)
{
lights[q].SetActive(settings.useCustomLights & settings.enableLight[q]);
lights[q].GetComponent<Light>().color = settings.colorLight[q];
lights[q].transform.rotation =
Quaternion.AngleAxis(settings.dirLight[q].x, Vector3.up) *
Quaternion.AngleAxis(settings.dirLight[q].y, Vector3.right);
}
if (settings.useCustomLights)
RenderSettings.ambientLight = settings.ambient;
else if (settings.emptyScene)
RenderSettings.ambientLight = Color.white;
plane.GetComponent<Renderer>().material = m;
}
private void DestroyScene()
{
GameObject.DestroyImmediate(camera);
GameObject.DestroyImmediate(plane);
GameObject.DestroyImmediate(previewTexture);
}
RenderTexture UpdateMaterialPreview(Material m)
{
if (!m)
return null;
var saveAmbientLight = RenderSettings.ambientLight;
var saveMainTexture = m.mainTexture;
if (settings.bakeMainTexAsWhite)
m.mainTexture = null;
// setup
if (!camera)
SetupScene();
camera.SetActive(true);
UpdateScene(m);
var res = FindLargestTextureResolution(plane.GetComponent<Renderer>().sharedMaterial, settings.minTextureResolution, settings.maxTextureResolution);
var rt = RenderCameraToRenderTexture(camera.GetComponent<Camera>(), Mathf.FloorToInt(res.x), Mathf.FloorToInt(res.y));
// restore
camera.SetActive(false);
RenderSettings.ambientLight = saveAmbientLight;
m.mainTexture = saveMainTexture;
previewTexture = rt;
return rt;
}
void CaptureMaterial(Material m)
{
var matAssetPath = AssetDatabase.GetAssetPath(m);
var assetPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(matAssetPath), System.IO.Path.GetFileNameWithoutExtension(matAssetPath));
var rt = UpdateMaterialPreview(m);
RenderTextureToPNG(rt, settings.bakeAlpha, assetPath + ".png");
}
void OnEnable()
{
if (settings == null)
settings = new BakeMaterialSettings();
SetupScene();
visible = true;
}
void OnDisable()
{
DestroyScene();
settings.Save();
visible = false;
}
static Material GetTargetMaterial()
{
Material material = null;
var id = Selection.activeInstanceID;
if (id > 0)
{
var obj = EditorUtility.InstanceIDToObject(id);
if (obj != null)
{
var mesh = ((GameObject)obj).GetComponent<MeshRenderer>();
if (mesh != null)
{
material = mesh.material;
}
}
}
return material;
}
void OnSelectionChange()
{
Repaint();
}
void Update()
{
bool rebuildScene = false;
if (scheduleBakeOnNextUpdate)
{
Bake();
scheduleBakeOnNextUpdate = false;
rebuildScene = true;
}
if (originalScene == "" && EditorApplication.currentScene == "")
settings.emptyScene = true;
if (settings.emptyScene && originalScene == "" && EditorApplication.currentScene != "")
{
DestroyScene();
if (EditorApplication.SaveCurrentSceneIfUserWantsTo())
{
originalScene = EditorApplication.currentScene;
EditorApplication.NewScene();
}
else
settings.emptyScene = false;
rebuildScene = true;
}
else if (!settings.emptyScene && originalScene != "")
{
EditorApplication.OpenScene(originalScene);
rebuildScene = true;
originalScene = "";
}
if (rebuildScene)
{
SetupScene();
}
if (rebuildScene || stateChanged || !settings.emptyScene)
{
UpdateMaterialPreview(lastMaterial);
Repaint();
stateChanged = false;
}
}
void OnGUI()
{
var material = GetTargetMaterial();
if (material == null)
return;
if (lastMaterial != material)
UpdateMaterialPreview(material);
if (material)
lastMaterial = material;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.BeginVertical(GUILayout.MaxWidth(200));
if (!(originalScene == "" && EditorApplication.currentScene == ""))
{
settings.emptyScene = !EditorGUILayout.BeginToggleGroup("Scene ligthing", !settings.emptyScene);
EditorGUILayout.EndToggleGroup();
}
settings.useCustomLights = EditorGUILayout.BeginToggleGroup("Custom lighting", settings.useCustomLights);
if (settings.useCustomLights)
{
EditorGUI.indentLevel = 1;
settings.ambient = EditorGUILayout.ColorField("Ambient", settings.ambient);
for (int q = 0; q < BakeMaterialSettings.kLights; ++q)
{
settings.enableLight[q] = EditorGUILayout.BeginToggleGroup("Light", settings.enableLight[q]);
EditorGUI.indentLevel = 2;
settings.colorLight[q] = EditorGUILayout.ColorField("Color", settings.colorLight[q]);
settings.dirLight[q] = EditorGUILayout.Vector2Field("Direction", settings.dirLight[q]);
EditorGUILayout.EndToggleGroup();
}
}
EditorGUI.indentLevel = 0;
EditorGUILayout.EndToggleGroup();
settings.bakeAlpha = EditorGUILayout.Toggle("Bake Alpha", settings.bakeAlpha);
settings.bakeMainTexAsWhite = !EditorGUILayout.Toggle("MainTex", !settings.bakeMainTexAsWhite);
settings.minTextureResolution = EditorGUILayout.IntField("Min Resolution", settings.minTextureResolution);
settings.maxTextureResolution = EditorGUILayout.IntField("Max Resolution", settings.maxTextureResolution);
settings.minTextureResolution = Mathf.Max(2, settings.minTextureResolution);
settings.maxTextureResolution = Mathf.Max(settings.minTextureResolution, settings.maxTextureResolution);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Bake"))
{
CaptureMaterial(lastMaterial);
}
if (GUILayout.Button("Bake Selected"))
{
scheduleBakeOnNextUpdate = true;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
texViewScrollPosition = EditorGUILayout.BeginScrollView(texViewScrollPosition);
var r = GUILayoutUtility.GetAspectRect(1.0f);
if (previewTexture)
EditorGUI.DrawPreviewTexture(r, previewTexture);
EditorGUILayout.EndScrollView();
EditorGUILayout.EndHorizontal();
if (GUI.changed)
{
stateChanged = true;
}
}
[MenuItem("Tools/Bake Material ...", false, 5)]
static void CreateBakeEditor()
{
var window = EditorWindow.GetWindow(typeof(BakeMaterial));
window.minSize = kWindowMinSize;
window.Show();
}
[MenuItem("Tools/Bake Selected Materials", false, 4)]
static void Bake()
{
var instanceIDs = Selection.instanceIDs;
var currentScene = EditorApplication.currentScene;
var wasAlreadyVisible = BakeMaterial.visible;
var window = (BakeMaterial)EditorWindow.GetWindow(typeof(BakeMaterial));
if (window.settings.emptyScene)
{
if (!EditorApplication.SaveCurrentSceneIfUserWantsTo())
return;
EditorApplication.NewScene();
}
window.SetupScene();
foreach (var i in instanceIDs)
{
Material m = EditorUtility.InstanceIDToObject(i) as Material;
if (m)
window.CaptureMaterial(m);
}
window.DestroyScene();
if (!window.settings.emptyScene && !string.IsNullOrEmpty(currentScene))
{
EditorApplication.OpenScene(currentScene);
}
if (!wasAlreadyVisible)
window.Close();
}
static Vector2 FindLargestTextureResolution(Material m, int minTexRes, int maxTexRes)
{
var res = new Vector2(minTexRes, minTexRes);
foreach (var n in BakeMaterialSettings.kStandardTexNames)
{
if (!m.HasProperty(n))
continue;
Texture t = m.GetTexture(n);
if (!t)
continue;
res.x = Mathf.Max(res.x, t.width);
res.y = Mathf.Max(res.y, t.height);
}
res.x = Mathf.Min(res.x, maxTexRes);
res.y = Mathf.Min(res.y, maxTexRes);
return res;
}
static RenderTexture RenderCameraToRenderTexture(Camera cam, int width, int height)
{
var rt = cam.GetComponent<Camera>().targetTexture;
if (rt && rt.width != width && rt.height != height)
DestroyImmediate(rt);
if (!rt)
rt = new RenderTexture(width, height, 24);
cam.GetComponent<Camera>().targetTexture = rt;
cam.GetComponent<Camera>().Render();
return rt;
}
static void RenderTextureToPNG(RenderTexture rt, bool bakeAlpha, string assetPath)
{
RenderTexture.active = rt;
var screenShot = new Texture2D(rt.width, rt.height, bakeAlpha ? TextureFormat.ARGB32 : TextureFormat.RGB24, false);
screenShot.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
RenderTexture.active = null;
var bytes = screenShot.EncodeToPNG();
System.IO.File.WriteAllBytes(assetPath, bytes);
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
}
}
{
private static string kEditorPrefsName = "BakeMaterialSettings";
public static int kBakingLayerShouldBeUnusedInScene = 30;
public static string[] kStandardTexNames = { "_MainTex", "_BumpMap", "_Detail", "_ParallaxMap", "_Parallax" };
public bool bakeAlpha = false;
public bool bakeMainTexAsWhite = false;
public int minTextureResolution = 8;
public int maxTextureResolution = 2048;
public bool emptyScene = false;
public bool useCustomLights = false;
public Color ambient = Color.black;
public static int kLights = 3;
public bool[] enableLight = new bool[kLights];
public Color[] colorLight = new Color[kLights];
public Vector2[] dirLight = new Vector2[kLights];
public BakeMaterialSettings()
{
Load();
}
public void Load()
{
bakeAlpha = EditorPrefs.GetBool(kEditorPrefsName + ".bakeAlpha");
bakeMainTexAsWhite = EditorPrefs.GetBool(kEditorPrefsName + ".bakeMainTexAsWhite");
minTextureResolution = EditorPrefs.GetInt(kEditorPrefsName + ".minTextureResolution", 8);
maxTextureResolution = EditorPrefs.GetInt(kEditorPrefsName + ".maxTextureResolution", 2048);
emptyScene = EditorPrefs.GetBool(kEditorPrefsName + ".emptyScene");
useCustomLights = EditorPrefs.GetBool(kEditorPrefsName + ".useCustomLights");
ambient.r = EditorPrefs.GetFloat(kEditorPrefsName + ".ambient.r");
ambient.g = EditorPrefs.GetFloat(kEditorPrefsName + ".ambient.g");
ambient.b = EditorPrefs.GetFloat(kEditorPrefsName + ".ambient.b");
ambient.a = EditorPrefs.GetFloat(kEditorPrefsName + ".ambient.a", 1.0f);
for (int q = 0; q < kLights; ++q)
{
enableLight[q] = EditorPrefs.GetBool(kEditorPrefsName + ".enableLight" + q);
colorLight[q].r = EditorPrefs.GetFloat(kEditorPrefsName + ".color.r" + q, 0.5f);
colorLight[q].g = EditorPrefs.GetFloat(kEditorPrefsName + ".color.g" + q, 0.5f);
colorLight[q].b = EditorPrefs.GetFloat(kEditorPrefsName + ".color.b" + q, 0.5f);
colorLight[q].a = EditorPrefs.GetFloat(kEditorPrefsName + ".color.a" + q, 1.0f);
dirLight[q].x = EditorPrefs.GetFloat(kEditorPrefsName + ".dir.x" + q);
dirLight[q].y = EditorPrefs.GetFloat(kEditorPrefsName + ".dir.y" + q);
}
}
public void Save()
{
EditorPrefs.SetBool(kEditorPrefsName + ".bakeAlpha", bakeAlpha);
EditorPrefs.SetBool(kEditorPrefsName + ".bakeMainTexAsWhite", bakeMainTexAsWhite);
EditorPrefs.SetInt(kEditorPrefsName + ".minTextureResolution", minTextureResolution);
EditorPrefs.SetInt(kEditorPrefsName + ".maxTextureResolution", maxTextureResolution);
EditorPrefs.GetBool(kEditorPrefsName + ".emptyScene", emptyScene);
EditorPrefs.SetBool(kEditorPrefsName + ".useCustomLights", useCustomLights);
EditorPrefs.SetFloat(kEditorPrefsName + ".ambient.r", ambient.r);
EditorPrefs.SetFloat(kEditorPrefsName + ".ambient.g", ambient.g);
EditorPrefs.SetFloat(kEditorPrefsName + ".ambient.b", ambient.b);
EditorPrefs.SetFloat(kEditorPrefsName + ".ambient.a", ambient.a);
for (int q = 0; q < kLights; ++q)
{
EditorPrefs.SetBool(kEditorPrefsName + ".enableLight" + q, enableLight[q]);
EditorPrefs.SetFloat(kEditorPrefsName + ".color.r" + q, colorLight[q].r);
EditorPrefs.SetFloat(kEditorPrefsName + ".color.g" + q, colorLight[q].g);
EditorPrefs.SetFloat(kEditorPrefsName + ".color.b" + q, colorLight[q].b);
EditorPrefs.SetFloat(kEditorPrefsName + ".color.a" + q, colorLight[q].a);
EditorPrefs.SetFloat(kEditorPrefsName + ".dir.x" + q, dirLight[q].x);
EditorPrefs.SetFloat(kEditorPrefsName + ".dir.y" + q, dirLight[q].y);
}
}
}
public class BakeMaterial : EditorWindow
{
private static string kMateriBakeNodeName = "__MateriaBakeSetup";
private static Vector2 kWindowMinSize = new Vector2(300, 386);
private BakeMaterialSettings settings;
private static bool visible = false;
private GameObject camera;
private GameObject plane;
private Texture previewTexture;
private GameObject[] lights = new GameObject[BakeMaterialSettings.kLights];
private bool stateChanged = false;
private Vector2 texViewScrollPosition = Vector2.zero;
private Material lastMaterial;
private string originalScene = "";
private bool scheduleBakeOnNextUpdate = false;
private void SetupScene()
{
DestroyScene();
GameObject oldGo = GameObject.Find(kMateriBakeNodeName);
if (oldGo)
DestroyImmediate(oldGo);
camera = new GameObject(kMateriBakeNodeName, typeof(Camera));
plane = GameObject.CreatePrimitive(PrimitiveType.Plane);
Camera cam = camera.GetComponent<Camera>();
cam.backgroundColor = Color.black;
cam.clearFlags = CameraClearFlags.SolidColor;
cam.orthographic = true;
cam.orthographicSize = 5.0f;
cam.cullingMask = 1 << BakeMaterialSettings.kBakingLayerShouldBeUnusedInScene;
plane.transform.parent = cam.transform;
plane.transform.position = Vector3.forward * 10.0f;
plane.transform.rotation = Quaternion.Euler(0, 0, 180) * Quaternion.Euler(-90, 0, 0);
plane.layer = BakeMaterialSettings.kBakingLayerShouldBeUnusedInScene;
for(int i = 0; i < lights.Length; i++)
{
lights[i] = new GameObject();
lights[i].AddComponent<Light>();
var light = lights[i].GetComponent<Light>();
light.type = LightType.Directional;
light.cullingMask = 1 << BakeMaterialSettings.kBakingLayerShouldBeUnusedInScene;
lights[i].transform.parent = cam.transform;
lights[i].SetActive(false);
}
}
private void UpdateScene(Material m)
{
for (int q = 0; q < BakeMaterialSettings.kLights; ++q)
{
lights[q].SetActive(settings.useCustomLights & settings.enableLight[q]);
lights[q].GetComponent<Light>().color = settings.colorLight[q];
lights[q].transform.rotation =
Quaternion.AngleAxis(settings.dirLight[q].x, Vector3.up) *
Quaternion.AngleAxis(settings.dirLight[q].y, Vector3.right);
}
if (settings.useCustomLights)
RenderSettings.ambientLight = settings.ambient;
else if (settings.emptyScene)
RenderSettings.ambientLight = Color.white;
plane.GetComponent<Renderer>().material = m;
}
private void DestroyScene()
{
GameObject.DestroyImmediate(camera);
GameObject.DestroyImmediate(plane);
GameObject.DestroyImmediate(previewTexture);
}
RenderTexture UpdateMaterialPreview(Material m)
{
if (!m)
return null;
var saveAmbientLight = RenderSettings.ambientLight;
var saveMainTexture = m.mainTexture;
if (settings.bakeMainTexAsWhite)
m.mainTexture = null;
// setup
if (!camera)
SetupScene();
camera.SetActive(true);
UpdateScene(m);
var res = FindLargestTextureResolution(plane.GetComponent<Renderer>().sharedMaterial, settings.minTextureResolution, settings.maxTextureResolution);
var rt = RenderCameraToRenderTexture(camera.GetComponent<Camera>(), Mathf.FloorToInt(res.x), Mathf.FloorToInt(res.y));
// restore
camera.SetActive(false);
RenderSettings.ambientLight = saveAmbientLight;
m.mainTexture = saveMainTexture;
previewTexture = rt;
return rt;
}
void CaptureMaterial(Material m)
{
var matAssetPath = AssetDatabase.GetAssetPath(m);
var assetPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(matAssetPath), System.IO.Path.GetFileNameWithoutExtension(matAssetPath));
var rt = UpdateMaterialPreview(m);
RenderTextureToPNG(rt, settings.bakeAlpha, assetPath + ".png");
}
void OnEnable()
{
if (settings == null)
settings = new BakeMaterialSettings();
SetupScene();
visible = true;
}
void OnDisable()
{
DestroyScene();
settings.Save();
visible = false;
}
static Material GetTargetMaterial()
{
Material material = null;
var id = Selection.activeInstanceID;
if (id > 0)
{
var obj = EditorUtility.InstanceIDToObject(id);
if (obj != null)
{
var mesh = ((GameObject)obj).GetComponent<MeshRenderer>();
if (mesh != null)
{
material = mesh.material;
}
}
}
return material;
}
void OnSelectionChange()
{
Repaint();
}
void Update()
{
bool rebuildScene = false;
if (scheduleBakeOnNextUpdate)
{
Bake();
scheduleBakeOnNextUpdate = false;
rebuildScene = true;
}
if (originalScene == "" && EditorApplication.currentScene == "")
settings.emptyScene = true;
if (settings.emptyScene && originalScene == "" && EditorApplication.currentScene != "")
{
DestroyScene();
if (EditorApplication.SaveCurrentSceneIfUserWantsTo())
{
originalScene = EditorApplication.currentScene;
EditorApplication.NewScene();
}
else
settings.emptyScene = false;
rebuildScene = true;
}
else if (!settings.emptyScene && originalScene != "")
{
EditorApplication.OpenScene(originalScene);
rebuildScene = true;
originalScene = "";
}
if (rebuildScene)
{
SetupScene();
}
if (rebuildScene || stateChanged || !settings.emptyScene)
{
UpdateMaterialPreview(lastMaterial);
Repaint();
stateChanged = false;
}
}
void OnGUI()
{
var material = GetTargetMaterial();
if (material == null)
return;
if (lastMaterial != material)
UpdateMaterialPreview(material);
if (material)
lastMaterial = material;
EditorGUILayout.BeginHorizontal();
EditorGUILayout.BeginVertical(GUILayout.MaxWidth(200));
if (!(originalScene == "" && EditorApplication.currentScene == ""))
{
settings.emptyScene = !EditorGUILayout.BeginToggleGroup("Scene ligthing", !settings.emptyScene);
EditorGUILayout.EndToggleGroup();
}
settings.useCustomLights = EditorGUILayout.BeginToggleGroup("Custom lighting", settings.useCustomLights);
if (settings.useCustomLights)
{
EditorGUI.indentLevel = 1;
settings.ambient = EditorGUILayout.ColorField("Ambient", settings.ambient);
for (int q = 0; q < BakeMaterialSettings.kLights; ++q)
{
settings.enableLight[q] = EditorGUILayout.BeginToggleGroup("Light", settings.enableLight[q]);
EditorGUI.indentLevel = 2;
settings.colorLight[q] = EditorGUILayout.ColorField("Color", settings.colorLight[q]);
settings.dirLight[q] = EditorGUILayout.Vector2Field("Direction", settings.dirLight[q]);
EditorGUILayout.EndToggleGroup();
}
}
EditorGUI.indentLevel = 0;
EditorGUILayout.EndToggleGroup();
settings.bakeAlpha = EditorGUILayout.Toggle("Bake Alpha", settings.bakeAlpha);
settings.bakeMainTexAsWhite = !EditorGUILayout.Toggle("MainTex", !settings.bakeMainTexAsWhite);
settings.minTextureResolution = EditorGUILayout.IntField("Min Resolution", settings.minTextureResolution);
settings.maxTextureResolution = EditorGUILayout.IntField("Max Resolution", settings.maxTextureResolution);
settings.minTextureResolution = Mathf.Max(2, settings.minTextureResolution);
settings.maxTextureResolution = Mathf.Max(settings.minTextureResolution, settings.maxTextureResolution);
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button("Bake"))
{
CaptureMaterial(lastMaterial);
}
if (GUILayout.Button("Bake Selected"))
{
scheduleBakeOnNextUpdate = true;
}
EditorGUILayout.EndHorizontal();
EditorGUILayout.EndVertical();
texViewScrollPosition = EditorGUILayout.BeginScrollView(texViewScrollPosition);
var r = GUILayoutUtility.GetAspectRect(1.0f);
if (previewTexture)
EditorGUI.DrawPreviewTexture(r, previewTexture);
EditorGUILayout.EndScrollView();
EditorGUILayout.EndHorizontal();
if (GUI.changed)
{
stateChanged = true;
}
}
[MenuItem("Tools/Bake Material ...", false, 5)]
static void CreateBakeEditor()
{
var window = EditorWindow.GetWindow(typeof(BakeMaterial));
window.minSize = kWindowMinSize;
window.Show();
}
[MenuItem("Tools/Bake Selected Materials", false, 4)]
static void Bake()
{
var instanceIDs = Selection.instanceIDs;
var currentScene = EditorApplication.currentScene;
var wasAlreadyVisible = BakeMaterial.visible;
var window = (BakeMaterial)EditorWindow.GetWindow(typeof(BakeMaterial));
if (window.settings.emptyScene)
{
if (!EditorApplication.SaveCurrentSceneIfUserWantsTo())
return;
EditorApplication.NewScene();
}
window.SetupScene();
foreach (var i in instanceIDs)
{
Material m = EditorUtility.InstanceIDToObject(i) as Material;
if (m)
window.CaptureMaterial(m);
}
window.DestroyScene();
if (!window.settings.emptyScene && !string.IsNullOrEmpty(currentScene))
{
EditorApplication.OpenScene(currentScene);
}
if (!wasAlreadyVisible)
window.Close();
}
static Vector2 FindLargestTextureResolution(Material m, int minTexRes, int maxTexRes)
{
var res = new Vector2(minTexRes, minTexRes);
foreach (var n in BakeMaterialSettings.kStandardTexNames)
{
if (!m.HasProperty(n))
continue;
Texture t = m.GetTexture(n);
if (!t)
continue;
res.x = Mathf.Max(res.x, t.width);
res.y = Mathf.Max(res.y, t.height);
}
res.x = Mathf.Min(res.x, maxTexRes);
res.y = Mathf.Min(res.y, maxTexRes);
return res;
}
static RenderTexture RenderCameraToRenderTexture(Camera cam, int width, int height)
{
var rt = cam.GetComponent<Camera>().targetTexture;
if (rt && rt.width != width && rt.height != height)
DestroyImmediate(rt);
if (!rt)
rt = new RenderTexture(width, height, 24);
cam.GetComponent<Camera>().targetTexture = rt;
cam.GetComponent<Camera>().Render();
return rt;
}
static void RenderTextureToPNG(RenderTexture rt, bool bakeAlpha, string assetPath)
{
RenderTexture.active = rt;
var screenShot = new Texture2D(rt.width, rt.height, bakeAlpha ? TextureFormat.ARGB32 : TextureFormat.RGB24, false);
screenShot.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
RenderTexture.active = null;
var bytes = screenShot.EncodeToPNG();
System.IO.File.WriteAllBytes(assetPath, bytes);
AssetDatabase.ImportAsset(assetPath, ImportAssetOptions.ForceUpdate);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment