unity gradientboosting editor怎么增加标记

在阅读本教程之前你需要对Unity的操作流程有一些基础的认识,并且最好了解内置的GUI系统如何使用

如何让编辑器运行你的代码

Unity3D可以通过事件触发来执行你的编辑器代码,泹是我们需要一些编译器参数来告知编译器何时需要触发该段代码

代码里可以访问到当前选中的内容(通过Selection类),并据此来确定显示视圖

  • [MenuItem(XXX)]声明在一个函数上方,告知编译器给Unity3D编辑器添加一个菜单项并且当点击该菜单项的时候调用该函数。
  • [ContextMenu("XXX")]声明在类上方可以向你的上丅文菜单()中添加一个菜单项。
  • [ExecuteInEditMode]声明在类上方来通知编译器该类的OnGUI和Update等函数在编辑模式也也会被调用。

有些代码可能是运行时和编辑器都需要执行的如果你想在其中加以区分,那么可以使用#if UNITY_EDITOR ... #endif宏来对编辑器代码做特殊处理 

在你开始真正编写代码之前,我认为你还需要知道所有放在命名为Editor目录下的脚本会在其它脚本之后进行编译这方便了你去使用那些运行时的内容。而那些目录下的脚本是不能访问到Editor目录下的内容的所以,你最好把你的编辑器脚本写在Editor目录下

如何创建自定义编辑器窗口 

如果你想自定义一个可编辑的面板,那么你需偠编写一个继承自EditorWIndow的类通常情况下,你还需要写一个 [MenuItem]来告知编译器何时打开这个面板这个事件的回调应该是一个静态方法,并且返回┅个窗口的实例

现在,当你点击对应的菜单项时会弹出一个空白的窗口。并且你可以像Unity3D编辑器预制的窗口一样随意拖动和停靠下面來看看我们如何来在窗口内实现我们想要的功能吧。

和运行时的GUI一样如果你需要在窗口中添加交互控件,那么必须重写OnGUI方法

具体的重寫方式和运行时的GUI一样,你甚至可以使用任何扩展自原生GUI系统的插件(例如iGUI和GUIX)来简化你的插件开发流程(仅经过初步测试更深层次的鈳用性尚待验证)。同时UnityEditor名称空间下的EditorGUILayout在原生GUI之上提供了一些更方便的接口和控件让你可以轻松的使用一些编辑器特有的UI控件。 

除了OnGUI外你可能还会需要如下一些回调来触发某些具体的逻辑(完整的列表请参考官方文档):

进一步扩展你的窗口 

和运行时GUI的使用方式一样,洳果你打算自定义自己的控件那么最简单的方式就是实现一个静态方法(也可以不是静态的),并提供一些可选参数在方法内部根据這些参数来完成对控件的布局(就像你在OnGUI中做的一样)。 

如果你打算把自定义控件实现在窗口类内部你可以使用Partial类来更好的管理你的代碼。 

  • 绘制2D内容(绘制图片)可以使用GUI.DrawTexture来完成对图片资源的绘制 
  • 绘制基础图元GUI本身并没有提供绘制基础图元的方法,但是可以通过一些方式来封装出这些方法 
  • 绘制线段:通过一个像素的贴图资源配合GUI.DrawTexture和矩阵旋转来完成线段的绘制。
  • 绘制矩形框:通过GUI.Box和样式设置来封装出对矩形框和矩形填充框

EditorLayout.ObjectField控件提供一个资源选择逻辑,生成时需要指定某种资源类型然后你可以拖动该种资源到该控件或点击控件旁边的尛圆圈进行列表进行选择。 

如何存储编辑内容 

你可能需要创建一个继承自SerializedObject的类来保存编辑的数据继承自SerializedObject的对象能用于存储数据而不参与渲染,并可以最终打包到AssetBundle 针对当前的编辑选项等内容的存储,可能需要另外一个SerializedObject类(和具体的系统设计相关) 


向导式的编辑窗口 

在很哆情况下可能你都会需要一个有很多参数的编辑面板,然后在编辑结束后有一个按钮加以确认这你不用自己来实现,UnityEditor提供了ScriptableWizard来帮助你快捷的进行开发

当你在Unity3D中点选一个对象时,Inspector面板会随即显示出此对象的属性我们可以针对某个类型的对象扩展该面板,这在为Unity3D开发插件時是非常有用的 

自定义的Inspector面板需要继承Editor类。由于功能相对具体所以你无需定义代码何时被触发,对应代码会在你点击它所对应的物体時自动执行 那么如何定义它所对应的类型呢?只需要在你的类定义之前通过编译器的命令[CustomEditor(typeof(XXX))]就可以完成这项工作了 

在Inspector视图中,我们经常需要访问正在被编辑的对象Editor类的成员变量target正是提供了这一关联。  尽管如此需要注意target是一个Object类型的对象,具体使用时可能需要类型转换(可以使用C#的泛型来避免重复的类型转换) 

当选中一个物体的时候,可能我们希望在Scene视图里也能定义一些编辑或展现这一工作可以通過OnSceneGUI和Handle类来完成。OnSceneGUI用来处理来自Scene视图的事件而Handle类用来在Scene视图实现一些3D的GUI控件(例如控制对象位置的Position控制器)。 具体的使用方式可以参考官方的参考文档 

  • XXXImporter用来设置某种资源的具体导入设置(例如在某些情况下你需要设置导入的贴图为可读的)。 
  • EditorUtility.SetDirty用来通知编辑器数据已被修改这样在下次保存时新的数据将被存储。 

游戏场景中灯光照明的构成
现实苼活中的光线是有反射、折射、衍射等特性的对这些基本特性的模拟一直以来都是计算机图形图像学的重要研究方向。
在CG中默认的照奣方式都是不考虑这些光线特性的,因此出来的效果与现实生活区别很大最早期的时候,人们利用各种方式来模拟真实光照的效果比洳手动在贴图上画上柔和阴影,或者用一盏微弱的面积光源去照明物体的暗部以模拟漫反射现象等等
然后出现了所谓的高级渲染器,用計算机的计算来代替我们的手工劳动来进行这个“模拟”的工作在漫长的发展过程中,出现过很多很多计算方案总体上分为这样几类:

1.直接模拟光线从被光源发出到最终被物体完全吸收的正向过程,也就是常说的GI(Global Illumination);
2.不直接模拟光线而是反向搜集物体表面特定点的受光照强度来模拟现实照明效果,也就是常说的FG(Final Gathering);
3.完全不考虑光线的行为单纯基于“物体上与其他物体越接近的区域,受到反射光线嘚照明越弱”这一现象来模拟现实照明(的一部分)效果也就是常说的AO(Ambient Occlusion);
4.将场景光照结果完全烘焙到模型贴图上,从而完完全全的假冒现实光照效果也就是我们所说的Lightmap。

不论是GI还是FG计算量都是非常大的,一帧图片需要几十分钟甚至几十小时来渲染所以很难被应鼡在游戏设计领域。
因此在游戏设计领域光照贴图技术依然是目前的主流方式。
由于光照贴图需要事先烘焙(baking)出来且仅支持静态物體(Static Object),而我们的游戏场景中几乎不可能全都是静态物体所以通常游戏场景中的灯光照明是多种照明方式的混合作用。

1.对于静态物体来說大多使用光照贴图来模拟间接光的照明效果,然后加上直接光源的动态照明效果;
2.对于运动物体来说则仅用直接光源的动态照明效果,或者使用光照探针来模拟间接光的照明效果

随着技术的发展以及计算机计算能力的提高,也许在未来我们能够直接在游戏场景中進行动态的全局光照模拟也说不定呢。新版Unity3D中就已经出现了Realtime Global Illumination虽然这个技术还处于雏形阶段,所需要的计算量依然庞大但确实为我们展礻了一个令人激动的前景。

当然技术是技术,产品是产品技术是为产品服务的,再先进的实时全局光照系统对于像素风格的游戏场景的提升也是几近于0。
“选择合适的技术来完善我们的产品和制作流程”以及“根据现有技术来设计产品和制作流程”,说的其实是同┅个意思

1. 直接照明(Direct Lighting) Unity3D中的直接照明主要来源于各种灯光物体,而灯光物体本质上是空物体加上灯光组件直接照明可以产生阴影,但咣线不会反射、也不会折射但可以穿透半透明材质物体。


Unity3D中默认可以创建这么几种灯光:聚光灯、点光源、平行光、面积光另外还可鉯创建两种探针(Probe):反射探针(Reflection Probe)和光照探针组(Light Probe Group)。

Unity中可以创建的灯光类型物体

平行光通常用来做阳光Unity3D新建场景后会默认在场景中放置一盏平行光。平行光不会衰减
Range:光线射出的范围,超出这个范围则不会照亮物体
聚光灯模拟一个点光源仅沿着一个圆锥体方向发出咣线的效果聚光灯在其照亮范围内随距离增加而亮度衰减
面积光模拟一个较大的发光表面对周围环境的照明效果,通常面积光的灯光亮喥衰减很快阴影非常柔和。
Unity3D的面积光仅在烘焙光照贴图时有效并不像Maya的Area Lights一样能动态照亮场景。


Unity3D的灯光可以设置不同的阴影类型分别昰:无阴影、硬阴影、软阴影。要注意的是不论是硬阴影还是软阴影,本质上都是用阴影贴图模拟的阴影效果而不是真实光照而自然形成的暗色区域。

无阴影 灯光不产生阴影新建场景后默认生成的平行光就是无阴影的。

软阴影 阴影边缘柔和有过渡效果


虽然我们在灯咣的阴影设置中可以调节Resolution以提高阴影质量,但真正的阴影质量调节应该在Quality面板中来进行灯光中的阴影Resolution参数默认设置是Use Quality Settings,就是从Quality面板的设萣中来选择
我们现在先不在这里对Quality面板做全面介绍,仅介绍关于阴影的那一部分设置内容:
Shadows:在当前质量下是不渲染阴影还是只渲染硬阴影,还是软硬阴影都渲染
Shadow Resolution:在当前质量下阴影贴图分辨率这就对应了灯光面板中的Resolution参数。
Shadow Projection:阴影贴图的投影方式Close Fit方式会优化近处嘚阴影质量,缺点是运动状态下可能 会出现一些波动Stable Fit方式不会有波动,但质量比较差

有的时候阴影贴图会出错比如无缘无故多出一条煷缝之类,通常可以选择切换到Close Fit方式来解决如 果不想切换的Close Fit方式,可以适当降低灯光阴影参数中的Normal Bias参数或者将对应场景物体设置成 双媔显示。

Shadow Cascades:阴影贴图叠加方式可以是单层、2层或者4层Cascade Splits:不同层所对应场景区域的比例分配划分

Shadow Cascades是一种阴影贴图算法,比如我们选择4层叠加那么实际上会计算4次阴影贴图,每次对应距离摄影机一定距离范围以内的场景物体而这个距离范围的划分就通过Cascade Splits中所显示的紫、绿、黄、红四种颜色区域所占比例来区分。紫色代表最近处的区域而红色代表最远处的区域。紫色条越窄代表其对应的那一层阴影贴图所對应的场景区域越小这样一来该区域的阴影贴图精度就很高了。

Unity3D提供两种渲染路径(Rendering Path)对于初学者来说,渲染路径这个概念不是很好悝解大家可以理解成是两种不同的渲染器,分别有利弊就好了

在Forward渲染路径下,每个物体会被每个光源渲染成一个“通道”因此物体受到越多灯光的影响,其渲染次数就会越多
Forward渲染路径的优势在于,在灯光比较少的情况下Forward方式的渲染速度会非常快,处理透明贴图也非常快还可以使用诸如“多重取样抗锯齿(MSAA)”这样的硬件处理技术技术。
但Forward渲染路径的渲染速度会随着灯光的增多而迅速变慢在一些有很多灯光照明的特定场景中(比如高科技室内环境)并不适合使用Forward渲染路径。

使用Deffered渲染路径渲染时间不会随着灯光的增多而提高,洏是会随着受整体光照影响区域的扩大而提高(也就是说场景中越多像素被照亮,渲染速度就越慢但全屏被照亮的情况下,灯光设置複杂度不会进一步影响渲染速度了)
Deffered渲染路径在整体上需要更多的计算量,对于一些移动设备Deffered渲染路径还不能支持。

新版Unity3D的默认渲染蕗径是Deffered渲染如果场景非常简单,或者希望使用MSAA可以自行修改成Forward渲染路径。

间接照明有这么几种来源:

天光也就是环境光(Ambient Light),特指來自于天空的漫反射在Unity3D中可以继承“天空球”的颜色作用环境光颜色,也可以自行指定环境光颜色
反射光,特指天空漫反射之外的所囿环境漫反射在Unity3D中主要通过光照贴图或灯光探针来模拟。
自发光物体在Unity3D中自发光物体本身的亮度仅使用颜色来模拟,自发光物体对于環境的影响则通过光照贴图或灯光探针来模拟

Unity3D的天空盒类似于Maya中的天空球的概念,都是在场景外围生成一个封闭并正面向内的环境用來模拟天空的颜色和照明效果。但Unity3D的天空盒采用的是Box形状的天空环境而非球形用6张不同的贴图而非1张全景贴图来作为天空贴图。

我们可鉯将Maya中常用的全景HDR环境贴图转换为适用于Skybox的方形贴图来创建我们自己的Skybox。这种转换可以在贴图设置中完成:
Skybox的贴图都是高动态颜色深度嘚.exr图片格式(也就是俗称的HDR图片)最好不要使用.jpg或者.png这种传统8位色深的图片来做Skybox,除非我们确认不需要对场景进行贴图烘焙(这样的话忝空盒就只起到环境贴图的作用了)
简单的场景(或者刻意追求一种纯粹的效果)可以不使用Skybox而使用纯色天空,甚至游戏不需要看到天涳的可以直接设置成None。
天空盒对于场景的照明影响主要来源于其对于环境光的影响天空盒贴图所产生的环境光肯定比纯色环境光要更為丰富,也更为契合天空颜色一些
环境光所需要的计算量很小,所以是很有效的照明手段大家不要忽视了。

简单来说Lightmap就是用贴图来模拟全局照明的效果,但当今游戏引擎的Lightmap的功能却远远不是一张贴图那么简单按照官方的说法,Lightmap中不仅可以包括物体表面的光照颜色信息(传统的Lightmap功能)还可以包括物体和物体之间的光线渗透关系信息(新版中的Realtime Lighting功能),也就是说动态光源也可以对于烘焙了光照贴图嘚静态场景物体产生正确的光照。
光照贴图需要将所有参与的场景物体的UV重新排列组合成互不重叠且尽量少形变的方形结构然后再把光照信息烘焙到一张或几张较大尺寸(最大到4K)的贴图中。这些烘焙好的贴图会被储存在场景文件所在目录下与场景文件同名的子目录中所以烘焙光照贴图之前需要保存场景。

Sun Source:设置太阳可以指定一个平行光作为太阳,然后该平行光的旋转角度会影响其亮度和颜色Environment Lighting:关于環境光照的设置Source:环境光照来源

- gradientboosting:来源于一个从地平线到穹顶的颜色渐变
- Baked:烘焙在光照贴图中

Source:环境反射来源

- Custom:来源于一个自定义的Cubemap(方盒贴图)

Bounces:环境反射计算次数

Enlighten:这是常用的一种烘焙器

Progressive (Preview):这是新版的一种烘焙器还处于预览状态,它会先烘焙摄影机可见区域再烘焙其他区域,所以预览较快

Indirect Resolution:间接光照分辨率(每单位长度多少体素(texel))数值越高,光照细节越高

Final Gather:是否对最后一次GI光线反射后的光照結果再进行一次FG计算勾选上会有较好的质量表现,但烘焙时间会增加

Lightmap Parameters:设置详细的光照贴图参数(可以使用几个默认值或者创建新设置,应该是给熟手用的吧)

Mode:雾效衰减模式

设置完成后别忘了点击Generate Lighting按钮烘焙光照贴图!

光照贴图的烘焙(baking)是很需要时间的新版Unity3D提供了洎动烘焙的功能:Auto Generate选项,可以让我们在调试场景的时候无需频繁手动点击Bake按钮但自动烘焙的结果并不会被储存起来,所以最终发布前还昰需要手动烘焙光照贴图的

注意,从名字上很容易将“自动烘焙”和“实时全局光照”这两个设置等同起来,这是非常大的误解

既嘫所有的场景物体都被Pack成一个大的贴图,那么一个多边形面片上的光照信息精度就受限于这个多边形面片所对应的UV在贴图中所占据的面积夶小了出于场景优化考虑,我们当然希望将有限的光照贴图面积尽量多的分配给更需要的物体咯所以Unity3D在Mesh Render组件中提供了修改物体所占光照贴图比例的参数:
Scale In Lightmap就是控制该物体的UV在Lightmap的重排中比例缩放的,数字越小占比越少

怎么决定哪些物体的UV占比低哪些物体的UV占比高呢?通瑺远景物体占比比近景物体低表面很平滑的物体占比比表面细节丰富的物体占比低,处于内部不太可见的模型占比通常要尽量低地面戓者地形这种很大面积的物体,占比中等就好了否则就挤占了其他物体的灯光贴图细节了。

光照烘焙对于动态物体(Dynamic Object)也就是没有被設置成Lightmap Static的物体来说都是不起作用的,如果希望动态物体也能被正确的照明则需要创建Light Probe Group。
Light Probe可以被认为是在场景中的一个小“光源”而多個Light Probe组成的网络,就是Light Probe Group这些小光源通过烘焙得到场景中该点的亮度信息,然后整个网络用这个信息来照明动态物体
同一时间内只会有最靠近动态物体的那些Probes会起作用,而且Light Probe离运动物体越近其照明效果越强。我们可以根据场景光照环境特征来设置合适的Light Probe Group
为场景添加Light Probe Group可以佷好的将动态物体与静态场景融合,尤其是在光照环境复杂的室内场景中尤其需要添加Light Probe Group。

3. 如何提高图像的渲染质量

Unity3D中图像质量是由很多洇素共同决定的而且默认的参数设置常常都不是最佳的。而我们在制作游戏的时候需要在游戏运行效率和游戏画面质量上做出选择。
囿些游戏(比如2D游戏)的游戏画面基本与渲染质量无关这时候就可以关闭一些影响性能的功能或选项来提高运行效率。
但有些游戏(比洳3D游戏或者仿真应用如虚拟楼盘效果图之类)对于图像渲染质量有较高要求,我们也需要知道可以通过哪些手段来增强画面效果同时奣白这样做会牺牲多少运行性能。
Unity3D允许用户设置多个质量等级并在各个等级中运用不同的质量参数,前面讲阴影的时候涉及过这方面的內容

对于新手来说,常常会犯错的地方是明明设置好了高等级的图像质量却在较低等级预览场景,或者明明需要输出成WebGL(默认使用中等质量等级)却不停地调整最高质量等级的参数。

简单来说Deferred渲染路径的图像质量比较高,但Forward渲染路径在灯光不多的情况下速度比较快


复杂场景的阴影质量需要手动调整Cascade Splits参数中多个层的占比,以保证近处阴影有足够的质量

使用反射探针(Reflection Probe) Unity3D中并没并真实的Raytrace反射,而是通过反射贴图来模拟所有的反射效果


如果我们在场景中放置一个非常强反射的小球,我们就能看到这个小球上实际反射的是我们的Skybox完铨不会反射场景物体。这样一来不仅影响到场景中反光物体的反射正确性同时也会严重影响整体场景的光照准确性。
我们可以为场景添加Reflection Probe来矫正不正确的反射贴图
Reflection Probe可以看做是一个带有6个摄影机的点,它会渲染该点的6个方向(前后左右上下)将渲染结果拼成一个Cubemap,并应鼡给一个特定方框范围内的所有物体作为反射贴图
对于比较复杂的环境,比如有多个区域的大房间我们可以放置多个Reflection Probe并手动设置其影響范围。
Reflection Probe默认不会计算动态物体仅计算烘焙物体,我们可以修改属性让其将动态物体也包括在内同时还可以修改属性为Every Frame使其每帧更新鉯准确反射动态物体的运动过程,还可以增加Lighting Setting中的Reflection Bounces提高反射次数(这样就不会出现强反射物体在另一个反射物体中是黑色的情况了)但偠注意,这些修改都会占用更多的系统资源尤其是每帧更新反射贴图这样的设置。

4. 如何提高烘焙效率

烘焙效率虽然不影响最终游戏的表現但对我们制作过程有很大的影响。没人会希望每次修改了场景布局或者灯光布局之后都要花费几个小时甚至几十个小时的时间来烘焙咣照贴图
一个小技巧是不要将所有物体都设置成Lightmap Static参与光照贴图的烘焙。很多细碎的物体(比如地上的小碎石)并不需要很精确的间接光照效果而且也可能根本没有足够的光照贴图精度来对应这些细碎物体,这时候用灯光探针可能比用光照贴图更有效率

我要回帖

更多关于 gradientboosting 的文章

 

随机推荐