- 浏览: 264588 次
- 性别:
- 来自: 大连
文章分类
最新评论
复杂材质烘焙成一张贴图
- 博客分类:
- Unity3D
这个脚本可以将复杂的材质,比如有法线贴图的材质进行"烘焙",转变为单一的贴图,可用来将
将这个脚本放Editor文件夹里,使用时选择一个Material材质,然后在菜单种"Custom/Bake Material"打开并调整照明和其他参数,点击Bake按钮,就会生成一个单一的贴图.
脚本:BakeMaterial.js
将这个脚本放Editor文件夹里,使用时选择一个Material材质,然后在菜单种"Custom/Bake Material"打开并调整照明和其他参数,点击Bake按钮,就会生成一个单一的贴图.
脚本:BakeMaterial.js
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); } }
发表评论
-
unity Mathf 数学运算(C#)
2013-05-14 15:32 4078Mathf 数学运算Mathf.Abs绝 ... -
Unity3D与VS2008结合
2013-03-07 13:24 2990mono出问题了,打开之后总是没反应,憋的我只能另想办法了,还 ... -
按自身本地坐标移动
2012-11-09 11:10 0transform.Translate( new Vector ... -
Transform.eulerAngles
2012-09-19 11:20 6137eulerAngles的三个变量,x,y,z表示三个绕坐标轴旋 ... -
UNITY3D开发IOS 强制屏幕四个方向不旋转的方法
2012-09-18 13:32 7252void Start () { //纵向 上下 ... -
Unity Mathf 数学运算(C#)
2012-09-17 10:27 107607Mathf.Abs绝对值 计算并返回指定参数 f 绝对值。 ... -
xxx.unity3d 这种文件怎么打开呢`
2012-09-03 10:26 0unity3d是在unity编辑器下编辑模型,然后使用unit ... -
unity3d协作过程中svn的使用
2012-06-20 14:42 1552算是从unity3d官方网站上的翻译,如果你没有看到,可以看下 ... -
Unity3D 里的单例模式(转)
2012-05-04 16:15 2276在Unity3D中可以用不同的方法来实现单例,第一种是通常用法 ... -
unity3d换贴图
2012-04-25 11:51 0//换贴图,直接把这段代码加在要换贴图的模型上即可 ... -
unity3d 修改 webplayer 的logo
2012-03-30 13:48 3899经过测试,以下两种方式都是可以的。 第一种,加到<sc ... -
[转载]Unity3d闪烁灯光脚本
2012-03-29 09:05 1850using UnityEngine; using ... -
Unity引擎链接mySQL数据库
2012-03-29 08:58 5067需要unity3d3.5 pro版本,所以先确认自己用的是不是 ... -
在Unity3D里使用JSON格式进行数据交换(转)
2012-03-29 08:55 12742这个例子里做的事情很简单,主要做了两件事: 1 从服务器的p ... -
unity3d调用外部摄像头
2012-03-26 15:24 0public string deviceName; ... -
天气系统
2012-03-21 08:37 0var lightmapFarsFirst:Texture ... -
Unity3D鼠标响应事件
2012-03-19 10:14 0void OnMouseDrag () { ... -
javaScript改变skybox
2012-03-07 23:38 1132var dayMaterial:Material; va ... -
Unity 3D 入门常见问题
2012-02-29 10:12 3814下面列出了常见的问题. 文档 Unity 手册 -- 包含用 ... -
UNITY3D常用代码
2012-02-28 08:51 001、基本碰撞检测代码 function OnCollis ...
相关推荐
【烘焙材质到单一贴图的脚本2】是Unity3D中的一个自定义脚本,主要功能是将具有复杂纹理和光照信息的材质简化为一张单一的贴图,以适应移动平台等资源有限的环境。这个过程通常被称为“烘焙”(Baking),它将原本...
《烘焙到材质脚本2》是针对Unity3D游戏开发中的一个重要工具,它主要用于优化复杂的材质,特别是包含法线贴图的材质。在Unity中,法线贴图用于模拟物体表面的微小细节,增加真实感,但这些复杂的计算会消耗大量资源...
通过烘焙,可以将复杂的光照效果(如环境光遮蔽、阴影等)转化为简单的纹理贴图,从而减少实时计算量,提高游戏运行效率。 #### 二、Unity3d烘焙贴图工作流程 1. **UVW贴图处理**: - 完成模型的UVW贴图制作,...
在Unity中,“烘焙到材质”的技术主要用于处理那些包含高级光照效果(如法线贴图)的复杂材质。通过将这些复杂材质烘焙成一张或几张单一的纹理贴图,可以极大地减少实时渲染的计算量,这对于性能有限的移动设备来说...
在Unity引擎中,光照贴图烘焙(Lightmap Baking)是一种优化光照计算的方法,它可以将复杂的光照信息预先计算并存储到贴图中,以便在运行时以较低的性能成本渲染场景。然而,当游戏场景中存在大量预制体(Prefab)且...
在Unity引擎中,烘焙贴图(Baked Lightmaps)是一种优化光照处理的技术,它将静态光照信息预先计算并存储在纹理中,以减少运行时的计算负担。在Unity5.x版本中,开发者可以实现动态添加烘焙贴图的功能,这对于那些...
在Unity中,烘焙贴图将光照信息编码到纹理中,这些纹理随后被应用到游戏对象的材质上,使得在运行时无需进行复杂的实时光照计算。这一过程包括光照数据的捕捉、转换和存储,通常包括光照贴图(Lightmaps)和阴影贴图...
在Unity3D游戏开发中,灯光烘焙是一种优化技术,它能够预先计算光照信息并存储到贴图中,从而减轻运行时的计算负担。然而,在实际应用中,烘焙灯光贴图可能会遇到一些问题,如阴影丢失或法线效果不正确。本文将详细...
- **多材质烘焙**:当一个模型包含多种材质时,可以使用不同的UV通道来烘焙不同的材质。这样可以更好地利用UV空间,提高贴图的分辨率。 - **纹理翻耕**:对于复杂场景,可以通过多次烘焙和合并纹理的方式来优化最终...
5. **统一材质类型**:所有模型的材质球应设置为Lambert 1,这是Maya的基本漫反射材质,适合烘焙。 烘焙Normal Map(法线贴图)的步骤如下: 1. 在Maya的Rendering选项卡中,展开Lighting/Shading,选择Transfer ...
Unity烘焙教程 for 3dsMax 本教程主要讲述了如何在Unity中导入和使用烘焙贴图,从3dsMax中...本教程提供了详细的指导,帮助用户快速掌握Unity中的烘焙贴图和Lightmapped 材料的使用,并提高模型的现实感和材质效果。
在虚拟现实和游戏开发中,烘焙贴图是一种常见的优化光照效果的技术,它允许开发者在有限的硬件资源下实现接近真实光照的表现...同时,烘焙过程中的等待时间也是一个重要因素,复杂的模型可能需要较长时间才能完成烘焙。
动画烘焙是将复杂的动画逻辑和计算转换为预烘焙的数据,以便在游戏中实时播放时减少CPU负担。这包括将骨骼动画、蒙皮权重、IK(反向动力学)解决方案等预先计算并存储,使得在游戏运行时可以快速读取和播放,提高...
它能存储包括几何数据、材质、纹理、骨骼动画等多种信息,方便在不同软件之间交换模型数据。在这个模型中,FBX文件包含了低模的几何信息,可以导入到各种3D软件或游戏引擎中进行进一步处理或展示。 2048的贴图文件...
冷冻烘焙行业作为现代食品工业的一个分支,近年来在中国市场展现出强劲的成长动力和发展潜力。立高食品作为冷冻烘焙领域的先行者之一,在该行业中占据了有利的市场地位。以下将从多个方面详细解读冷冻烘焙行业的相关...
因为优化对于游戏至关重要,特别是那些针对移动设备(甚至更多在 VR 中)的游戏,Super Combiner 将烘焙材质和网格,充分利用静态和动态批处理。 绝对非破坏性工作流程(源资产保持绝对完整) 非常容易使用且优化的...
i烘焙商业计划书.pdfi烘焙商业计划书.pdfi烘焙商业计划书.pdfi烘焙商业计划书.pdfi烘焙商业计划书.pdfi烘焙商业计划书.pdfi烘焙商业计划书.pdfi烘焙商业计划书.pdfi烘焙商业计划书.pdfi烘焙商业计划书.pdfi烘焙商业...
它使用原生的 Blender 烘焙操作符来烘焙基于 PBR 的贴图、默认的 Blender Cycles 贴图和特殊蒙版贴图。该插件发出并推进了 Blender 的烘焙过程,使其成为适用于任何场景设置的强大、功能齐全的一站式解决方案。...
首先,LightMapping是Unity3D的一种光照预计算技术,它将复杂的光照计算结果烘焙到场景中的物体表面,从而在运行时减少GPU的负载。烘焙过程包括计算全局光照、阴影和环境光等,并存储在纹理中。通常,LightMapping是...