Does Qualcomm chip GPU have HSR like functions

Posted by englishman69 on Sun, 02 Jan 2022 21:52:22 +0100

1) Does Qualcomm chip GPU have functions similar to HSR
2) will RT dynamic diagram on UGUI cause UI update
3) UI often iterates the appearance. How to change the code as little as possible
4) Should I use AssetBundle package mode or simulation mode in the development process?

This is the 279th UWA technical knowledge sharing push. Today, we continue to select a number of issues related to development and Optimization for you. It is recommended that you read them for 10 minutes. After reading them carefully, you will get results.

UWA Q & a community: answer.uwa4d.com
UWA QQ group 2: 793972859 (the original group is full)

GPU

Q: Does Qualcomm chip GPU have HSR like functions? Hope to answer, thank you.

A: Reference is as follows:
Test case 1: Xiaomi 9
Click the button to add a full screen opaque Quad. Using Standard Shader, the farther away from the camera, the smaller the RenderQueue.

Results: from the FPS, the frame rate is 60 frames up to layer 100. It shows that Xiaomi 9 does have a function similar to HSR, that is, opaque objects do not need to manually adjust the rendering queue, so that those close to the camera can render first.

Test case 2: Xiaomi 5X
Click the button to add a full screen opaque Quad. Using Standard Shader, the farther away from the camera, the smaller the RenderQueue.

Results: from the FPS, 43 frames fell in layer 1, 25 frames fell in layer 2, and 17 frames fell in layer 3. It indicates that there is no function similar to HSR on Xiaomi 5X.

Test case 3: Xiaomi 5X
Click the button to add a full screen opaque Quad. Use the Standard Shader. The farther away from the camera, do not adjust the RenderQueue.

Results: from the perspective of FPS, 43 frames are displayed on layer 1 and still 43 frames are displayed on layer 5. After the RenderQueue is not adjusted, the opacity of Unity is drawn from near to far. Due to the Early-Z relationship, the occluded objects will not be calculated by Fragment Shader, so the frame rate is relatively stable.

Summary: for objects with large area and high Shader complexity such as terrain, it is still necessary to adjust the rendering queue to the later one, because for low-end models, there is no function such as HSR. Therefore, you can adjust the rendering queue of the terrain to the back, so that Early-Z is effective for large terrain, so as to reduce the rendering pixels of the terrain.

For high-end models, such as Xiaomi 9, because its GPU hardware supports HSR function, the rendering queue does not matter for opaque objects.

In general, it is recommended to adjust the rendering queue of large terrain, which is good for low-end models.

Thank Xiaomiao @ UWA Q & a community for providing answers

UGUI

Q: Will using RenderTexture on UGUI components cause UI updates?

A: A simple experiment was conducted on this problem: the experiment set up a camera to shoot two moving objects, and then the RenderTexture was assigned to 100 rawimages on the UGUI. When running on the real machine, the UI update time is almost 0.

Theoretically, the vertex properties of these rawimages have not changed, and will not lead to UI updates.

thank Faust@UWA The Q & a community provided answers

UGUI

Q: Question: the previous project used Lua for UI development. One ToLua, one XLua. Planning or art often need to adjust the appearance of the completed UI, and generally need to change the layout or node level. At first, GameObject was used to access a node in the code Find finds the node. Once the hierarchical relationship changes, the program needs to be changed. It's very troublesome. How to adjust the UI without changing the code?

Idea: think of a naming standard scheme: after the program gets the Prefab of the UI and binds the script associated with Lua of the UI, rename all the nodes that the program needs to access as rd_xxxxx, child node rd under script control_ The beginning cannot be repeated. If there are child nodes in the list, hang an auxiliary script (such as UItemHelper) on it.

Lua traverses all nodes and caches all nodes when loading for the first time_ XXX's nodes are related to the script (Lua). In this way, the Lua code can directly use self.rd_xxx xx to obtain the object, and it is not afraid of Prefab level adjustment, nor does it need to call GameObject.Find many times.

It is stipulated that when other personnel adjust UI Prefab, it cannot be changed rd_xxxxx, if it needs to be modified, it needs the program cooperation.

Reference code: a reference modification of ToLua project:

Luaxxx associated with Lua script object CS (for example, LuaMono.cs) initialization, add:

......
        if (m_params.Count == 0)
        {
            //Automatic collection of lua Association objects
            SetRDObjectRef(luaClass, this.gameObject, true);
        }
        else
        {
            //Compatibility during node sorting (reuse UI also goes here to avoid repeated collection)
            foreach (ParamItem pi in m_params)
            {
                luaClass[pi.name] = pi.value;
            }
        }
......
 
    /// <summary>
    ///Check all nodes under the node. If the name is "rd_" The beginning is the program needs
    /// </summary>
    /// <param name="luaClass"></param>
    /// <param name="go"></param>
    void SetRDObjectRef(LuaTable luaClass,GameObject go,bool is_root = false)
    {
        if(go)
        {
            if(MyExtensions.StringStartsWith(go.name,"rd_"))
            {
#if UNITY_EDITOR
                //Check for duplicates
                if(luaClass[go.name] != null && !luaClass[go.name].Equals(null))
                {
                    GameFramework.Log.Error("{0} LuaClass already have GO key:{1} {2}", LuaScript, go.name, luaClass[go.name]);
                }
#endif
                luaClass[go.name] = go;
                ParamItem item = new ParamItem();
                item.name = go.name;
                item.value = go;
                m_params.Add(item);
            }
 
            if(is_root || (go.GetComponent<LuaMono>() == null && go.GetComponent<UItemHelper>() == null))
            {
                //Traverse all child nodes
                for(int i=0;i<go.transform.childCount;++i)
                {
                    SetRDObjectRef(luaClass, go.transform.GetChild(i).gameObject);
                }
            }
        }
    }

UItemHelper.cs

using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine.UI;
 
public class UItemHelper : MonoBehaviour
{
#if UNITY_EDITOR
    public class ParamItem
    {
        public string name;
        public UnityEngine.Object value;
    }
#endif
 
    Dictionary<string, GameObject> m_nodes = new Dictionary<string, GameObject>();
    bool init = false;
#if UNITY_EDITOR
    [SerializeField]
    protected List<ParamItem> m_params = new List<ParamItem>();
#endif
    void Awake()
    {
        Init();
    }
 
    public void Init()
    {
        if(!init)
        {
            m_nodes.Clear();
            SetRDObjectRef(this.gameObject, true);
            init = true;
        }
    }
 
    /// <summary>
    ///Check all nodes under the node. If the name is "rd_" The beginning is the program needs
    /// </summary>
    /// <param name="luaClass"></param>
    /// <param name="go"></param>
    void SetRDObjectRef(GameObject go, bool is_root = false)
    {
        if (go)
        {
            if (MyExtensions.StringStartsWith(go.name, "rd_"))
            {
#if UNITY_EDITOR
                //Check for duplicates
                if (m_nodes.ContainsKey(go.name))
                {
                    GameFramework.Log.Error("sub item node {0} already have GO key:{1} {2}", this.name, go.name, m_nodes[go.name]);
                }
                else
#endif
                {
                    m_nodes.Add(go.name, go);
#if UNITY_EDITOR
                    ParamItem item = new ParamItem();
                    item.name = go.name;
                    item.value = go;
                    m_params.Add(item);
#endif
                }
            }
 
            if (is_root || (go.GetComponent<LuaMono>() == null && go.GetComponent<UItemHelper>() == null))
            {
                int childCount = go.transform.childCount;
                Transform t = go.transform;
                //Traverse all child nodes
                for (int i = 0; i < childCount; ++i)
                {
                    SetRDObjectRef(t.GetChild(i).gameObject);
                }
            }
        }
    }
 
    public GameObject GetNode(string name)
    {
        if(m_nodes.ContainsKey(name))
        {
            return m_nodes[name];
        }
        return null;
    }
 
    public Image GetNodeImage(string name)
    {
        if (m_nodes.ContainsKey(name))
        {
            GameObject go = m_nodes[name];
            if (go != null)
            {
                Image img = go.GetComponent<Image>();
                return img;
            }
        }
        return null;
    }
 
    public Text GetNodeText(string name)
    {
        if (m_nodes.ContainsKey(name))
        {
            GameObject go = m_nodes[name];
            if (go != null)
            {
                Text txt = go.GetComponent<Text>();
                return txt;
            }
        }
        return null;
    }
 
    public Button GetNodeButton(string name)
    {
        if (m_nodes.ContainsKey(name))
        {
            GameObject go = m_nodes[name];
            if (go != null)
            {
                Button btn = go.GetComponent<Button>();
                return btn;
            }
        }
        return null;
    }
 
    // Nodes added later
    public void AddNode(GameObject go)
    {
#if UNITY_EDITOR
        //Check for duplicates
        if (m_nodes.ContainsKey(go.name))
        {
            GameFramework.Log.Error("sub item node {0} already have GO key:{1} {2}", this.name, go.name, m_nodes[go.name]);
        }
        else
#endif
        {
            m_nodes.Add(go.name, go);
#if UNITY_EDITOR
            ParamItem item = new ParamItem();
            item.name = go.name;
            item.value = go;
            m_params.Add(item);
#endif
        }
    }
 
    // Delete later added nodes
    public void RemoveNode(GameObject go)
    {
#if UNITY_EDITOR
        if (m_nodes.ContainsKey(go.name))
#endif
        {
            m_nodes.Remove(go.name);
#if UNITY_EDITOR
            ParamItem item = new ParamItem();
            item.name = go.name;
            item.value = go;
            m_params.Remove(item);
#endif
        }
    }
 
    public Dictionary<string, GameObject> GetAllRdGameObject()
    {
        return m_nodes;
    }
}

Others: of course, each project is different and needs to be implemented separately. I don't know what solution is used when you encounter similar problems in the project?

For example, some schemes do not want to initialize at the beginning. You can set the meta table and rewrite it when creating the associated Lua_ Index, when self rd_ When XXX accesses in this way, the prefix of the index is rd_, Then determine the cache, and if not, find the corresponding node Association.

A1: the path based UI control search is still fragile. It is better to directly use Unity serialization reference. You can modify the structure and name at will without worrying about loss.

Here's a good plan: UIControlBinding

Thank Zhang Di @ UWA Q & a community for providing answers

A2: don't use GameObject Find method, the serialization editor is directly bound to Lua. Same as using native CS bindings.

Thanks 1 9 7 3-311135@UWA The Q & a community provided answers

A3: serialize the UI control directly to the C# script. Do not use Find and GetComponent at runtime. After the Prefab of the UI panel is instantiated, directly insert these objects into a Lua Table and pass them to Lua.

Thank Tang Chong @ UWA Q & a community for providing answers

Asset

Q: Using AssetBundle package can ensure the correctness of resources to a large extent, but it is a waste of time to package any modification of resources, especially art and planning students resist it; The use of simulation mode is probably only more efficient. Problems such as effect errors and circular references can only be found after packaging (of course, there are many other ways to find them in advance, but they are additional means).

In recent projects, it has been found that even if resources are preloaded, there will still be very serious jams (1s +) in the Play process. Such a long card frame leads to the direct wrong performance effect: for example, the process of 1s moving from the starting point to the ending point directly becomes a flash to the ending point, which becomes a Bug.

The reason for Caton is: assetdatabase The loaded Prefab will not load its dependent Texture into memory. The Texture will be loaded only when Prefab renders for the first time. We used 40MB + Texture for a very complex (not optimized) skill special effect and stuck the UploadTexture.

Taking such a special issue as an opportunity, I am ready to reconsider the scheme to be implemented. I hope you can give more suggestions, which can be a comparative choice between the two, or other better practices or realization.

A: Putting the Unity project in a high-speed SSD should ease a lot.

A scheme I saw before is to create a camera invisible to players during preloading, execute the Animator, ParticleSystem and audio components of skill effects, and call camera Render, forcing all kinds of resources to WarmUp well, so there is basically no IO operation after entering the game, which should greatly alleviate the problem of subject description.

Some special effects are managed by the timeline track, and then the timeline itself is an independent module. You can find special effects according to the skill configuration (skill configuration is associated with timeline, and timeline is associated with special effects), and then pre render the special effects. Timeline is just a logical process controller. Of course, if the timeline itself is stuck, it is better to pre execute it.

Thank Zhang Di @ UWA Q & a community for providing answers

20211213
More wonderful questions waiting for you to answer ~

  1. Unity incremental packaging assets with unchanged AssetBundle will also be repackaged
  2. Open Generate Lightmap UVs when the model has UV2
  3. How to implement incremental update of AAB package

The cover image comes from the Internet

That's all for today's sharing. Of course, life is boundless and knowledge is boundless. In the long development cycle, these problems you see may be just the tip of the iceberg. We have already prepared more technical topics on UWA Q & a website for you to explore and share. You who love progress are welcome to join us. Maybe your method can solve the urgent needs of others; And the "stone" of his mountain can also attack your "jade".

Official website: www.uwa4d.com
Official technology blog: blog.uwa4d.com
Official Q & a community: answer.uwa4d.com
UWA School: edu.uwa4d.com
Official technical QQ group: 793972859 (the original group is full)

Topics: UI gpu