Achieving 60FPS on mobile, Youtube

Optimizing Graphics in Unity, Unity

Overdraw

Overdrawn is to draw one pixel more than once. Post-processing will re-touch the pixel at least once. It adds burdens to the GPU and delays the frame.

Rendering is done by draw calls. The intermediate steps are not on the screen but in frame buffers. A frame buffer is a memory buffer that contains data representing the pixels in a complete video frame. It’s a portion of RAM. It’s like a canvas that the artist is going to paint on. (Render Queue decides the order of rendering.) Drawing into the buffer is expensive and costs memory bandwidth.

Methods to measure overdraw in Unity

  1. Overdraw Visualization Mode in the Scene’s draw mode menu. The most intense color indicates the areas having the highest overdraw. It’s not mostly correct because the built-in doesn’t count the z-writing. Laster version has a “TransparencyOverdraw” in Window → Render Pipeline → Render Pipeline Debug → Rendering → Fullscreen Debug Mode.
  2. RenderDoc Overdraw Analysis. It has a built-in Unity integration.

Reduce

Opaque overdraw

Opaque overdraw is cheaper than the transparent overdraw because it’s only substituting the pixels. Unity tries to render opaque objects front-to-back to discard the distant object’s pixels. This sorting is based on the distance between the camera and the object’s bounding-box center. Inefficienty gemoetry increase the costs, however. Skybox, or an inverted sphere, is almost at the camera position, so it will be drawn firstly, even though there are other objects in front of the camera. So skyboxes should be manually rendered after opaque geometry in Unity.

Splitting objects into smaller sub-objects helps efficiently sorting draw calls, because Unity can take more accurate origin points. Self-intersecting geometry is not great. A way to reduce the overdraw of this type of geometry is to split the intersection. Please note that this will trade more draw calls for less over draw.

Static, dynamic batching and GPU instancing merge multiple draw calls in one. It reduces the CPU load of the render thread, but merging draw calls won’t be sorted anymore.

Common solution is to disable batching for the troublesome objects. Another is to set the Unity render order manually by changing the render queue.

Transaprent Overdraw

Alpha blending requries additional reand arithmetic operations. Transparent materials do not write to the z-buffer, so more pixels won’t be discard. To reduce the transparent overdraw, we can do:

  1. decrase the amount of transparency layers
  2. reducing the screen size the transaprent geometry takes. It means to scale down the screen size of the transparent objects, to remove the 100% transparent texels from the sprites, to make a tight mesh that reduce the fully transparent regions.

Unity UI only supports full-quad rendering so it easily stacks UI elements on top of each other, since they are not tight meshes. On the other hand, sprite renderer supports drawing mesh that more accurately represents the opaque part. Tight mesh reduce the over draw levels.

Particle systems often stack particles on top of each other, so the GPU has to render the cluttered areas. Unity3D had posted the performance tips.

Post-processing effects might end up with an additional layer of 100% overdraw per effect, depending on the implementation.

Additive blending is cheaper than alpha blending on mobile.


Source:

  1. Framebuffer, Wikipedia
  2. Improving The GPU Performance of Your Games, The Gamedev Guru.
  3. Overdraw Cheatsheet, The Gamedev Guru.