Shader related optimization
As we all know, the HLSL/CG we use to write Shaders in Unity are all high-level languages. This is to write a set of Shaders compatible with multiple platforms. When Unity is packaged, it will be compiled into instructions that can be run on the corresponding platform. The body is generated according to the macro, and when the package is running, the GPU will switch the packaged code according to the macro you set, instead of writing a shader that is only generated, which is also to improve the running speed.
If you want to view the actual running code, you can use tools such as RenderDoc to capture the frame to view the actual running code.
You can view the number of variants currently generated on the Shader.
The most important thing to optimize Shader is to optimize the algorithm of Shader, organize the code structure, and reduce redundancy. Use the leanest and most efficient code to implement our functions.
Function performance optimization
We can check on Microsoft's website , sort according to the instruction slot, and check the order of performance consumption. It shows the occupancy in the fragment:
- Texture sampling minimizes the number of samples and consumes sorting: texCubelod > texCube > tex2Dlod > tex2D
- Reduce complex math function calls that cannot directly compile simple instructions: pow, exp, sign, cos, sin, tan
- Can be reused, try to reduce repeated calculations: normalize, dot
- saturate,abs,max,min recommended, high efficiency
Precautions
- Avoid using division, use rcp instead, a/b can be changed to a*rcp(b) to improve performance
- Avoid logic and loops like if and loop
- Calculation accuracy problem: use float for world space position and texture coordinates with high precision requirements, and use half for others (texture coordinates, vectors, colors (HDR), etc.)
- Reducing the number of registers
is generally reduced in Varyings, Attributes are obtained from Mesh, and can be removed if they are not used in Shader. - Can be calculated at the vertex, try to calculate in the vertex shader, some linear data, such as Fog SH
- Use AlphaTest carefully, it will lead to the failure of Early-z, it is best to use scripts, set macros, and automatically modify the queue to 2450 when it is turned on
- Color Mask problem, the mobile terminal may occupy resources on some platforms.
rendering optimization
No matter how much the function is optimized, it will not save much. It is better to save more than rendering a few times. Therefore, we have to start by reducing the amount of rendering.
- Reduce Overdraw Try to avoid AlphaTest and AlphaBlend objects, especially AlphaTest to 2450, do not mix with opaque objects. Reduce special effects for the entire screen.
- Reduce post-processing, each full-screen post-processing increases the amount of calculation too much, it is best to reduce the resolution calculation during calculation, for example, a down-sampling method is used in bloom calculation.
- Anti-aliasing, try not to open it on the mobile terminal, performance recommendation: MSAA < TAA < FXAA&SMAA
inline inline function
In Unity's built-in CGInclude file, we can find that many functions have the inline keyword, and the functions modified by inline are inline functions, which can solve the problem that some frequently called small functions consume a lot of stack space (stack memory), but inline The use of inline is limited. Inline is only suitable for functions with simple code in the body of the function and will be used frequently. It cannot contain complex structural control statements such as while and switch, and the inline function itself cannot be a direct recursive function (that is, It also calls its own function internally).
Optimization of art resources
Art resources mainly include: textures, meshes, and shader variants, the most important of which are textures.
texture
Texture size affects resource loading time, gpu rendering time, memory usage, package size, and image quality.
Some students always think that it is wrong to compress the size in unity to the extreme. It is just the image storage format imported into unity, which does not mean the occupation after packaging. Unity will convert the format into other formats when packaging. format to store.
The above figure shows the occupancy of the packaged pictures, and the front part shows what kind of compression is used for the current picture.
Therefore, don't care about the size and size of the image when it is imported, but set it on the image, such as setting its maximum size to 1024.
Compression format
First, popularize the bpp, such as 4 bpp, which means that each pixel occupies 4 bits and should be 4 bits per pixel.
- Lossy compression
PVRTC: RGBA 4 bpp size requires positive direction
ETC2: RGBA 8 bpp size requires a multiple of 4
ASTC 4x4: RGBA 8 bpp size requires a multiple of 4 (and 6x6 8x8 requires corresponding multiples), It supports HDR
and the default is RGBA 32bit, occupying at least four times larger than others - PC common format
DXT: RGB 4 bpp size requirement is a power of 2 Opaque texture commonly used
BC7: RGBA 8bpp size requirement is a power of 2 supports transparent channel
BC6H: RGBA (HDR) 8 bpp supports HDR
Unity official texture compression document
3. Turning on minmap can effectively reduce bandwidth, but it will increase memory by 33%.
4. Anisotropic filtering is recommended not to be turned on or only processed separately.
It is turned on by default. Generally, Per Texture is set, and then it needs to be on the picture open.
After it is turned on, the sampling will be increased, which will reduce the aliasing when the texture mipmap transitions.
5. If the size of the ui image does not meet the standard, lossless compression will be used, which will cause waste.
Mesh
- Note that the write is enabled, and the memory usage will double in the enabled state
- The skeleton model should pay attention to the number of faces, which affects performance, because its animation needs to calculate the vertex position every frame
Resource-related inspection tools
-
Texture and Mesh inspection tool, you can check the relevant occupation with one click, and
you can check out the corresponding large files with one click.
Mesh counts the total occupancy of the number of uses, and you can clearly view the total occupancy of the current Mesh in the scene. Red is an unmerged mesh. -
Texture-related detection
Can detect whether the size of the texture is standardized.
Can detect whether the size of the texture is too large.
It will export pictures that are not multiples of 4 to the corresponding folder, and then art students can modify the picture and replace the resources. -
Shader-related checks
You can view the number of all shader variants
You can print out the number of all shader variants in the project.
The way to reduce variants is to reduce the use of macros. If there is no other way, use less multi_compile and use shader_feature
variants. Click here to see the official website -
Resource reference search
You can view the mutual references between resources, Uses can view the used resources, Used By can view the referenced resources, and Unused Assets can view unused resources. You can select
objects to view related references, or search upwards -
Prebe resource analysis
Find the resource reference analysis and occupancy of a Prefab.
skin animation
Skin animation also takes up a lot of performance when the game is running. Generally, there are some ways to solve it. Here I recommend the one used in the previous project, using GPU Skinning + LOD. The nearby model uses the default skin animation to ensure the effect. For the character model at the location, use low poly + vertex animation to bake the animation texture, convert the reverse and distance according to the color pixel, and regenerate the vertex position drawing. This method also supports batching and even GPU Instancing to improve performance.
resource loading
Resource loading sometimes freezes. Check the official documentation , which generally requires the assistance of program classmates to complete.
Shader loading
By default, the shader loads geometry the first time it renders, which is one of the reasons we reduced the variants. If the same variant and shader are used, the shader will not be reloaded when rendering new geometry.
Sometimes it will run stuck, we can use the preloaded form for Shader loading.
UI optimization
Optimize the unity UI , this is a backup first, and then look at it when needed.