Unity烘焙材质到单一贴图的脚本

合集下载

unity3d游戏开发之UV贴图教程

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脚本编辑器介绍

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光照贴图烘焙知识详解

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教程: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】

怎么在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】

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烘焙场景的创建保存和使用(附demo项目)Unity烘焙场景是一种将场景中的静态物体和光照信息转换为纹理贴图的过程,可以提高游戏的渲染效率。

在Unity中,烘焙场景的创建、保存和使用非常简单。

首先,我们需要创建一个新的场景,并将需要烘焙的物体放置在场景中。

烘焙通常用于静态物体,因为它们不会在运行时发生移动。

可以使用Unity的预制体或手动创建物体。

在场景中,我们还需要设置光照信息。

这可以通过创建光源或使用Unity提供的预置光照设置来完成。

光照设置包括环境光、定向光、点光源、聚光灯等。

根据场景需要,可以调整光源的位置、颜色和强度等属性。

完成物体和光照的设置后,我们可以开始进行烘焙。

在Unity的顶部菜单栏中,选择“Window”->”Lighting”打开烘焙窗口。

在烘焙窗口中,选择“Scene”选项卡。

在这里,可以设置烘焙的一些参数,如光照贴图的像素分辨率、间接光照的质量等。

同时,还可以选择烘焙的物体和光照信息。

点击“Bake”按钮开始烘焙过程。

Unity会根据场景中物体的位置和光照的设置,计算出每个像素的颜色和光照强度,并将其保存为一张贴图。

这张贴图将被应用到场景中的物体上,提高渲染效率。

完成烘焙后,我们可以保存场景。

在Unity的顶部菜单栏中,选择“File”->”Save Scene”来保存场景。

保存后,场景将包含烘焙后的光照信息,可以在其他项目中使用。

保存的场景可以在其他项目中导入和使用。

在新的项目中,打开场景后,场景中的物体将自动应用保存的光照信息。

这样可帮助我们节省时间和提高工作效率。

除了创建、保存和使用烘焙场景,我们还可以进一步优化烘焙结果。

在烘焙窗口的“Lighting”选项卡中,可以调整烘焙参数,如光照贴图的分辨率、间接光照的采样数量等。

通过适当调整这些参数,可以使烘焙结果更精确和逼真。

总结来说,Unity烘焙场景的创建、保存和使用非常简单。

通过将静态物体和光照信息转换为纹理贴图,可以提高游戏的渲染效率和优化性能。

unity3d烘焙场景设置注意事项

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程序研究院

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游戏开发之使用烘焙贴图教程
关于灯光贴图,烘焙贴图如何在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材料。

并添加到插槽光影质感。

unity烘焙光照贴图

unity烘焙光照贴图

光影烘焙,英文叫Lightmapping 或 light baking。

Unity 自带了 Lightmapping 的功能(是 Illuminate Labs出的名为Beast的产品)。

本系列教程分为4讲:第一讲光影烘焙第三讲 Light Probes第四讲脚本控制其中第三第四讲讲解的是动态物体与烘焙后场景的融合。

打开方式Window - Lightmapping有几点需要注意:1.所要烘焙物体的mesh必须要有合适的lightmapping uv。

如果不确定的话,就在导入模型设置中勾选 Generate Lightmap UVs2.任何Mesh Renderer, Skinned Mesh Renderer 或者 Terrain 都要标注为static(lightmap static)界面一:Objec点击Bake Scene即开始烘mappingObject MapsRan d4rersVBipODI Pelvis (Skinned Mesh Renderer)Lightmsp StaticScale In Lightmap 1CleatI lightmap2: 2K 1 024M1024P::烘焙参数的设置Mode:(1)Dual Lightmap mode:近景烘焙图(near lightmaps)和远景烘焙图(far lightmaps)都会被烘焙,只有deferred rendering path支持该模式。

(2)Single Lightmap mode:只有远景烘焙图(far lightmaps)会被烘焙,(3)Directional Lightmap mode:Use in forward rendering:一般可以忽略它。

针对Dual lightmaps的设定,只在Mode选的是Dual时才会出现。

在forward rendering模式下是否激活dual lightmaps,需要自己写对应的Shader。

Unity烘焙教程

Unity烘焙教程

unity自带LightMapping和3Ds Max烘焙贴图的小对比对于做虚拟现实的朋友来说,烘焙贴图应该不是一个陌生的东西。

想要在有限性能的电脑上面即时运算较好的光影效果,一般都会采用烘焙贴图的方法。

而除了在3dmax里面烘焙贴图之外,Unity3D也自带了LightMapping烘焙贴图的功能。

下面我们来做一个小例子,对两者的意义和效果做一个小对比。

在3dmax里面,我简单的建立了几个模型,并分别赋予他们不同的颜色:然后使用3dmax自带的光线追踪渲染一下,会出现这样的效果:很明显的,光线追踪之后的渲染效果比没有光线追踪时立体感强了很多。

这是因为高级渲染器模拟了真实环境里面光线的各种反射和散射,使物体看起来接近真实的效果。

我们所要做的烘焙,其实就是把这种经过高级渲染器计算的光影效果,记录在贴图上面。

我对上面的几个物体展了UV,并使用3dmax的烘焙功能,烘焙出相应的贴图。

并把这个带着UV信息的模型导出为FBX,放进Unity里面。

在unity里面,我拉出了两个模型,一个按照原来的颜色直接给予他材质,另外一个把3dmax里面烘焙的贴图贴上了模型,会出现上图的情况。

场景里面也没有打灯光,假如是只有颜色的材质时,模型会没有任何的轮廓和立体感。

而贴上了烘焙贴图的模型,看起来会和在3dmax里面使用光线追踪时渲染的效果差不多。

接下来我们对只有颜色的这个模型进行LightMapping烘焙处理。

选择该模型,然后在Static里面选择Lightmap Static。

在菜单栏的Window——>lightMapping打开lightMapping面板,在bake栏里面设置一下烘焙的参数,我这里用了如下参数:设置好之后,就可以烘焙了,在烘焙之前先保存场景,然后点击Bake Scene按钮。

经过漫长的等待(等待的时间取决于你的模型的复杂程度),烘焙结束,生成了贴图,我们可以在maps里面查看:这时候,我们可以进行一个小对比了:同样是场景里面没有灯光,但不论是经过Lightmapping烘焙的模型,还是在3DMax里面烘焙贴图的模型,都有了较为真实的光影效果。

Unity3D之Lightmap入门、烘焙贴图、场景技巧

Unity3D之Lightmap入门、烘焙贴图、场景技巧

Unity3D之Lightmap入门作者:李志健Unity内置的光照贴图烘培工具是Illuminate Labs 的Beast。

烘培光照贴图流程被完美的整合到Unity中。

这就意味着使用Beast可以根据你的网格物体,材质贴图和灯光属性的设置来烘培你的场景,从而得到完美的光照贴图。

同时也意味着光照图将作为渲染引擎的一部分。

只要你烘培一次光照贴图你就不需要其他任何操作。

光照图将自动指定到物体上。

准备需要烘培的光照贴图的场景从菜单栏选择Window – Lightmapping打开光照图工具窗口。

1.检查你将要烘培的模型上是否存在一个合适的用来定位光照贴图的UVs。

你也可以从mesh import settings面板中的勾选Generate Lightmap UVs选项来生成一个用于定位光照图UV的集。

2.在物体面板中将要烘培光照贴图的物体设置为Static(静态),这样Unity就会知道哪些物体是需要被烘培的。

3.在Bake面板下调整Resolution的值控制光照贴图的分辨率。

(在Scene View面板里勾选上小窗口LightmapDisplay中的Show Resolution选项可以帮助你更直观的查看贴图分辨率设置)。

4.点击Bake(烘培)5.在Unity编辑器底部的状态栏的右边会出现一个进度条。

6.当烘培结束时,你可以从光照图编辑器的底部预览窗口中查看所有烘培好的贴图。

场景和游戏窗口将会更新。

现在在你的场景中已经可以看到光照贴图效果了!Tweaking Bake Settings 调节烘焙设置最终场景的渲染效果取决与你对灯光和烘培选项的更多设置。

让我们来看一个通过基础设置改进光照的质量的小例子。

这是一个简单的场景,包含一组立方提和一个位于场景中心的点光源。

灯光产生硬阴影,看起来这个效果十分的晦暗和不自然。

Selecting the light and opening the Object pane of the Lightmapping window exposes Shadow Radius and Shadow Samples properties. Setting Shadow Radius to 1.2, Shadow Samples to 100 and re-baking produces soft shadows with wide penumbra - our image already looks much better.选择灯光打开物体面板,展开阴影范围和阴影采样属性。

unity3d5.6烘焙教程持续更新中

unity3d5.6烘焙教程持续更新中

unity3d5.6烘焙教程持续更新中unity5.6是今年发布,作为5.x的最后一个版本,有很多烘焙优势,在此总结一些作为5.x系列完结的笔记这个版本在烘焙上的特点就是增加了渐进光照贴图(Progressive Lightmapper),这个功能可以说极大地改善场景光照烘焙的工作流程,可以加快场景烘焙效率,再也不怕烘焙一晚上发现有灯光有问题了当然它不是用来替代Enlighten的,很多地方还是略有不同的,但是感觉这个速度更快。

虽然有的新增的灯光混合模式不受支持,但是它在模型迭代中能发挥更大的优势。

Progressive 光照优势就是能很快看到一个区域的光照效果,而且在高参数下烘焙非常快,可以随时停止,效果依然保留,这个功能好多了缺点也挺多的,比如只支持两个模式(看下面,有些效果会缺失),参数高的时候内存占用非常大,如果内存小的机器很容易崩溃enlighten比较还是比较传统,内存消耗不多,比较不容易崩溃,支持所有模式,所以需要高端效果的时候还是这种支持的多但是缺点是不到渲染结束看不到效果,相同参数下烘焙时间感觉长了不只好几倍下面是两个白模渲染效果对比可以看到其实渐进式的效果范围ao效果范围更广更暗一些关于新版本还有4种光照模式,有些理解起来还都是挺纠结的而且官方和其他教程解释得都比较抽象,所以下面以质量为主进行一些说明表面上这些设置和mixed灯光有关,属于混合灯光方面的内容lightmode具体可以看这里/Manual/LightModes.html关于混合灯光四种模式区别具体看下面的/Manual/LightMode-Mixed.html但这些与烘焙质量也有很大关系,我测试了以阴影质量为主列下面的表下面讨论的项目是在bake light下,directional模式下混合灯光模式:说一下下面的模式主要针对的都是混合灯光也就是mixed方式,动态和静态虽然有的模式能相互投影但是影子依然会非常锐利,具体如何使用实时阴影取决于ShadowDistance的值和光照模式。

多维材质模型烘培入Unity教程

多维材质模型烘培入Unity教程

多维材质模型烘培入Unity教程
1,这里我有两个对象(装饰物和沙发),你能看见,一共有8张贴图(7张装饰物的贴图,一张沙发贴图).
2,展UVW设置通道为1并点击保存.
3,用第一个通道的UV来展通道2的UVW.
4,打开烘培图选项,选择"Output into Source"和"Keep Baked Materials",这个选项将自动更新你原来的材质球而且不使用壳材质.点击"0"键打开烘培窗口.
5,效果如下:
6,按下M键打开材质对话框,查看新烘培的材质,在"Self Illumination Slot"中你能看到现在是Lightmap图.导出为Fbx文件.
7,打开Unity并且导入这个模型因为3dsmax中用了8张贴图,所以Unity将给模型赋予8个材质,lightmap贴图不能随着到如今来.手动从3dsmax文件夹导入光影图.名字是模型名与Lightingmap结尾.本例中有2个烘培图,分别是sofaLightingMap.TGA, and wallLightingMap.TGA.
8,将我们所有的材质都赋予好,现在改变默认材质为"Lightmapped".我选择"Lighmapped/VertexLit",然后把对应的烘培图赋予对应的材质.
9,好了,烘培图放置正确!效果还不错吧!。

Unity烘焙材质到单一贴图的脚本

Unity烘焙材质到单一贴图的脚本

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);}}。

一键批量添加材质的法线贴图-unity插件

一键批量添加材质的法线贴图-unity插件

⼀键批量添加材质的法线贴图-unity插件有时候材质做完后需要更改贴图,或者增加贴图,数量少的时候可以⼀张张添加和修改,数量多的时候就只能代码⽣成了。

原理是通过名字的关联:主贴图和法线贴图⼤多数只是后缀的不同上,如果不是那是美术规范没做好啊,代码很简单,基本是编辑器类的代码。

这个是还没完善的特定版代码,如直接使⽤需要更改⽂件夹名字和贴图后缀。

using UnityEngine;using System.Collections;using System.Collections.Generic;using UnityEditor;using System.IO;using System.Text;[ExecuteInEditMode]public class Transferandmapnormal : EditorWindow{[MenuItem("Window/AutoAddNormal")]//打开⼀个新的窗⼝static void AutoAddNormalinmaterials(){Rect wr = new Rect(0, 200, 500, 500);Transferandmapnormal window = (Transferandmapnormal)EditorWindow.GetWindowWithRect(typeof(Transferandmapnormal), wr, true, "AutoAddNormal");window.Show();}public List<Material> scensmaterial = new List<Material>();public List<string> sourceTexturespath = new List<string>();private string textureSuffix = "_NRM.jpg";private string docPath = "DWSJ.fbm";//public Material[] scensmaterial;//绘制窗⼝时调⽤void OnGUI(){belField("⾃动添加法线贴图或其他贴图", GUILayout.Width(200), GUILayout.Height(200));GUILayout.BeginArea(new Rect(0, 80, 300, 80), "", "Box");// textureSuffix = EditorGUILayout.TextField("输⼊贴图后缀:", textureSuffix);if (GUILayout.Button("获取场景材质", GUILayout.Width(200))){if (scensmaterial != null){ scensmaterial.Clear(); }if (sourceTexturespath != null){ sourceTexturespath.Clear(); }GetScenesmaterial();}if (GUILayout.Button("应⽤法线贴图到材质", GUILayout.Width(200))){FindandapplyNormalmap();}if (GUILayout.Button("关闭窗⼝", GUILayout.Width(200))){this.Close();}if (GUILayout.Button("除去法线贴图", GUILayout.Width(200))){testpath();}GUILayout.EndArea();}private Material tempmaterial;//获取场景内的材质球//获取材质球的贴图名称和路径void GetScenesmaterial(){Object[] selection = Selection.GetFiltered(typeof(Material), SelectionMode.Editable | SelectionMode.TopLevel);if (selection.Length == 0) return;foreach (Material test in selection){if (test.mainTexture != null){scensmaterial.Add(test);sourceTexturespath.Add(docPath + "/" + + textureSuffix);}else{scensmaterial.Add(null);sourceTexturespath.Add("0");}}}//在相应的⽂件夹⾥获取法线贴图//把法线贴图贴到material对应的位置public List<Texture> tempTex;public void FindandapplyNormalmap(){for (int i = 0; i < scensmaterial.Count; i++){if (!sourceTexturespath[i].Equals("0")){//string path = AssetDatabase.GetAssetPath(targetObj);// Assets / Resources / DWSJ.fbm / DWSJ00B.jpgTextureImporter texture = (TextureImporter)AssetImporter.GetAtPath("Assets/Resources" + "/" + sourceTexturespath[i]);Debug.Log("Assets/Resources" + "/" + sourceTexturespath[i]);if (texture != null){texture.textureType = TextureImporterType.Bump;AssetDatabase.ImportAsset("Assets/Resources" + "/" + sourceTexturespath[i]);string correctString=sourceTexturespath[i].Replace(".jpg","");Debug.Log(correctString);Texture TempTexture =Resources.Load(correctString) as Texture;scensmaterial[i].SetTexture("_BumpMap", TempTexture);}}}AssetDatabase.Refresh();}public void testpath(){Object[] selection = (Object[])Selection.objects;//合法性处理if (selection.Length == 0) return;//批量导⼊贴图foreach (Object obj in selection){//取得每⼀张贴图Texture texture = (Texture)obj;//获得贴图路径string localpath = AssetDatabase.GetAssetPath(texture);Debug.Log(localpath);TextureImporter importer = (TextureImporter)AssetImporter.GetAtPath(localpath);//设置贴图类型importer.textureType = TextureImporterType.Bump;//导⼊项⽬资源AssetDatabase.ImportAsset(localpath);}AssetDatabase.Refresh();}}api解析:[ExecuteInEditMode]//在编辑器模式下可调⽤[MenuItem("Window/AutoAddNormal")]//在window⼯具栏下增AutoAddNormal选项window.Show();//展⽰新的窗⼝GUILayout.Button("应⽤法线贴图到材质", GUILayout.Width(200))//添加按钮Object[] selection = Selection.GetFiltered(typeof(Material), SelectionMode.Editable | SelectionMode.TopLevel);//把选取的物体过滤掉⾮Material类型的object到object选项。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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);}}。

相关文档
最新文档