Unity3d: UGUI source code, Rebuild optimization

How is the image drawn

Objects rendered in Unity are composed of meshes, and the drawing units of meshes are primitives (points, lines, triangles). The drawing information is
stored in the Vertexhelper class, including normals in addition to vertices. , UV, Color, Tangent.

Rebuild concept

Canvas is responsible for the process of merging the grids of UI elements of child nodes, generating corresponding rendering instructions and sending them to Unity's graphics pipeline. So Canvas is the component that renders the UI. When the UI changes, a batch is executed, which is the culprit that affects performance more. Note that the Batch of Canvas only affects its child nodes, but not its child Canvas.

Rebuild program flow

  1. Image and Text both inherit Graphic, and Graphic has ICanvasElement interface, which implements the rebuild function
   public interface ICanvasElement
   {
    
    
       /// <summary>
       /// Rebuild the element for the given stage.
       /// </summary>
       /// <param name="executing">The current CanvasUpdate stage being rebuild.</param>
       ///  // 根据CanvasUpdate的不同阶段重建元素
       void Rebuild(CanvasUpdate executing);
  1. CanvasUpdateRegistry listens to the willRenderCanvases event of Canvas, which is called every frame before rendering
   public class CanvasUpdateRegistry
   {
    
    
         //布局重建队列,当UI元素的布局需要更新时将其加入队列
       private readonly IndexedSet<ICanvasElement> m_LayoutRebuildQueue = new IndexedSet<ICanvasElement>();

       //图形重建队列,当UI元素的图像需要更新时将其加入队列
       private readonly IndexedSet<ICanvasElement> m_GraphicRebuildQueue = new IndexedSet<ICanvasElement>();

       protected CanvasUpdateRegistry()
       {
    
    
           //监听了Canvas的willRenderCanvases事件,这个事件会在渲染前进行每帧调用
           Canvas.willRenderCanvases += PerformUpdate;
       }
  1. PerformUpdate collects the layout reconstruction queue, and the graphics reconstruction queue calls ICanvasElement.Rebuild to complete the reconstruction

when to join rebuild

It is realized by setting "dirty data", including layout (Layout), material (Material) and vertices (Vertices). If the layout is set to be dirty, the layout will be reconstructed. If the vertex or material is set to be dirty, the graphics will be reconstructed. Layout reconstruction will add itself to m_LayoutRebuildQueue, and graphics reconstruction will add itself to m_GraphicRebuildQueue, waiting to be called.
SetLayoutDirty: added to the layout reconstruction queue
SetVerticesDirty, SetMaterialDirty: material, vertex transformation added to the graphics reconstruction queue

Layout reconstruction: position or size;

Image reconstruction: vertex change, material change (size, rotation, text change, picture modification)

optimization

The main goal is to reduce the Canvas.SendWillRenderCanv parameter in the Profile. By limiting the number of vertices, vertex changes, etc.

  1. The text attribute changes ("123"->"1234"), triggering SetLayoutDirty: related to countdown, change every 1s, do not change in real time

  2. Change the text, picture color, trigger SetVerticesDirty (vertex change), so the best way to change the picture color is to change the shader color

  3. The layout component is causing rebuild issues

  4. Text stroke, shadow performance problem
    One character generates 4 vertices,
    if Shadow is added, it is equivalent to copying Text again to generate 8 vertices, and
    Outline will copy Text 4 times to generate 20 vertices.
    Replace with the corresponding shader

  5. text gradient

  6. Image format selection
    Image: The number of vertices depends on the selection of Image Type.
    ①Simple 4 vertices;
    ②Sliced: Check FillCenter and the number of vertices is 36, unchecked is 32;
    ③Tiled depends on the size of the Rectranform setting and the size of the original image, and N images are rolled out to be 4*N;
    ④Filled choose to compare Many, but at least 4.
    Therefore, the Simple mode is preferred for Image, followed by the Sliced ​​mode and the FillCenter is not checked.

  7. Dynamic and static separation: Canvas.SendWillRenderCanvases() and Canvas.BuildBatch() are calculated with Canvas as the root node, and different Canvas will not affect another Canvas. However, a lot of static and dynamic separation will affect the batching of Canvas, so we can separate the battle UI and the main interface in a targeted manner

View the factors affecting reconstruction in the source code

Trigger SetLayoutDirty

Graphic:

  1. protected override void OnRectTransformDimensionsChange(): Callback when the UI's RectTransform changes, as long as you inherit UIBehavior to get the callback

Image:

  1. protected override void OnCanvasHierarchyChanged(): The state of the parent canvas has changed

Text:

  1. Text attribute change: related to countdown, change every 1s, do not change in real time
  2. public bool supportRichText: When setting whether to enable rich text, switch rules (as long as the state is different from last time, SetLayoutDirty, instead of real-time Dirty after opening)
  3. public bool resizeTextForBestFit: When setting whether to allow the text to be automatically resized, switch rules
  4. public int resizeTextMinSize: the minimum text size allowed
  5. public int resizeTextMaxSize: set the maximum text size
  6. public TextAnchor alignment: The positioning of the text relative to its RectTransform.
  7. public int fontSize: text size
  8. public HorizontalWrapMode horizontalOverflow: horizontal overflow mode
  9. public VerticalWrapMode verticalOverflow: vertical overflow mode
  10. public float lineSpacing: Line spacing, specified as a factor of the font line height. A value of 1 will generate standard line spacing
  11. public FontStyle fontStyle: font style

Trigger SetVerticesDirty: vertex changes

Graphic:

  1. public virtual Color color: color, so it is best to change the color of the picture to change the color of the material ball
  2. protected override void OnRectTransformDimensionsChange(): Callback when the UI's RectTransform changes, as long as you inherit UIBehavior to get the callback

Image:

  1. public Type type:Simple,Sliced等
  2. public bool preserveAspect: whether to keep the aspect ratio, switch rules
  3. public bool fillCenter
  4. public FillMethod fillMethod: fill mode
  5. public float fillAmount
  6. public bool fillClockwise
  7. public int fillOrigin
  8. public bool useSpriteMesh: crop the transparent part of the image
  9. protected override void OnCanvasHierarchyChanged(): parent canvas changed

RawImage:

  1. public Texture texture
  2. public Rect uvRect

Shadow:

  1. public Color effectColor
  2. public Vector2 effectDistance
  3. public bool useGraphicAlpha

Text:

  1. public virtual string text
  2. public bool supportRichText
  3. public bool resizeTextForBestFit
  4. public int resizeTextMinSize
  5. public int resizeTextMaxSize
  6. public TextAnchor alignment
  7. public bool alignByGeometry: Perform horizontal alignment using the section's glyph geometry instead of glyph metrics.
    This can result in better fitting left and right alignment, but may result in incorrect positioning when trying to overlay multiple fonts (such as professional outline fonts)
  8. public int fontSize
  9. public HorizontalWrapMode horizontalOverflow
  10. public VerticalWrapMode verticalOverflow
  11. public float lineSpacing
  12. public FontStyle fontStyle

Trigger SetMaterialDirty: material changes

Graphic:

  1. public virtual Material material

Mask:

  1. public bool showMaskGraphic:
  2. protected override void OnEnable()
  3. protected override void OnDisable()
  4. protected override void OnValidate(): for editors

MaskableGraphic:

  1. public bool maskable
  2. protected override void OnTransformParentChanged()
  3. protected override void OnCanvasHierarchyChanged()
  4. public virtual void RecalculateMasking(): Recalculates the mask for this element and all child elements.

Trigger SetAllDirty, all changes

Image indirectly inherits from Graphic, when its Sprite changes, it will call the SetAllDirty function
SetAllDirty to change the timing

Graphic:

  1. protected override void OnTransformParentChanged() Parent object changed
  2. protected override void OnEnable()
  3. protected override void Reset(): assign the default value, only useful in the editor, can be ignored
  4. protected override void OnDidApplyAnimationProperties(): animation properties change
  5. protected override void OnValidate(): It will be called when the script is loaded or any value in the Inspector is modified. It is only useful in the editor and can be ignored

Image:

  1. static void RebuildImage(SpriteAtlas spriteAtlas) Atlas changes
  2. Sprite property changes
  3. overrideSprite Temporarily modify the picture
  4. public override void SetNativeSize() set the size

Text:

  1. public void FontTextureChanged(): The font texture is modified: TTF dynamic font, Unity will generate a texture every time the Text is assigned, and save the UV information of each word, then when displaying the font, take the final texture from the generated texture according to the UV information Rendered on the screen.
  2. font property change

Guess you like

Origin blog.csdn.net/luoyikun/article/details/123699116