A useful background to iOS optimization can be found on the iOS hardware page.
iOS设备上运行alpha-test会极耗费cpu。尽可能的用“alpha-blend”材质来替代“alpha-test”材质。如果不可避免的需要使用“alpha-test”材质的话,把alpha-test像素数量调至最少。
通常情况下,让每帧显示顶点数少于40,000个(iPhone 3GS),对于更老的设备,让顶点数少于10,000个。(iPhone,iPhone 3G,iPod Touch 1代和2代)
Per-vertex dynamic lighting会增加大量的顶点位移。避免多个灯光照射同一物体。对于静止物体(Static object)灯光烘培是最好的方法。
优化多边形模型时,有2条基本原则:
-1- 不要使用任何多余的三角面
-2- 让UV贴图接缝数和硬边(如,doubled-up vertices)尽可能的少
注意,显卡需处理的顶点数通常和3D软件显示的顶点数不同。建模软件通常显示的是构成一个模型的各表面转角顶点数之和。而显卡有时需要把一个多边形上的顶点分割为二个、甚至更多逻辑点以便于渲染。如果一个顶点拥有多重法线、UV坐标或顶点色,则这个顶点将被分割。Unity中的顶点数一般会比3D软件中的显示数目大得多。
Using iOS's native PVRT compression formats will decrease the size of your textures (resulting in faster load times and smaller memory footprint) and can also dramatically increase rendering performance. Compressed textures use only a fraction of the memory bandwidth needed for uncompressed 32bit RGBA textures. A comparison of uncompressed vs compressed texture performance can be found in the iOS Hardware Guide.
Some images are prone to visual artifacts in the alpha channels of PVRT-compressed textures. In such cases, you might need to tweak the PVRT compression parameters directly in your imaging software. You can do that by installing the PVR export plugin or using PVRTexTool from Imagination Tech, the creators of the PVRT format. The resulting compressed image file with a .pvr extension will be imported by the Unity editor directly and the specified compression parameters will be preserved.
If PVRT-compressed textures do not give good enough visual quality or you need especially crisp imaging (as you might for GUI textures, say) then you should consider using 16-bit textures instead of RGBA textures. By doing so, you will reduce the memory bandwidth by half.
The GPUs on iOS devices have fully supported pixel and vertex shaders since the iPhone 3GS. However, the performance is nowhere near what you would get from a desktop machine, so you should not expect desktop shaders to port to iOS unchanged. Typically, shaders will need to be hand optimized to reduce calculations and texture reads in order to get good performance.
Transcendental mathematical functions (such as pow, exp, log, cos, sin, tan, etc) will tax the GPU greatly, so a good rule of thumb is to have no more than one such operation per fragment. Consider using lookup textures as an alternative where applicable.
It is not advisable to attempt to write your own normalize, dot, inversesqrt operations, however. If you use the built-in ones then the driver will generate much better code for you.
Bear in mind also that the discard operation will make your fragments slower.
You should always specify the precision of floating point variables when writing custom shaders. It is critical to pick the smallest possible floating point format in order to get the best performance.
If the shader is written in GLSL ES then the floating point precision is specified as follows:-
If the shader is written in CG or it is a surface shader then precision is specified as follows:-
For further details about shader performance, please read the Shader Performance page.
Take your time to study Apple documentations on hardware and best practices for writing shaders. Note that we would suggest to be more aggressive with floating point precision hints however.
Bake your scene static lighting into textures using Unity built-in Lightmapper. The process of generating a lightmapped environment takes only a little longer than just placing a light in the scene in Unity, but:
If a number of objects being rendered by the same camera uses the same material, then Unity iOS will be able to employ a large variety of internal optimizations such as:
All these optimizations will save you precious CPU cycles. Therefore, putting extra work to combine textures into single atlas and making number of objects to use the same material will always pay off. Do it!
Below are some tips for designing character models to give optimal rendering speed.
You should use only a single skinned mesh renderer for each character. Unity optimizes animation using visibility culling and bounding volume updates and these optimizations are only activated if you use one animation component and one skinned mesh renderer in conjunction. The rendering time for a model could roughly double as a result of using two skinned meshes in place of a single mesh and there is seldom any practical advantage in using multiple meshes.
You should also keep the number of materials on each mesh as low as possible. The only reason why you might want to have more than one material on a character is that you need to use different shaders for different parts (eg, a special shader for the eyes). However, two or three materials per character should be sufficient in almost all cases.
A bone hierarchy in a typical desktop game uses somewhere between fifteen and sixty bones. The fewer bones you use, the better the performance will be. You can achieve very good quality on desktop platforms and fairly good quality on mobile platforms with about thirty bones. Ideally,keep the number below thirty for mobile devices and don't go too far above thirty for desktop games.
The number of polygons you should use depends on the quality you require and the platform you are targeting. For mobile devices, somewhere between 300 and 1500 polygons per mesh will give good results, whereas for desktop platforms the ideal range is about 1500 to 4000. You may need to reduce the polygon count per mesh if the game can have lots of characters onscreen at any given time. As an example, Half Life 2 used 2500-5000 triangles per character. Current AAA games running on the PS3 or Xbox 360 usually have characters with 5000-7000 triangles.
When animations are imported, a model's inverse kinematic (IK) nodes are baked into forward kinematics (FK) and as a result, Unity doesn't need the IK nodes at all. However, if they are left in the model then they will have a CPU overhead even though they don't affect the animation. You can delete the redundant IK nodes in Unity or in the modeling tool, according to your preference. Ideally, you should keep separate IK and FK hierarchies during modeling to make it easier to remove the IK nodes when necessary.
To draw an object on the screen, the engine has to issue a draw call to the graphics API (OpenGL ES in the case of iOS). Every single draw call requires a significant amount of work on the part of the graphics API, causing significant performance overhead on the CPU side.
Unity combines a number of objects at runtime and draws them together with a single draw call. This operation is called "batching". The more objects Unity can batch together, the better rendering performance you will get.
Built-in batching support in Unity has significant benefit over simply combining geometry in the modeling tool (or using the CombineChildren script from the Standard Assets package). Batching in Unity happens after visibility determination step. The engine does culling on each object individually, and the amount of rendered geometry is going to be the same as without batching. Combining geometry in the modeling tool, on the other hand, prevents effecient culling and results in much higher amount of geometry being rendered.
Only objects sharing the same material can be batched together. Therefore, if you want to achieve good batching, you need to share as many materials among different objects as possible.
If you have two identical materials which differ only in textures, you can combine those textures into a single big texture - a process often called texture atlasing. Once textures are in the same atlas, you can use single material instead.
If you need to access shared material properties from the scripts, then it is important to note that modifying Renderer.material will create a copy of the material. Instead, you should useRenderer.sharedMaterial to keep material shared.
Unity can automatically batch moving objects into the same draw call if they share the same material.
Dynamic batching is done automatically and does not require any additional effort on your side.
Static batching, on the other hand, allows the engine to reduce draw calls for geometry of any size (provided it does not move and shares the same material). Static batching is significantly more efficient than dynamic batching. You should choose static batching as it will require less CPU power.
In order to take advantage of static batching, you need explicitly specify that certain objects are static and will not move, rotate or scale in the game. To do so, you can mark objects as static using the Static checkbox in the Inspector:
Using static batching will require additional memory for storing the combined geometry. If several objects shared the same geometry before static batching, then a copy of geometry will be created for each object, either in the Editor or at runtime. This might not always be a good idea - sometimes you will have to sacrifice rendering performance by avoiding static batching for some objects to keep a smaller memory footprint. For example, marking trees as static in a dense forest level can have serious memory impact.
Static batching is only available in Unity iOS Advanced.
The Game View has a Stats button in the top right corner. When the button is pressed, an overlay window is displayed which shows realtime rendering statistics, which are useful for optimizing performance. The exact statistics displayed vary according to the build target.
The Statistics window contains the following information:-
Time per frame and FPS | The amount of time taken to process and render one game frame (and its reciprocal, frames per second). Note that this number only includes the time taken to do the frame update and render the game view; it does not include the time taken in the editor to draw the scene view, inspector and other editor-only processing. |
Draw Calls | The total number of meshes drawn after batching was applied. Note that where objects are rendered multiple times (for example, objects illuminated by pixel lights), each rendering results in a separate draw call. |
Batched (Draw Calls) | The number of initially separate draw calls that were added to batches. "Batching" is where the engine attempts to combine the rendering of multiple objects into one draw call in order to reduce CPU overhead. To ensure good batching, you should share materials between different objects as often as possible. |
Tris andVerts | The number of triangles and vertices drawn. This is mostly important when optimizing for low-end hardware |
Used Textures | The number of textures used to draw this frame and their memory usage. |
Render Textures | The number of Render Textures and their memory usage. The number of times the active Render Texture was switched each frame is also displayed. |
Screen | The size of the screen, along with its anti-aliasing level and memory usage. |
VRAM usage | Approximate bounds of current video memory (VRAM) usage. This also shows how much video memory your graphics card has. |
VBO total | The number of unique meshes (Vertex Buffers Objects or VBOs) that are uploaded to the graphics card. Each different model will cause a new VBO to be created. In some cases scaled objects will cause additional VBOs to be created. In the case of a static batching, several different objects can potentially share the same VBO. |
Visible Skinned Meshes | The number of skinned meshes rendered. |
Animations | The number of animations playing. |
Unity comes with a performance profiler. It is disabled by default so to enable it, you need to open the Unity-generated XCode project, select the iPhone_Profiler.h
file and change the line
#define ENABLE_INTERNAL_PROFILER 0
to
#define ENABLE_INTERNAL_PROFILER 1
Select Run->Console in the XCode menu to display the output console (GDB) and then run your project. Unity will output statistics to the console window every thirty frames. For example:
iPhone/iPad Unity internal profiler stats: cpu-player> min: 9.8 max: 24.0 avg: 16.3 cpu-ogles-drv> min: 1.8 max: 8.2 avg: 4.3 cpu-waits-gpu> min: 0.8 max: 1.2 avg: 0.9 cpu-present> min: 1.2 max: 3.9 avg: 1.6 frametime> min: 31.9 max: 37.8 avg: 34.1 draw-call #> min: 4 max: 9 avg: 6 | batched: 10 tris #> min: 3590 max: 4561 avg: 3871 | batched: 3572 verts #> min: 1940 max: 2487 avg: 2104 | batched: 1900 player-detail> physx: 1.2 animation: 1.2 culling: 0.5 skinning: 0.0 batching: 0.2 render: 12.0 fixed-update-count: 1 .. 2 mono-scripts> update: 0.5 fixedUpdate: 0.0 coroutines: 0.0 mono-memory> used heap: 233472 allocated heap: 548864 max number of collections: 1 collection total duration: 5.7
All times are measured in milliseconds per frame. You can see the minimum, maximum and average times over the last thirty frames.
cpu-player | Displays the time your game spends executing code inside the Unity engine and executing scripts on the CPU. |
cpu-ogles-drv | Displays the time spent executing OpenGL ES driver code on the CPU. Many factors like the number of draw calls, number of internal rendering state changes, the rendering pipeline setup and even the number of processed vertices can have an effect on the driver stats. |
cpu-waits-gpu | Displays the time the CPU is idle while waiting for the GPU to finish rendering. If this number exceeds 2-3 milliseconds then your application is most probably fillrate/GPU processing bound. |
cpu-present | The amount of time spent executing the presentRenderbuffer command in OpenGL ES. |
frametime | Represents the overall time of a game frame. Note that iOS hardware is always locked at a 60Hz refresh rate, so you will always get multiples times of ~16.7ms (1000ms/60Hz = ~16.7ms). |
draw-call # | The number of draw calls per frame. Keep it as low as possible. |
tris # | Total number of triangles sent for rendering. |
verts # | Total number of vertices sent for rendering. You should keep this number below 10000 if you use only static geometry but if you have lots of skinned geometry then you should keep it much lower. |
batched | Number of draw-calls, triangles and vertices which were automatically batched by the engine. Comparing these numbers with draw-call and triangle totals will give you an idea how well is your scene prepared for batching. Share as many materials as possible among your objects to improve batching. |
The player-detail section provides a detailed breakdown of what is happening inside the engine:-
physx | Time spent on physics. |
animation | Time spent animating bones. |
culling | Time spent culling objects outside the camera frustum. |
skinning | Time spent applying animations to skinned meshes. |
batching | Time spent batching geometry. Batching dynamic geometry is considerably more expensive than batching static geometry. |
render | Time spent rendering visible objects. |
fixed-update-count | Minimum and maximum number of FixedUpdates executed during this frame. Too many FixedUpdates will deteriorate performance considerably. There are some simple guidelines to set a good value for the fixed time delta here. |
The mono-scripts section provides a detailed breakdown of the time spent executing code in the Mono runtime:
update | Total time spent executing all Update() functions in scripts. |
fixedUpdate | Total time spent executing all FixedUpdate() functions in scripts. |
coroutines | Time spent inside script coroutines. |
The mono-memory section gives you an idea of how memory is being managed by the Mono garbage collector:
allocated heap | Total amount of memory available for allocations. A garbage collection will be triggered if there is not enough memory left in the heap for a given allocation. If there is still not enough free memory even after the collection then the allocated heap will grow in size. |
used heap | The portion of the allocated heap which is currently used up by objects. Every time you create a new class instance (not a struct) this number will grow until the next garbage collection. |
max number of collections | Number of garbage collection passes during the last 30 frames. |
collection total duration | Total time (in milliseconds) of all garbage collection passes that have happened during the last 30 frames. |
The two main ways of reducing the size of the player are by changing the Active Build Configuration within Xcode and by changing the Stripping Level within Unity.
You can choose between the Debug and Release options on the Active Build Configuration drop-down menu in Xcode. Building as Release instead of Debug can reduce the size of the built player by as much as 2-3MB, depending on the game.
In Release mode, the player will be built without any debug information, so if your game crashes or has other problems there will be no stack trace information available for output. This is fine for deploying a finished game but you will probably want to use Debug mode during development.
The size optimizations activated by stripping work in the following way:-
These levels are cumulative, so level 3 optimization implicitly includes levels 2 and 1, while level 2 optimization includes level 1.
Note: Micro mscorlib is a heavily stripped-down version of the core library. Only those items that are required by the Mono runtime in Unity remain. Best practice for using micro mscorlib is not to use any classes or other features of .NET that are not required by your application. GUIDs are a good example of something you could omit; they can easily be replaced with custom made pseudo GUIDs and doing this would result in better performance and app size.
Stripping depends highly on static code analysis and sometimes this can't be done effectively, especially when dynamic features like reflection are used. In such cases, it is necessary to give some hints as to which classes shouldn't be touched. Unity supports a per-project custom strippingblacklist. Using the blacklist is a simple matter of creating a link.xml file and placing it into the Assets folder. An example of the contents of the link.xml file follows. Classes marked for preservation will not be affected by stripping:-
Note: it can sometimes be difficult to determine which classes are getting stripped in error even though the application requires them. You can often get useful information about this by running the stripped application on the simulator and checking the Xcode console for error messages.
Yes. An empty project would take about 13 MB in the AppStore if all the size optimizations were turned off. This gives you a budget of about 7MB for compressed assets in your game. If you own an Advanced License (and therefore have access to the stripping option), the empty scene with just the main camera can be reduced to about 6 MB in the AppStore (zipped and DRM attached) and you will have about 14 MB available for compressed assets.
When they publish your app, Apple first encrypt the binary file and then compresses it via zip. Most often Apple's DRM increases the binary size by about 4 MB or so. As a general rule, you should expect the final size to be approximately equal to the size of the zip-compressed archive of all files (except the executable) plus the size of the uncompressed executable file.
The following table summarizes iOS hardware available in devices of various generations:
The iPhone/iPad graphics processing unit (GPU) is a Tile-Based Deferred Renderer. In contrast with most GPUs in desktop computers, the iPhone/iPad GPU focuses on minimizing the work required to render an image as early as possible in the processing of a scene. That way, only the visible pixels will consume processing resources.
The GPU's frame buffer is divided up into tiles and rendering happens tile by tile. First, triangles for the whole frame are gathered and assigned to the tiles. Then, visible fragments of each triangle are chosen. Finally, the selected triangle fragments are passed to the rasterizer (triangle fragments occluded from the camera are rejected at this stage).
In other words, the iPhone/iPad GPU implements a Hidden Surface Removal operation at reduced cost. Such an architecture consumes less memory bandwidth, has lower power consumption and utilizes the texture cache better. Tile-Based Deferred Rendering allows the device to reject occluded fragments before actual rasterization, which helps to keep overdraw low.
For more information see also:-
Starting with the iPhone 3GS, newer devices are equipped with the SGX series of GPUs. The SGX series features support for the OpenGL ES2.0 rendering API and vertex and pixel shaders. The Fixed-function pipeline is not supported natively on such GPUs, but instead is emulated by generating vertex and pixel shaders with analogous functionality on the fly.
The SGX series fully supports MultiSample anti-aliasing.
Older devices such as the original iPhone, iPhone 3G and iPod Touch 1st and 2nd Generation are equipped with the MBX series of GPUs. The MBX series supports only OpenGL ES1.1, the fixed function Transform/Lighting pipeline and two textures per fragment.
The only texture compression format supported by iOS is PVRTC. PVRTC provides support for RGB and RGBA (color information plus an alpha channel) texture formats and can compress a single pixel to two or four bits.
The PVRTC format is essential to reduce the memory footprint and to reduce consumption of memory bandwidth (ie, the rate at which data can be read from memory, which is usually very limited on mobile devices).
The iPhone/iPad has a dedicated unit responsible for vertex processing which runs calculations in parallel with rasterization. In order to achieve better parallelization, the iPhone/iPad processes vertices one frame ahead of the rasterizer.
CPU和GPU共用内存。图像使用了更多的内存,则游戏可用的内存就更少。
The iPhone/iPad main CPU is equipped with a powerful SIMD (Single Instruction, Multiple Data) coprocessor supporting either the VFP or the NEON architecture. The Unity iOS run-time takes advantage of these units for multiple tasks such as calculating skinned mesh transformations, geometry batching, audio processing and other calculation-intensive operations.
--------------------------------------------------------------------------------------------Textures bring your Meshes, Particles, and interfaces to life! They are image or movie files that you lay over or wrap around your objects. As they are so important, they have a lot of properties. If you are reading this for the first time, jump down to Details, and return to the actual settings when you need a reference.
The shaders you use for your objects put specific requirements on which textures you need, but the basic principle is that you can put any image file inside your project. If it meets the size requirements (specified below), it will get imported and optimized for game use. This extends to multi-layer Photoshop or TIFF files - they are flattened on import, so there is no size penalty for your game.
The Texture Inspector looks a bit different from most others:
The top section contains a few settings, and the bottom part contains the Texture Importer and the texture preview.
Aniso Level | Increases texture quality when viewing the texture at a steep angle. Good for floor and ground textures, see below. |
Filter Mode | Selects how the Texture is filtered when it gets stretched by 3D transformations: |
Point | The Texture becomes blocky up close |
Bilinear | The Texture becomes blurry up close |
Trilinear | Like Bilinear, but the Texture also blurs between the different mip levels |
Wrap Mode | Selects how the Texture behaves when tiled: |
Repeat | The Texture repeats (tiles) itself |
Clamp | The Texture's edges get stretched |
Textures all come from image files in your Project Folder. How they are imported is specified by the Texture Importer. You change these by selecting the file texture in the Project View and modifying the Texture Importer in the Inspector.
In Unity 3 we simplified for you all the settings, now you just need to select what are you going to use the texture for and Unity will set default parameters for the type of texture you have selected. Of course if you want to have total control of your texture and do specific tweaks, you can set the Texture Type to Advanced. This will present the full set of options that you have available.
Texture Type | Select this to set basic parameters depending on the purpose of your texture. |
Texture | This is the most common setting used for all the textures in general. |
Normal Map | Select this to turn the color channels into a format suitable for real-time normal mapping. For more info, see Normal Maps |
GUI | Use this if your texture is going to be used on any HUD/GUI Controls. |
Reflection | Also known as Cube Maps, used to create reflections on textures. check Cubemap Textures for more info. |
Cookie | This sets up your texture with the basic parameters used for the Cookies of your lights |
Advanced | Select this when you want to have specific parameters on your texture and you want to have total control over your texture. |
Generate Alpha From Grayscale | If enabled, an alpha transparency channel will be generated by the image's existing values of light & dark. |
Generate from Greyscale | |
Bumpiness | Control the amount of bumpiness. |
Filtering | Determine how the bumpiness is calculated: |
Smooth | This generates normal maps that are quite smooth. |
Sharp | Also known as a Sobel filter. this generates normal maps that are sharper than Standard. |
You dont need to set any values in this case, Unity will set all the values for you.
Mapping | This determines how the texture will be mapped to a cubemap. |
Sphere Mapped | Maps the texture to a "sphere like" cubemap. |
Cylindrical | Maps the texture to a cylinder, use this when you want to use reflections on objects that are like cylinders. |
Simple Sphere | Maps the texture to a simple sphere, deforming the reflection when you rotate it. |
Nice Sphere | Maps the texture to a sphere, deforming it when you rotate but you still can see the texture's wrap |
An interesting way to add a lot of visual detail to your scenes is to use Cookies - greyscale textures you use to control the precise look of in-game lighting. This is fantastic for making moving clouds and giving an impression of dense foliage. The Light page has more info on all this, but the main thing is that for textures to be usable for cookies you just need to set the Texture Type to Cookie.
Light Type | Type of light that the texture will be applied to. (This can be Spotlight, Point or Directional lights). For Directional Lights this texture will tile, so in the texture inspector, you must set the Edge Mode to Repeat; for SpotLights You should keep the edges of your cookie texture solid black in order to get the proper effect. In the Texture Inspector, set the Edge Mode to Clamp. |
Generate Alpha from Greyscale | If enabled, an alpha transparency channel will be generated by the image's existing values of light & dark. |
Non Power of 2 | If texture has non-power-of-two size, this will define a scaling behavior at import time (for more info see the Texture Sizes section below): |
None | Texture will be padded to the next larger power-of-two size for use with GUITexture component. |
To nearest | Texture will be scaled to the nearest power-of-two size at import time. For instance 257x511 texture will become 256x512. Note that PVRTC formats require textures to be square (width equal to height), therefore final size will be upscaled to 512x512. |
To larger | Texture will be scaled to the next larger power-of-two size at import time. For instance 257x511 texture will become 512x512. |
To smaller | Texture will be scaled to the next smaller power-of-two size at import time. For instance 257x511 texture will become 256x256. |
Generate Cube Map | Generates a cubemap from the texture using different generation methods. |
Read/Write Enabled | Select this to enable access to the texture data from scripts (GetPixels, SetPixels and otherTexture2D functions). Note however that a copy of the texture data will be made, doubling the amount of memory required for texture asset. Use only if absolutely necessary. This is only valid for uncompressed and DTX compressed textures, other types of compressed textures cannot be read from. Disabled by default. |
Generate Mip Maps | Select this to enable mip-map generation. Mip maps are smaller versions of the texture that get used when the texture is very small on screen. For more info, see Mip Maps below. |
Correct Gamma | Select this to enable per-mip-level gamma correction. |
Border Mip Maps | Select this to avoid colors seeping out to the edge of the lower Mip levels. Used for light cookies (see below). |
Mip Map Filtering | Two ways of mip map filtering are available to optimize image quality: |
Box | The simplest way to fade out the mipmaps - the mip levels become smoother and smoother as they go down in size. |
Kaiser | A sharpening Kaiser algorithm is run on the mip maps as they go down in size. If your textures are too blurry in the distance, try this option. |
Fade Out Mips | Enable this to make the mipmaps fade to gray as the mip levels progress. This is used for detail maps. The left most scroll is the first mip level to begin fading out at. The rightmost scroll defines the mip level where the texture is completely grayed out |
Generate Normal Map | Enable this to turn the color channels into a format suitable for real-time normal mapping. For more info, see Normal Maps, below. |
Bumpiness | Control the amount of bumpiness. |
Filtering | Determine how the bumpiness is calculated: |
Smooth | This generates normal maps that are quite smooth. |
Sharp | Also known as a Sobel filter. this generates normal maps that are sharper than Standard. |
Normal Map | Select this if you want to see how the normal map will be applied to your texture. |
Lightmap | Select this if you want to use the texture as a lightmap. |
When you are building for different platforms, you have to think on the resolution of your textures for the target platform, the size and the quality. With Unity 3 you can override these options and assign specific values depending on the platform you are deploying to. Note that if you don't select any value to override, the Editor will pick the default values when building your project.
Max Texture Size | The maximum imported texture size. Artists often prefer to work with huge textures - scale the texture down to a suitable size with this. |
Texture Format | What internal representation is used for the texture. This is a tradeoff between size and quality. In the examples below we show the final size of a in-game texture of 256 by 256 pixels: |
Compressed | Compressed RGB texture. This is the most common format for diffuse textures. 4 bits per pixel (32 KB for a 256x256 texture). |
16 bit | Low-quality truecolor. Has 16 levels of red, green, blue and alpha. |
Truecolor | Truecolor, this is the highest quality. At 256 KB for a 256x256 texture. |
If you have set the Texture Type to Advanced then the Texture Format has different values.
Texture Format | What internal representation is used for the texture. This is a tradeoff between size and quality. In the examples below we show the final size of an in-game texture of 256 by 256 pixels: |
RGB Compressed DXT1 | Compressed RGB texture. This is the most common format for diffuse textures. 4 bits per pixel (32 KB for a 256x256 texture). |
RGBA Compressed DXT5 | Compressed RGBA texture. This is the main format used for diffuse & specular control textures. 1 byte/pixel (64 KB for a 256x256 texture). |
RGB 16 bit | 65 thousand colors with no alpha. Compressed DXT formats use less memory and usually look better. 128 KB for a 256x256 texture. |
RGB 24 bit | Truecolor but without alpha. 192 KB for a 256x256 texture. |
Alpha 8 bit | High quality alpha channel but without any color. 64 KB for a 256x256 texture. |
RGBA 16 bit | Low-quality truecolor. Has 16 levels of red, green, blue and alpha. Compressed DXT5 format uses less memory and usually looks better. 128 KB for a 256x256 texture. |
RGBA 32 bit | Truecolor with alpha - this is the highest quality. At 256 KB for a 256x256 texture, this one is expensive. Most of the time, DXT5 offers sufficient quality at a much smaller size. The main way this is used is for normal maps, as DXT compression there often carries a visible quality loss. |
Texture Format | What internal representation is used for the texture. This is a tradeoff between size and quality. In the examples below we show the final size of a in-game texture of 256 by 256 pixels: |
RGB Compressed PVRTC 4 bits | Compressed RGB texture. This is the most common format for diffuse textures. 4 bits per pixel (32 KB for a 256x256 texture) |
RGBA Compressed PVRTC 4 bits | Compressed RGBA texture. This is the main format used for diffuse & specular control textures or diffuse textures with transparency. 4 bits per pixel (32 KB for a 256x256 texture) |
RGB Compressed PVRTC 2 bits | Compressed RGB texture. Lower quality format suitable for diffuse textures. 2 bits per pixel (16 KB for a 256x256 texture) |
RGBA Compressed PVRTC 2 bits | Compressed RGBA texture. Lower quality format suitable for diffuse & specular control textures. 2 bits per pixel (16 KB for a 256x256 texture) |
RGB Compressed DXT1 | Compressed RGB texture. This format is not supported on iOS, but kept for backwards compatibility with desktop projects. |
RGBA Compressed DXT5 | Compressed RGBA texture. This format is not supported on iOS, but kept for backwards compatibility with desktop projects. |
RGB 16 bit | 65 thousand colors with no alpha. Uses more memory than PVRTC formats, but could be more suitable for UI or crisp textures without gradients. 128 KB for a 256x256 texture. |
RGB 24 bit | Truecolor but without alpha. 192 KB for a 256x256 texture. |
Alpha 8 bit | High quality alpha channel but without any color. 64 KB for a 256x256 texture. |
RGBA 16 bit | Low-quality truecolor. Has 16 levels of red, green, blue and alpha. Uses more memory than PVRTC formats, but can be handy if you need exact alpha channel. 128 KB for a 256x256 texture. |
RGBA 32 bit | Truecolor with alpha - this is the highest quality. At 256 KB for a 256x256 texture, this one is expensive. Most of the time, PVRTC formats offers sufficient quality at a much smaller size. |
Unity can read the following file formats: PSD, TIFF, JPG, TGA, PNG, GIF, BMP, IFF, PICT. It should be noted that Unity can import multi-layer PSD & TIFF files just fine. They are flattened automatically on import but the layers are maintained in the assets themselves, so you don't lose any of your work when using these file types natively. This is important as it allows you to just have one copy of your textures that you can use from Photoshop, through your 3D modelling app and into Unity.
Ideally texture sizes should be powers of two on the sides. These sizes are as follows: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024 or 2048 pixels. The textures do not have to be square, i.e. width can be different from height.
It is possible to use other (non power of two) texture sizes with Unity. Non power of two texture sizes work best when used on GUI Textures, however if used on anything else they will be converted to an uncompressed RGBA 32 bit format. That means they will take up more video memory (compared to PVRT(iOS)/DXT(Desktop) compressed textures), will be slower to load and slower to render (if you are on iOS mode). In general you'll use non power of two sizes only for GUI purposes.
Non power of two texture assets can be scaled up at import time using the Non Power of 2 option in the advanced texture type in the import settings. Unity will scale texture contents as requested, and in the game they will behave just like any other texture, so they can still be compressed and very fast to load.
When mapping a 2D texture onto a 3D model, some sort of wrapping is done. This is called UV mapping and is done in your 3D modelling app. Inside Unity, you can scale and move the texture using Materials. Scaling normal & detail maps is especially useful.
Mip Maps are a list of progressively smaller versions of an image, used to optimise performance on real-time 3D engines. Objects that are far away from the camera use the smaller texture versions.Using mip maps uses 33% more memory, but not using them can be a huge performance loss. You should always use mipmaps for in-game textures; the only exceptions are textures that will never be minified (e.g. GUI textures).GUI图片不需要设置成Mip Maps
Normal maps are used by normal map shaders to make low-polygon models look as if they contain more detail. Unity uses normal maps encoded as RGB images. You also have the option to generate a normal map from a grayscale height map image.
If you want to make a terrain, you normally use your main texture to show where there are areas of grass, rocks sand, etc... If your terrain has a decent size, it will end up very blurry. Detail textures hide this fact by fading in small details as your main texture gets up close.
When drawing detail textures, a neutral gray is invisible, white makes the main texture twice as bright and black makes the main texture completely black.
If you want to use texture for reflection maps (e.g. use the Reflective builtin shaders), you need to use Cubemap Textures.
Anisotropic filtering increases texture quality when viewed from a grazing angle, at some expense of rendering cost (the cost is entirely on the graphics card). Increasing anisotropy level is usually a good idea for ground and floor textures. In Quality Settings anisotropic filtering can be forced for all textures or disabled completely.