Unity烘焙材质到单一贴图的脚本
unity3d游戏开发之UV贴图教程

UV贴图教程一、理解UV贴图UVs是驻留在多边形网格顶点上的两维纹理坐标点,它们定义了一个两维纹理坐标系统,称为UV纹理空间,这个空间用U和V两个字母定义坐标轴。
用于确定如何将一个纹理图像放置在三维的模型表面。
本质上,UVs是提供了一种模型表面与纹理图像之间的连接关系,UVs负责确定纹理图像上的一个点(像素)应该放置在模型表面的哪一个顶点上,由此可将整个纹理都铺盖到模型上。
如果没有UVs,多边形网格将不能被渲染出纹理。
通常在创建MAYA原始对象时,UVs一般都被自动创建(在创建参数面板上有一个Create UVs选项,默认是勾选的),但大部分情况下,我们还是需要重新安排UVs,因为,在编辑修改模型时,UVs不会自动更新改变位置。
重新安排UVs,一般是在模型完全做好之后,并且在指定纹理贴图之前进行。
此外,任何对模型的修改都可能会造成模型顶点与UVs的错位,从而使纹理贴图出现错误。
更多精彩请点击【狗刨学习网】二、UVs和纹理映射NURBS表面与多边形网格的贴图机制不同,NURBS表面的UV是内建的(已经自动定义出U、V),这些UV不能被编辑,移动CV将会影响纹理贴图。
而多边形的UVs并非一开始就存在,还必须明确地创建并且可以随后进一步修改编辑。
三、UV贴图为一个表面创建UVs的过程叫UV贴图(UV mapping)。
这个过程包括创建、编辑。
其结果是明确地决定图像如何在三维模型上显示,这项技术的熟练程度直接影响模型的最后表现。
四、创建UVsMaya中有很多UVs创建工具:如,自动UV工具、平面UV工具、圆柱UV工具、球形UV工具、用户自定义UV工具等。
每种创建工具都是使用一种预定的规则将UV纹理坐标投射到模型表面,自动创建纹理图像与表面的关联。
通常,对自动产生的UV还必须使用UV编辑器进一步编辑才能达到所需要的效果。
因为每次对模型的修改(如挤压,缩放,增加、删除等等)都会造成UVs错位,所以最好的工作流程是等模型完全设计好了之后,再开始创建UVs。
Unity3DMonoDevelop脚本编辑器介绍

Unity3DMonoDevelop脚本编辑器介绍Mono Develop脚本编辑器介绍Unity3D⽬前⽀持三种语⾔的脚本,包括c#、JavaScript、Boo,在⼀个游戏中开发者可以使⽤⼀种或者同时使⽤多种语⾔来实现脚本的控制。
三种不同的语⾔其实效率是相当的,最后都会编译成Unity3D内置的中间代码。
⽬前国内⽤c#的占⼤多数。
注意:1、项⽬运⾏过程中的修改不回保存。
2、脚本只能依附于对象或由其他脚本⽤才能运⾏。
3、⼀个脚本可以放在多个游戏对象上⾯,是多个实例。
4、⼀个脚本的多个实例和其他脚本之间互补⼲扰。
脚本编辑器的介绍:脚本在Project中的显⽰名称不要加cs,类名要和cs名称⼀致,所有类继承⾃MOnoBehaviour。
项⽬⼯程分层设计:Scenes:存放场景Scripts:存放脚本Resources:存放资源包Pesfabs:预设体Textures:贴图Materials:材质(主要为.mat ⽂件)Audios:声⾳Models:模型(存放FBX等⽂件)初始化不要放到构造函数中,⽽是放到Start()⽅法中。
放到游戏对象中的脚本(实例化)可以在Inspector中修改属性,get/set写法属性不被识别,直接public字段就能当属性⽤,不写修饰符就是私有private。
VS编辑器1、更改默认的开发⼯具,由MonoDev-->VS2、具体更改步骤:Edit-->Preference-->Extennal Tools-->External Tools-->External script EditorEdit-->preferences-->Extemal Tools-->Extemal Script Editor-->D:\Program Files\Microsoft Visual Studio 12.0\Common7\IDE-->devenv.exe-->关闭狗刨学习⽹,更多资源、博⽂、视频、教程供您免费下载。
Unity3D光照贴图烘焙知识详解

Unity3D光照贴图烘焙知识详解欢迎来到unity学习、unity培训、unity企业培训教育专区,这里有很多U3D资源、U3D 培训视频、U3D教程、U3D常见问题、U3D项目源码,我们致力于打造业内unity3d培训、学习第一品牌。
今天简单地跟大家分享一下Unity5.0里面的光照贴图烘焙技术。
由于时间只有20分钟,所以只能给大家一些概要性的介绍,没有办法深入,等到Unity5.0版本正式推出之后,我会给大家一些更详细的介绍。
接下来我会分3个部分跟大家讲解,第一部分讲解一下在以往的Unity版本中所采用的光照烘焙方法,以及Unity5.0中为什么会采用一套全新的光照贴图烘焙方法。
第二部分讲解Imagination的PowerVR Ray Tracing方法。
第三部分讲解Geomerics的Enlighten方法。
后两种方法都会被引入到Unity 5.0版本当中去。
首先我们来介绍Unity在4.X版本里面使用光照烘焙的方法。
我们采用的是Autodesk的Beast,而我们在5.0版本中可能会把它彻底移除。
这是为什么呢?我们先介绍一下Beast的弱点吧。
Beast只能烘焙静态的光照贴图,而不支持动态光照。
一般而言,使用Beast的工作流程是:先建造一个场景,然后在场景中布置各种光源,进而点击Bake操作键,接下来大家就可以喝喝咖啡,或者直接下班回家了,因为整个烘焙过程可能需要几分钟、几小时,甚至是更长的时间。
这样的过程还不一定得到正确的结果,如果发现前面的烘焙结果存在问题,还要重新返回到第一步,直至得到满意的烘焙结果。
这样的过程对于广大开发者来说肯定是一个不太友好的过程,势必会影响大家的工作效率。
那么既然我们说原来的方法存在着一定的问题,那么理想的光照方案是什么样的呢?第一,理想的方法不需要任何的预计算时间;第二,它能够让场景中所有与光照有关的信息都能够实现动态改变,比如说动态改变光源、改变材质、改变环境光照,甚至改变场景中几何体的形状;第三,这样的一套方法还需要做到实时渲染,这不仅包括Console设备,也包括我们手中的移动设备。
Unity3D教程:Unity批量处理修改烘培LightMap

中国第一免费Unity3D教程手册
Unity3D教程:Unity批量处理修改烘培LightMap
用Unity烘培后的多重纹理不能直接转到Unity中,还需要一个个的手动指认Shader。
在Max 里建立你的模型,然后Diffuse Map贴这个模型上,导出一个Fbx文件,然后再相同的模型和相同的Diffuse Map通道上,贴好烘培图,同样导出一个Fbx文件,最终的结果是2个Fbx文件,模型是相同的,其中一个包含材质UV信息,另一个包含LightMap 材质UV信息。
这个Unity资源包包含两个编辑器脚本,即"合并"两个模型网格和将一个模型上的UVs复制到另一个模型物体上并创建一个文本文件记录UV坐标信息.其他的脚本是重新导入Fbx物体的时候重新赋予UVs。
它还能自动设置所有LightMap材质,因此你不必手动的设置Shader和重新赋予LightMap纹理。
唯一的"副作用"是用来取LightMap的UV坐标的网格模型的LightMap通道会被Diffuse Map所占据,但这不是一个真正的问题,作为LightMap 网格模型可以在UV转移后删除掉。
使用本脚本的方法,你必须像下图这样选择两个网格物体文件,然后右键菜单中选择TransferUVs。
Unity3D教程:Unity批量处理修改烘培LightMap
这个脚本不仅测试了从LW 9.5导出的OBJ模型,它也可以很好的用于其他软件导出的模型文件。
中国第一免费Unity3D教程手册。
怎么在Unity3d中烘焙lightmap【2020】

怎么在Unity3d中烘焙lightmap【2020】本⽂将就如何在Unity2019中烘焙lightmap的话题,以实例的⽅式与⽹友展开讨论,相关实例截图如下:⼲活!● Unity⽇景烘焙⾸先⼩姐姐以著名的斯蓬扎宫模型场景为例,和⼤家⼀起探讨⼀下正午时分的光影布光⽅法及烘焙过程。
3dMax模型情况如下图所⽰(由图可见,模型的⾯数为6万多(见截图左上⾓),模型⼀定要采⽤精简的单⾯建模,否则这个场景的⾯数会多达⼏百万,甚⾄上千万的⾯,如此多的⾯数,Unity是吃不消的,⽆论烘焙过程的展UV,还是烘焙,甚⾄烘焙之后的场景运⾏,都会陷⼊⽆休⽌的等待、假死机和卡顿状态,毕竟烘焙之后也会个场景带来⼀些负载,⽽且最终作品要在⽤户机器或⼿机上运⾏,所以从模型的⾯数⽅⾯,必须充分考虑给场景留出⾜够的裕度)1. 模型导出⽆论你⽤3dMax、Maya、C4D、Blender或Sketchup建的模型,建议都以fbx格式导出,因为Unity3d对fbx格式兼容的最好,这也是官⽅的建议,导出时⼀定要勾选“EmbedMedia”(嵌⼊媒体),否则在导⼊Unity时会成为⽆贴图的“裸模”2. 模型导⼊Unity⑴在导⼊模型前,按下图所⽰,勾选掉Unity3d的“Auto Generate”(⾃动烘焙)选项,好多⼈⼀打开Unity3d,不知道怎么啦,总感觉系统处于运算状态,就是因为Unity默认这个选项是勾选的,当导⼊模型后,什么还没做,就⼀直陷⼊莫名的忙机,也是这个原因,所以导⼊前取消这个选项。
⑵按下图所⽰将刚才从3d软件导出的FBX模型拖⼊Unity3d的Assets⽂件夹,2017版之后,可能出于别的考虑,Unity不再直接导⼊材质和贴图,所以很多⼈发现模型导⼊后总是⽆材质和贴图的裸模,这⾥还需要做⼀点设置,看下⼀步。
⑶选中刚导⼊的FBX模型,点击inspector⾯板的Materails按钮,我们发现下⾯的所有材质都显⽰“none”,这就是裸模的根源,有童鞋说,前⾯不是说导出FBX时不勾选“Embedmedia”选项,就会出现裸模,这都勾选了,怎么还是裸模呢?这⾥需要说⼀下,如果前⾯不勾选,这⾥⼀定是裸模,但是,勾选之后,还需要⼀点点设置,否则依然会裸模,也就是前⾯和现在的设置缺⼀不可。
Unity室内效果烘焙和设置【2020】

Unity室内效果烘焙和设置【2020】下⾯以⼀个⼩客厅为例,和童鞋们⼀起讨论Unity3d的室内烘焙,⼀⽅⾯是对前⾯知识的综合应⽤,另⼀⽅⾯满⾜以下做装修童鞋的学习需求。
话不多说,开⼯!这个例⼦的3D场景如下图所⽰:拆分好的UV如下图所⽰导⼊Unity3d后的场景情况如下图所⽰:这个场景⽐较简单,⼀个窗户、⼀个沙发、⼀个茶⼏、⼀个书柜、两个落地灯、⼀个墙⾯装饰、还有⼀个挂画、茶⼏上⼀个杯⼦、两盆绿植,这⾥我们设想将场景烘焙成阴天的⽩昼⽓氛,也就是没有直射太阳光,室外光线完全是⼤⽓折射的太阳光,所以我们确定这个场景的主光源为从窗户投射的光线,可以使⽤Unity3d的⾯光源置于窗户附近,但我们这⾥选⽤Unity3d的材质灯光,也就是将某个模型的材质勾选“⾃发光”,这个模型就成了灯光了。
选中窗户玻璃,勾选其材质中的⾃发光(Emission),将⾃发光强度设为1.5,发光颜⾊设为⽩⾊,如下图所⽰:因为这个场景不可能有运动物体,光线也不会变化,所以选⽤静态灯光下的静态物体的⽅式烘焙场景,所以将⾃发光材质的Global Illumination(全局光照)设为Baked,勾选光照⾯板中的“Baked Global Illumination”,然后烘焙,得到如下图所⽰的结果(烘焙⽤时5分钟):从上图可见,场景太暗,但明暗关系已经有了,如果反复烘焙,太浪费时间,我们设想通过photoshop来调⾊,需要说明的是,这⾥所说的调⾊不是简单的图⽚调⾊,⽽是对整个场景调⾊。
如下图所⽰,将⼀个特殊的⾊带⽂件与相机关联起来,对这个⽂件调整,就会调整相机中的场景,这样我们将这个⽂件(png图⽚)⽤ps打开,然后截取⼀张相机视图的图⽚,按照图⽚调⾊的⽅法,对截取的图⽚调⾊,然后将图⽚调整的参数应⽤于那个⾊带⽂件,保存⾊带⽂件后,Unity3d的场景就回作相应的调整,关系就是这样。
下⾯我们就来调⾊,⾸先抓取相机视图的图⽚,然后在ps中打开,同时也将刚所说的⾊带⽂件也⽤ps打开,如下图:⾸先调⼀下截取的相机视图图⽚的亮度和对⽐度,亮度88,对⽐度-50,如下图所⽰:然后对⾊带也做这样的调整,如下图所⽰:然后保存⾊带⽂件,Unity的相机视图就会作相应的调整,调整后如下图所⽰:原理⼤家都明⽩了吧,这样就是以⽤ps灵活地为Unity3d场景调⾊了,只要Unity3d烘焙出场景的明暗关系,剩下的就交给ps了,这样可以节省⼤量反复测试烘焙的时间。
unity烘焙场景的创建保存和使用(附demo项目)
unity烘焙场景的创建保存和使用(附demo项目)Unity烘焙场景是一种将场景中的静态物体和光照信息转换为纹理贴图的过程,可以提高游戏的渲染效率。
在Unity中,烘焙场景的创建、保存和使用非常简单。
首先,我们需要创建一个新的场景,并将需要烘焙的物体放置在场景中。
烘焙通常用于静态物体,因为它们不会在运行时发生移动。
可以使用Unity的预制体或手动创建物体。
在场景中,我们还需要设置光照信息。
这可以通过创建光源或使用Unity提供的预置光照设置来完成。
光照设置包括环境光、定向光、点光源、聚光灯等。
根据场景需要,可以调整光源的位置、颜色和强度等属性。
完成物体和光照的设置后,我们可以开始进行烘焙。
在Unity的顶部菜单栏中,选择“Window”->”Lighting”打开烘焙窗口。
在烘焙窗口中,选择“Scene”选项卡。
在这里,可以设置烘焙的一些参数,如光照贴图的像素分辨率、间接光照的质量等。
同时,还可以选择烘焙的物体和光照信息。
点击“Bake”按钮开始烘焙过程。
Unity会根据场景中物体的位置和光照的设置,计算出每个像素的颜色和光照强度,并将其保存为一张贴图。
这张贴图将被应用到场景中的物体上,提高渲染效率。
完成烘焙后,我们可以保存场景。
在Unity的顶部菜单栏中,选择“File”->”Save Scene”来保存场景。
保存后,场景将包含烘焙后的光照信息,可以在其他项目中使用。
保存的场景可以在其他项目中导入和使用。
在新的项目中,打开场景后,场景中的物体将自动应用保存的光照信息。
这样可帮助我们节省时间和提高工作效率。
除了创建、保存和使用烘焙场景,我们还可以进一步优化烘焙结果。
在烘焙窗口的“Lighting”选项卡中,可以调整烘焙参数,如光照贴图的分辨率、间接光照的采样数量等。
通过适当调整这些参数,可以使烘焙结果更精确和逼真。
总结来说,Unity烘焙场景的创建、保存和使用非常简单。
通过将静态物体和光照信息转换为纹理贴图,可以提高游戏的渲染效率和优化性能。
unity3d烘焙场景设置注意事项
unity3d烘焙场景设置注意事项Fbx、贴图导入Unity时的注意事项:在导出Fbx之前,Maya中已经对物体连接了正确的贴图,并且贴图文件名不能更改。
把Fbx和贴图放在同一文件夹内,直接把此文件加拖入Unity内。
此时Diffuse贴图应能自动识别。
此时,对贴图修改后,在Unity中更新贴图(删除老贴图,导入新贴图,并保持命名,路经一致),模型能够自动更新。
假如Unity中删除贴图,关闭Unity,再打开Unity,导入之前删除的贴图,模型不会自动更新贴图。
------------------------------------------------------i3D的这篇教程中的模型比例有问题,先根据Unity官方帮助文档中的内容说一下:Unity官方帮助文档中认为,模型的缩放尺寸是非常重要的。
特别是涉及到一些物理特效模拟的时候。
Unity认为,在理想状态下,不要更改模型的Transforms Scale 值,保持Scale值为(1,1,1)。
(这样的话,模型在Maya中制作时需要freeze,使缩放值为(1,1,1))。
原因是,额外的缩放数值会增加不必要的计算量。
Unity首先推荐模型在创建时使用真实尺寸。
其次是在Unity的Import Settings中更改尺寸。
Unity在进行场景优化时会根据物体尺寸来进行优化。
当在Unity中把一个物体parent到另外一个物体时,最好父级物体的坐标值是(0,0,0),否则之后会遇到不少头痛问题。
Unity的粒子系统不受Transforms Scale值的影响。
物体的不均匀缩放值在Parent后会产生不良后果(这个情况和Maya中是一样的)Unity中,1个单位尺寸代表1米。
即在Unity中创建一个Cube的尺寸是1x1x1米大小。
Unity推荐把人的身高定为大约2个Unity单位高度(2米)。
在Max中,只要正确设置单位尺寸(系统单位尺寸设置以及输出时单位尺寸设置)成厘米后,得到的效果是一致的。
Unity3D研究院之Unity5.x运行时动态更新烘培贴图(八十七) 雨松MOMO程序研究院
Unity3D研究院之Unity5.x运行时动态更新烘培贴图(八十七)雨松MOMO程序研究院前段时间我研究过这个问题,但是没有解决只好作罢。
今天刚好有人又问我这个问题,我得空查了一下还是找到了解决办法。
另外也感谢问我的人,解答问题的同时也是我学习的过程。
运行时更新烘培贴图分两种情况1、场景的物件没有发生变化(也就是说没有运行时加载在场景上的Prefab)此时可以直接更换烘培贴图。
1234567891011121314151617181920212223242526using UnityEngine;using System.Collections;public class NewBehaviourScript : MonoBehaviour { //烘培烘培贴图1 public Texture2D greenLightMap; //烘培贴图2 public Texture2D redLightMap; void OnGUI(){ if(GUILayout.Button("green")) { LightmapData data = new LightmapData(); data.lightmapFar = greenLightMap; LightmapSettings.lightmaps = new LightmapData[1]{data}; } if(GUILayout.Button("red")) { LightmapData data = new LightmapData(); data.lightmapFar = redLightMap; LightmapSettings.lightmaps = newLightmapData[1]{data}; } }}。
Unity3D游戏开发之使用烘焙贴图教程
Unity3D游戏开发之使用烘焙贴图教程
关于灯光贴图,烘焙贴图如何在unity3d中导入及使用的基本教程。
1,当您完成uvw保存到您的模型。
uvw文件
2,创建新uvw并将其更改为通道2。
加载uvw前面创建。
这比给你更好的使用自动uvw结果。
3,打( 0 )打开渲染到纹理窗口。
选择“使用现有的渠道“ ,更改频道,以“2 “,选择添加“ Lightingmap “。
当你看到的图像呈现是不是真正的结果。
真正的图像存储在您的3dsmax的文件夹。
通常它存储这样(我Documents/3dsmax/sceneassets/images )为您的型号名称看待
“ LightingMap “背面。
通常这样的TGA文件。
本文出自【狗刨学习网】
4,在简单的办法是“从材料选择对象“,然后复制“烤材料“到一个空槽。
由于。
Fbx输出目前不支持“壳材料“ 。
5,在您指定的新出炉的材料模型,导出的FBX与推广模式。
在这里,我使用厘米,嵌入的纹理,转换为可移植格式(TIFF )。
6,当您打开您的统一计划,并导入模式,你会看到它的只有弥漫纹理从3dsmax的出口。
而且没有光影质感。
我的方法是导入光影纹理3dsmax的存储在(我
Documents/3dsmax/sceneassets/images )。
然后添加到您的模型fBm特征的文件夹。
7,在此之后进行。
改变你的模型材料,以1 Lightmapped材料。
并添加到插槽光影质感。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Unity烘焙材质到单一贴图的脚本这个脚本由 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[] = newGameObject[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);yer = 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 = eCustomLights & 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 (eCustomLights)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;// setupif (!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);// restorecamera.SetActiveRecursively(false);RenderSettings.ambientLight = saveAmbientLight;m.mainTexture = saveMainTexture;previewTexture = rt;return rt;}function CaptureMaterial(m : Material){var matAssetPath = AssetDatabase.GetAssetPath (m);var assetPath = bine (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 ();}elsesettings.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();}eCustomLights = EditorGUILayout.BeginToggleGroup("Custom lighting", eCustomLights);if (eCustomLights){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.bakeMainTexAsW hite);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);}}。