博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Unity 烘焙材质到单一贴图的脚本
阅读量:5330 次
发布时间:2019-06-14

本文共 15844 字,大约阅读时间需要 52 分钟。

原地址:http://www.cocoachina.com/gamedev/gameengine/2011/0406/2756.html

这个脚本由 CocoaChina 版主 “四角钱” 分享,可以将复杂的材质(比如有法线贴图的材质)进行"烘焙",转变为单一的贴图。可用来将 Unity 的游戏移植到移动平台时候使用。请将脚本放 Editor 文件夹里,使用时选择一个 Material 材质,然后在菜单种"Custom/Bake Material"打开并调整照明和其他参数,点击Bake按钮就会生成一个单一的贴图。

class BakeMaterialSettings{    private static var kEditorPrefsName = "BakeMaterialSettings";        static var kBakingLayerShouldBeUnusedInScene = 30;    static var kStandardTexNames = new Array ("_MainTex", "_BumpMap", "_Detail", "_ParallaxMap", "_Parallax");    var bakeAlpha = false;    var bakeMainTexAsWhite = false;    var minTextureResolution = 8;    var maxTextureResolution = 2048;    var emptyScene = false;    var useCustomLights = false;    var ambient = Color.black;        static var kLights = 3;    var enableLight = new boolean[kLights];    var colorLight = new Color[kLights];    var dirLight = new Vector2[kLights];        function BakeMaterialSettings ()    {        Load ();    }        function 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 (var 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);        }    }        function 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 (var 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);        }    }}class BakeMaterial extends EditorWindow{    private static var kMateriBakeNodeName = "__MateriaBakeSetup";    private static var kWindowMinSize = Vector2 (300, 386);        private static var settings : BakeMaterialSettings;    private static var visible : boolean = false;        private var camera : GameObject;    private var plane : GameObject;    private var previewTexture : Texture;    private var lights : GameObject[] = new GameObject[BakeMaterialSettings.kLights];    private var stateChanged = false;        private var texViewScrollPosition = Vector2.zero;    private var lastMaterial : Material;        private var originalScene = "";        private var scheduleBakeOnNextUpdate = false;        private function SetupScene ()    {        DestroyScene ();        var oldGo = GameObject.Find(kMateriBakeNodeName);        if (oldGo)            DestroyImmediate (oldGo);        camera = new GameObject (kMateriBakeNodeName, Camera);        plane = GameObject.CreatePrimitive (PrimitiveType.Plane);        var cam = camera;        cam.camera.backgroundColor = Color.black;        cam.camera.clearFlags = CameraClearFlags.SolidColor;        cam.camera.orthographic = true;        cam.camera.orthographicSize = 5.0;        cam.camera.cullingMask = 1 << settings.kBakingLayerShouldBeUnusedInScene;                plane.transform.parent = cam.transform;        plane.transform.position = Vector3.forward * 10.0;        plane.transform.rotation = Quaternion.Euler (0, 0, 180) * Quaternion.Euler (-90, 0, 0);        plane.layer = settings.kBakingLayerShouldBeUnusedInScene;                for (var l in lights)        {            l = new GameObject ("Light", Light);            l.light.type = LightType.Directional;            l.light.cullingMask = 1 << settings.kBakingLayerShouldBeUnusedInScene;            l.transform.parent = cam.transform;            l.active = false;        }    }        private function UpdateScene (m : Material)    {        for (q = 0; q < settings.kLights; ++q)        {            lights[q].active = settings.useCustomLights & settings.enableLight[q];            lights[q].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.renderer.material = m;    }            private function DestroyScene ()    {        GameObject.DestroyImmediate (camera);        GameObject.DestroyImmediate (plane);        GameObject.DestroyImmediate (previewTexture);    }    function UpdateMaterialPreview (m : Material) : RenderTexture    {        if (!m)            return;                var saveAmbientLight = RenderSettings.ambientLight;        var saveMainTexture = m.mainTexture;        if (settings.bakeMainTexAsWhite)            m.mainTexture = null;                    // setup        if (!camera)            SetupScene ();        camera.SetActiveRecursively(true);        UpdateScene (m);                var res = FindLargestTextureResolution (plane.renderer.sharedMaterial, settings.minTextureResolution, settings.maxTextureResolution);        var rt = RenderCameraToRenderTexture (camera.camera, res.x, res.y);                // restore        camera.SetActiveRecursively(false);        RenderSettings.ambientLight = saveAmbientLight;        m.mainTexture = saveMainTexture;                previewTexture = rt;        return rt;    }        function CaptureMaterial(m : Material)    {        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");    }    function OnEnable ()    {        if (!settings)            settings = new BakeMaterialSettings ();        SetupScene ();        visible = true;    }        function OnDisable ()    {        DestroyScene ();        settings.Save ();        visible = false;    }    static function GetTargetMaterial () : Material    {        return EditorUtility.InstanceIDToObject (Selection.activeInstanceID) as Material;    }    function OnSelectionChange ()    {        Repaint ();    }    function Update ()    {        var 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;        }    }        function OnGUI ()    {        var material = GetTargetMaterial ();        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 (var q = 0; q < settings.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("Custom/Bake Material ...", false, 5)    static function CreateBakeEditor()    {        var window = EditorWindow.GetWindow(BakeMaterial);        window.title = "Bake Material";        window.minSize = kWindowMinSize;        window.Show();    }    @MenuItem("Custom/Bake Selected Materials", false, 4)    static function Bake()    {        var instanceIDs = Selection.instanceIDs;        var currentScene = EditorApplication.currentScene;            var wasAlreadyVisible = BakeMaterial.visible;        var window = EditorWindow.GetWindow(BakeMaterial);                if (window.settings.emptyScene)        {            if (!EditorApplication.SaveCurrentSceneIfUserWantsTo ())                return;            EditorApplication.NewScene ();        }                window.SetupScene ();        for (var i in instanceIDs)        {            var m : Material = EditorUtility.InstanceIDToObject (i) as Material;            if (m)                window.CaptureMaterial (m);        }        window.DestroyScene ();                if (window.settings.emptyScene && currentScene)        {            EditorApplication.OpenScene (currentScene);        }                if (!wasAlreadyVisible)            window.Close ();    }        static function FindLargestTextureResolution (m : Material, minTexRes : int, maxTexRes : int) : Vector2    {        var res = Vector2 (minTexRes, minTexRes);        for (var n in BakeMaterialSettings.kStandardTexNames)        {            if (!m.HasProperty (n))                continue;                    var t : Texture = 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 function RenderCameraToRenderTexture (cam : Camera, width : int, height : int) : RenderTexture    {        var rt = cam.camera.targetTexture;        if (rt && rt.width != width && rt.height != height)            DestroyImmediate(rt);        if (!rt)            rt = new RenderTexture (width, height, 24);        cam.camera.targetTexture = rt;        cam.camera.Render ();        return rt;    }        static function RenderTextureToPNG (rt : RenderTexture, bakeAlpha : boolean, assetPath : String)    {        RenderTexture.active = rt;                var screenShot = new Texture2D (rt.width, rt.height, bakeAlpha? TextureFormat.ARGB32 : TextureFormat.RGB24, false);        screenShot.ReadPixels (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);    }}

  

转载于:https://www.cnblogs.com/123ing/p/3703739.html

你可能感兴趣的文章
【luogu P2298 Mzc和男家丁的游戏】 题解
查看>>
前端笔记-bom
查看>>
MATLAB作图方法与技巧(一)
查看>>
上海淮海中路上苹果旗舰店门口欲砸一台IMAC电脑维权
查看>>
Google透露Android Market恶意程序扫描服务
查看>>
给mysql数据库字段值拼接前缀或后缀。 concat()函数
查看>>
迷宫问题
查看>>
【FZSZ2017暑假提高组Day9】猜数游戏(number)
查看>>
泛型子类_属性类型_重写方法类型
查看>>
eclipse-将同一个文件分屏显示
查看>>
mysql5.x升级至mysql5.7后导入之前数据库date出错的解决方法!
查看>>
对闭包的理解
查看>>
练习10-1 使用递归函数计算1到n之和(10 分
查看>>
Oracle MySQL yaSSL 不明细节缓冲区溢出漏洞2
查看>>
windows编程ASCII问题
查看>>
.net webService代理类
查看>>
Code Snippet
查看>>
Node.js Express项目搭建
查看>>
zoj 1232 Adventure of Super Mario
查看>>
1201 网页基础--JavaScript(DOM)
查看>>