Unity对项目性能优化的实现

Unity对项目性能优化的实现,第1张

简化模型

最小化模型网格中的顶点和面的数量,避免复杂的网格。

使用纹理贴图代替复杂的网格

考虑用法线贴图对比高度贴图。法线贴图适用于伪造模型表面凸起和凹陷光照的简单纹理贴图。

高度贴图使用一张纹理图片来制作一种非常传统的3D表面几何图形。高度贴图比法线贴图优越是因为它们不仅定义了表面凸起和凹陷,而且提供了平行视差。作为一个着色器,它们的计算开销很大,只是没有网格的开销那么大。

限制需要绘制的对象

遮挡剔除(occlusion culling),在摄像机看不见对象时禁用对它们的渲染,因为它们被其他对象遮挡了。

Global Fog(迷雾限制),减少场景中细节渲染,其基于距离,比迷雾限制更远的对象将不会被绘制。

对细节分级或LOD分组,近处的物体用细节模型渲染,远处的模型则用简化的模型渲染,是一种简化几何对象的好方法。

光照和阴影的性能

节约使用实时光影,当某个对象投射阴影时会生成一个阴影贴图,它会被用于渲染其他可能接受阴影的对象。阴影有很高的渲染开销而且通常需要高端的GPU硬件。

其他技术如灯光探测器(实时或烘焙)和着色器的选择。

优化脚本

Update()回调函数每一帧都会被调用。移除不用的更新,使用一个状态变量和if语句在它们不需要时停止计算。内存管理,数学与物理。

批量处理

Unity是将不同的网格归类到一个单独的批处理中,这个批处理会被立即放进图形硬件。这比单独发送网格快很多塌哪。网格实际上先被编译进一个OpenGL顶点缓存对象或一个VBO,这是渲染流水线的低层细节。

每一个批处理调用一次绘制,在一个场景中减少调用绘制次数的比减少顶点或三角形的实际数量的效果更有意义。

共有两种类型的批处理——静态批处理和动态批处理

首先,确认在Player Settings中启用Static Batching和Dynamic Batching。

对于静态批处理,简单地通过在Unity的Inspector中为场景内的每个对象勾选Static复选链衫孙框以标记对象为静态。把一个对象标记为静态是告诉它将永远不能移动,动画或缩放。Unity将自动把这些共享相同材质网格放在一起形成一个大网格。

共享相同材质的网格,所有这样的网格在一个批处理中棚链必须有相同的材质设置——相同的纹理,着色器,着色参数及材质的指针对象。

对于动态批处理,那些没有标记为Static的对象,Unity将尝试把它们放进批处理,即使它会是一个更慢的过程,因为它需要考虑逐帧动画(CPU开销)。共享材质的需求依然存在,当然还有其他的限制,比如顶点个数(小于300个顶点)和统一的Transform Scale规则。只有Mesh Renderers和Particle Systems使用批处理,这意味着蒙皮网格,衣服,尾迹渲染以及其他一些类型的渲染组件并没有使用批处理。

多通道像素填充

多通道像素填充就是某些高级渲染器的工作方式。光照和材质效果,比如多光照,动态阴影及透明度(Trransparent和Fade Render模式)都是以这种方式实现的。

针对项目,可以选择优化并避免通道像素填充在一起,或者理解清楚什么样的场景需要高性能,什么样的场景需要高保真,需要仔细的策划这个场景。

使用Light Probes以很低的成本模拟动态对象的动态光照。

在Quality Settings中把同时发生的光照的全部数量设置为1。

其他渲染技巧

创建2048分辨率的纹理并导入到默认的1024的设置,这样可以加速渲染。

针对无阴影使用高质量的设置渲染到Android时,需要切换目标平台到PC,使用高分辨率烘焙光照并开启硬阴影和软阴影,再切换回Android。

针对低级设备的优化或将程序分为高低版本。

Unity内置的性能评估工具——Stats窗格和Profiler窗格

Game面板中可开启Stats窗格

CPU:获取到当前占用CPU进行计算的时间绝对值,或时间点,如果Unity主进程处于挂断或休眠状态时,CPU time将会保持不变。

Batches:即Batched Draw Calls,是Unity内置的Draw Call Batching技术。

什么叫做“Draw call”,CPU每次通知GPU发出一个 glDrawElements (OpenGl中的图元渲染函数)或者 DrawIndexedPrimitive (DirectX中的顶点绘制方法)的过程称为一次Draw call,一般来说,引擎每对一个物体进行一次DrawCall,就会产生一个Batch,这个Batch里包含着该物体所有的网格和顶点数据,当渲染另一个相同的物体时,引擎会直接调用Batch里的信息,将相关顶点数据直接送到GPU,从而让渲染过程更加高效,即Batching技术是将所有材质相近的物体进行合并渲染。

Tris:摄像机视野(field of view)内渲染的三角面总数量

Verts:摄像机视野(field of view)内渲染的顶点总数

Screen:当前Game屏幕的分辨率大小,5.8M表示总的内存使用数值

SetPass calls:描述渲染性能开销

Shadow casters:表示场景中有多少个可以投射阴影的物体,一般这些物体都作为场景中的光源。

visible skinned meshed:渲染皮肤网格的数量

Animations:正在播放动画的数量

Network:网络情况

Unity中的Profiler选项是一个性能探测工具,可以报告游戏中的哥哥区域花费的时长,包括渲染和脚本。它记录游戏中随着时间的统计数据并以时间线图表展现出来。点击可以逐帧查看细节

中国AR网(www.chinaar.com)连续分享了Unity教程,获得了火热的反响,今天再次分享教程《Unity教程:Unity脚本程序基础》

Unity脚本语言:

Unity3D  目前支持三种语言的脚本程序,包括C#、JavaScript、 Boo,在一个游戏中开发者可以使用一种或者同时使用多种语言来实现脚本的控制。

创建脚本:

在Unity中有两种新建脚本文件的方法,以C#Script为例:

打开菜单栏中Assets->Create->C#Script项。

在Project视图中右击Create或者前拆点击鼠标右键,在快捷菜单中选择Create->C#Script来创建脚本。

MonoDevelop编辑器:

在Project视图中双击脚本文件,Unity将会启动脚本编辑器用于编辑脚本。Unity默认的编困春辑器是内置的MonoDevelop,如下图所示。

脚本必然事件:

脚本相关问题:

脚本在Project中的显示名称不要加cs,类名要和cs名称一致,所有类继承自MonoBehaviour。

项目运行过程中的修改不会保存。

脚本只能依附于游戏对象或者由其他脚本调用才会运行,一个脚本可以放到多个游戏对象上,是多个实例。一个脚本的多个实例和其他脚本之间互不干扰。

脚本中文问题以及更改脚本模板。Unity\Editor\Data\Resources\ScriptTemplates\81-C# Script-NewBehaviourScript.cs编码格式  Ansi -> UTF-8+BOM  格式。

Unity中选择不同脚本编辑器的方式:

更改默认的开发工具,由MonoDev?VS

具体更改步骤:

Edit->Preference->Extennal  Tools ->External Tools>External  script  Editor。

控制台(Console):

Print和慧尺枣Debug打印:

Print是MonoBehaviour的一个成员。Debug则是一个密闭的类。在使用的范围上,Print必须要继承MonoBehaviour类,而Debug不用。 例如:打印输出常用方法的输出频率。Start() 、Update()、 FixedUpdate() 、OnGUI()

教程由中国AR网资源教程(http://www.chinaar.com/ZYJC/)分享,更多教程进入中国AR网可以看到,有相关问题也可以在文章后面进行评论。

//如题,绘制一个点

void DrawPoint(Vector2 point)//绘制一个点

{

//点在电脑屏幕磨胡念上投影成的像素点

int tx = (int)point.x

int ty = (int)point.y

//刷子的半径,函数题目虽说是画一个点,其实是以这个点中心,刷子半径的两倍为正方形边长

int r = brushSize / 2

//dx,dy是点的相对偏瞎困移坐标,详细看下文

int dx = 0

int dy = 0

//如果定义刷子半径小于3

if (brushSize <3)

{

for (int x = 0x <brushSizex++)

for (int y = 0y <= brushSizey++)

{

//防止纹理数组越界

if (x >= 0 &&x <texWidth &&y >= 0 &&y <texHeight)

//将纹理的颜色数组中从[0,0]到[brushSize,brushSize]的一个正方型区域(理想状态,不考虑texWidth或者texHeight小于刷子半径的行为)涂上刷子定做物义的颜色

colors32Draw[y * texWidth + x] = brushColor

}

}

else

{

//索检刷色范围

for (int x = tx - rx <= tx + rx++)

{

dy = 0

for (int y = ty - ry <= ty + ry++)

{

if (x >= 0 &&x <texWidth &&y >= 0 &&y <texHeight &&(brushColor).Equals(fill[(dy * brushSize) + dx]))

{

//如果刷子颜色与背景颜色不同,则将colors32换成刷子颜色

if (brushColor != backgroundColor)

colors32Draw[y * texWidth + x] = brushColor

//否则将该点变为透明,因为color32.a为0,ORZ

else

colors32Draw[y * texWidth + x] = new Color32((byte)(backgroundColor.r * 255), (byte)(backgroundColor.g * 255), (byte)(backgroundColor.b * 255), 0)

}

dy++

if (dy == brushSize) break

}

dx++

if (dx == brushSize) break

}

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8257785.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-14
下一篇 2023-04-14

发表评论

登录后才能评论

评论列表(0条)

保存