- 最后登录
- 2018-6-29
- 注册时间
- 2011-7-1
- 阅读权限
- 20
- 积分
- 359
- 纳金币
- 335582
- 精华
- 0
|
unity3d iOS Porting Tips
The following is an incomplete, unsorted bullet list of tips I picked up while porting my Unity3D game ‘Rope Racket’ to iOS (iPhone/iPad).
I will try to keep this list updated as needed, so check back soon.
Physics
Unity3D uses the highly optimized PhysX physics engine. Normally all operations involving physics should be taken care of automatically by the engine. Here are some points to consider:
§ Colliders – remove unneeded colliders and combine colliders into one. E.g. an enemy object can typically use one collider.
§ Overlapping colliders can produce as many as 3 solving iterations per each frame so pay special attention when forcing position on an object with a collider.
§ Use simpler colliders – sphere is simpler than cube, which is simpler than mesh collider.
§ Joints chain reaction – a movement on one end of the joint always yields movement on the other end. Using several interconnected joints can produce a chain reaction of consequent movements, and should be used with care.
General Optimization
Code optimization can significantly improve performance. In most cases, inefficient programming is the main blame for unoptimized performance.
§ Some operations do not need to be called with every frame. E.g. button states, check distances, AI decisions etc. Most actions can be called 10 times per sec without anyone noticing.
§ Get functions are a neat concept but can be expensive. Declaring a variable as public is crude, but is faster when external access is needed.
§ transform is also a get function. Cache it in a variable when used repetitively.
§ To avoid cpu spikes call garbage collector at scheduled intervals with System.GC.Collect();
§ Precalculate arithmetic tables where possible, or at least cache values when they don’t change (sin/cos/atan/sqrt).
Graphics
iOS GPU is very different from your PC’s. Some well known caveats:
§ Triangle count – I’ve read a lot about some hard limits like 7k but my experience shows that it doesn’t change that much in comparison to other factors. Try to keep below 10k per scene if possible.
§ Memory optimization – change the target maximum texture size per iOS to the smallest possible size without losing details. I found the 256x256 or less is quite sufficient for most objects. You can also change it per each target platform so it looks detailed on PC, and saves on memory on iOS.
§ Complex and multi-pass shaders are slow on iPhone’s GPU. Toon and cutout shading are examples of shaders that should be avoided if possible.
§ Lighting is very expensive. In general, every light is another drawing pass for all affected objects. Use one bright directional light. Use other lights, especially spot and point, with caution. Note that additional lights have two wrongs – they take an additional draw pass per each lit item, and initial light-on calculation takes a few milliseconds of stalled application.
§ Changing vertex position, normals or tangents is expensive and should not be done repetitively. Changing UV (pixel position within texture) is fast, however.
§ OnGUI is called every frame, plus every event. Furthermore, it does not share materials between subsequent calls to texture or text, even when the same resource is used (e.g. 2 calls for text and its shadow). Avoid if you can.
Draw Calls
A Draw Call is one or more objects, sharing a single material on a single camera, in a single shader pass, being placed on screen.
My experience proves that the most important element to optimize is to reduce the number of draw calls, even in high-end mobile device such as iPad. Apparently the pipeline between the CPU and GPU is not as efficient as in non-mobile devices.
§ Make sure Dynamic Batching is checked.
§ When checked, the engine groups all objects by their shared material, up to a maximum number of vertices per batch. Make sure that member sharedMaterial is used instead of material, whenever applicable.
§ Furthermore, all batched objects must share queue pass. Each camera has multiple drawing passes. If a few materials share the same pass, there is no guarantee that all objects using the same material will be batched. Therefore you can help Unity by placing a material in a particular pass by changing its pass order.
For example, shader directive Tags {“Queue” = “Transparent-1” }
will make sure that this shader is drawn right after Transparent pass. So setting Transparent-1 separates this new material from normal Transparent shaded materials, and batches all objects using this material into one pass.
Note: This trick also helps when trying to sort depths and fix Z issues.
§ Most importantly: Use one material (one texture) for as many objects as you can. For example, use an icon atlas and change UV position according to the desired image.
§ Alternative solution: load a font and export its texture. Place all your images on the exported font texture instead of the original letters. Then, use Text Mesh and change the letters to display the proper icon.
More Tips
Here are some handy non-optimization tips:
§ Instead of OnGUI or GUITexture, display all GUI in a new camera.
o Create a new camera for GUI: isometric, ignores all other layers, Depth 1 (to draw after main camera) and Don’t Clear.
o Use Text Mesh and Mesh Renderer to draw text. Make sure that the GameObject is set to the GUI camera layer. This is a very fast and versatile to use dynamic, localized text in Unity. Text can be changed, rotated, scaled and a user-defined material can be used instead of standard font.
o Similarly, logos and images can be displayed on boxes. The triangle cost is minimal and on this isometric camera, the side walls are culled.
When transparent image is used, either use a shader with Culling On so the back wall is removed, or place the box very close to the camera so the front wall is behind the camera and only the back wall is shown.
§ White border around textures is caused when a zero-alpha color partly bleeds into a visible pixel. In this case, the RGB part of that supposedly transparent pixel is taken into effect. To fix it in photoshop:
o Select all zero-alpha pixels
o Paint around the edges of the images with the edge color (the select region will protect the image)
o Create Layar Mask -> Hide selected area.
The result is an image where the RGB part of zero-alpha pixels matches the edges of the texture and bled pixels look nice.
More tips to follow soon.
//==========================================
Unity3D的iOS移植技巧
以下是一个不完整的的,未排序的符号列表,我拿起我Unity3D游戏“跳绳球拍”IOS(iPhone / ipad公司)移植时的提示。
我会尽量保持这个列表需要更新,所以请尽快。
物理
Unity3D使用高度优化的PhysX物理引擎。通常涉及物理学的所有操作,应采取由引擎自动处理。以下几点考虑:
§对撞机 - 删除不必要的对撞机,并结合成一个对撞机。例如敌人的对象通常可以使用一个对撞机。
§重叠对撞机可以产生解决多达3每人每帧的迭代,迫使时要特别注意与对撞机的对象的位置。
§使用简单的对撞机 - 球体比立方体,这是比网状撞机简单简单。
§接头链反应 - 一端联合运动总是产生在另一端的运动。使用几个相互联系的关节可以产生连锁反应,随之而来的运动,并应小心使用。
一般优化
代码优化,可以显着提高性能。在大多数情况下,低效率的编程是未优化性能的主要怪。
§某些操作不需要每帧调用。例如按钮状态,检查距离,人工智能的决定等,大多数操作可以被称为每秒10次,没有任何人的注意。
§获取功能是一个整洁的概念,但可能是昂贵的。声明一个变量作为公众原油,但速度时需要的外部访问。
§改造也是一个get函数。缓存在一个变量时重复使用。
§为了避免CPU峰值调用垃圾收集器在System.GC.Collect()预定的时间间隔;
§预先计算的算术表,在可能的情况下,或至少缓存值时,他们不改变(正弦/余弦/ ATAN / SQRT)。
图形
IOS GPU是从电脑的非常不同。一些知名的注意事项:
§三角计数 - 我读过有关7K这样一些硬性限制了很多,但我的经验表明,它并没有改变与其他因素相比,那么多。如果可能的话尽量保持低于10K每个场景。
§内存优化 - 改变目标的最大每IOS纹理尺寸,而不会丢失细节,以尽可能小的尺寸。我发现,256 × 256或以下,大多数对象是相当足够的。您还可以更改每每个目标平台,所以它看起来详细的PC上,并节省内存在iOS。
§复杂和多通道的着色器是iPhone的GPU缓慢。香椿和开孔阴影着色器,应尽量避免的例子。
§照明是非常昂贵的。在一般情况下,每一个灯是另一个绘图通过为所有受影响的的对象。使用一个光明的定向光。其他的灯,特别是现货和点,谨慎使用。请注意,额外的灯有两个错误 - 他们采取每一个额外的抽奖通,每个点燃项目和初始光的计算需要几毫秒的时间停滞不前的应用。
§改变顶点位置,法线或切线是昂贵的,不应该做的重复。是快的,但是改变紫外线(内纹理的像素位置)。
§ OnGUI被称为每一帧,再加上每一个事件。此外,它不共享材料之间的纹理或文字的后续调用,即使使用相同的资源(如调用的文本和它的影子)。避免,如果你能。
绘图调用
平局调用一个或多个对象,被放置在屏幕上,在一个着色器通过共享一个单一的材料,一台摄像机。
我的经验证明,最重要的元素,优化,以减少绘图调用,即使在高端iPad的移动设备,如。显然,CPU和GPU之间的管道,是不是像在非移动设备的高效。
§请确保选中动态配料。
§检查时,发动机组中的所有对象,由他们共同的材料,到最大数量每批次的顶点。确保成员sharedMaterial使用,而不是物质,只要适用。
§此外,所有的批处理对象必须共享队列传递。每个摄像机有多个绘图通行证。如果几个材料有着相同的通过,有没有将成批保证所有对象使用相同的材料。因此,您可以帮助Unity3D放置在一个特定的传递的材料,通过改变其传递次序。
例如,着色器的指令标签{“队列”=“透明- 1”}
将确保这个着色器是透明的传递后得出。设置透明- 1从正常透明阴影材料分离这种新材料,和批次的所有对象到一个通过使用这种材料。
注:这招也帮助时,试图进行排序的深度和修复Ž问题。
§最重要的是:许多对象,你可以使用一种材料(一个纹理)。例如,使用一个图标图集根据所需的图像,改变紫外线位置。
§替代解决方案:加载的字体和出口其质地。所有的图像放在出口,而不是原来的字母,字体纹理。然后,使用文字网和改变的字母,以显示正确的图标。
更多技巧
下面是一些方便的非优化技巧:
OnGUI或GUITexture §相反,显示在一个新的相机的GUI。
o创建一个GUI的新相机:等距,忽略所有其他层,深度为1(主摄像头后,绘制),不清除。
o使用文字网和丝网渲染绘制文本。确保游戏物体是设置GUI相机层。这是一个非常快速和灵活使用的动态,团结本地化的文本。可以改变文本,旋转,缩放,并可以使用标准字体,而不是一个用户定义的物质。
Ø同样,标识和图像可以显示在箱。三角形的成本是最小的,在此等角相机,侧墙扑杀。
当使用透明的图像,或者使用扑杀后墙就这么被删除,着色或地方框非常接近相机,使前墙背后的摄像头,并只显示后墙。
§白色边框周围的纹理是造成零-α的颜色时,部分进入一个可见的像素出血。在这种情况下,假想的透明像素的RGB部分生效。要修复它在Photoshop:
o选择所有零-α像素
Ø围绕边缘颜色的图像边缘油漆(选择地区将保护图像)
o创建拉亚面膜 - >隐藏选定的区域。
结果是零-α像素的RGB部分匹配的纹理和流血像素的边缘,好看的形象。
|
|