中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Unity3D Mesh中material和sharedMaterial的區別及內部實現的推斷是怎樣的

發布時間:2021-11-15 16:44:34 來源:億速云 閱讀:609 作者:柒染 欄目:大數據

本篇文章為大家展示了Unity3D Mesh中material和sharedMaterial的區別及內部實現的推斷是怎樣的,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

material 和 sharedMaterial 的區別

創建一個Material, 顏色為紅色,
創建兩個Quad,掛上剛剛創建的材質。 效果如下圖:

Unity3D Mesh中material和sharedMaterial的區別及內部實現的推斷是怎樣的

將第一個Quad掛載如下腳本, 運行:

render = GetComponent<Renderer>();render.material.color = Color.white;

效果如下圖:

Unity3D Mesh中material和sharedMaterial的區別及內部實現的推斷是怎樣的

修改腳本內容如下, 運行:

render = GetComponent<Renderer>();render.sharedMaterial.color = Color.white;

Quad的顏色變了
效果如下圖:

Unity3D Mesh中material和sharedMaterial的區別及內部實現的推斷是怎樣的

如何來解釋上面的現象呢, 根據官方文檔

Renderer.sharedMaterial

sharedMaterial 是共用的 Material,稱為共享材質。修改共享材質會改變所用使用該材質的物體,并且編輯器中的材質設置也會改變。

Renderer.material

material 是獨立的 Material,返回分配給渲染器的第一個材質。修改材質僅會改變該物體的材質。如果該材質被其他的渲染器使用,將克隆該材質并用于當前的渲染器。


推測 sharedMaterial 和 material 的實現

下面我們通過一些實現猜測 material 是如何實現的:

我們從 UnityEngine.Renderer 中可得知 sharedMaterial 和 material 是屬性(property),當給屬性賦值時會隱式的調用 set 方法,當獲取屬性值得時候會隱式的調用 get 方法。假設 sharedMaterial 的值變量假設為 _sharedMaterial, material 的值變量假設為 _material。

Material _material;  Material _sharedMaterial;
Material origin_sharedMat = render.sharedMaterial;Debug.Log(origin_sharedMat == render.sharedMaterial);
// True

調用了 sharedMaterial 的 get方法。 可以推斷出 sharedMaterial 的 get:

return _sharedMaterial;
  • 1

  • 第二個測試:

Material new_Mat = new Material(Shader.Find("Standard"));
render.sharedMaterial = new_Mat;Debug.Log(new_Mat == render.sharedMaterial);
// True

調用了 sharedMaterial 的 set方法。 可以推斷出 sharedMaterial 的 set:

_sharedMaterial = value;
  • 第三個測試:

Material origin_sharedMat = render.sharedMaterial;Material origin_Mat = render.material;Debug.Log(origin_sharedMat == render.sharedMaterial);Debug.Log(origin_Mat == render.sharedMaterial); 
Debug.Log(origin_Mat == render.material);
// Flase True True

在隱式調用 material 的 get 后, sharedMaterial 被修改。且 _material 和 _sharedMaterial 相等。
推斷 material 的 get:

if (_sharedMaterial ~= _material) {
    _material = new Material (_sharedMaterial);//這一步由第四個測試共同推出
    _sharedMaterial = _material;

}return _material;
  • 第四個測試:

Material new_Mat = new Material(Shader.Find("Standard"));
render.sharedMaterial = new_Mat;Debug.Log(new_Mat == render.sharedMaterial);Material origin_Mat = render.material;Debug.Log(new_Mat == origin_Mat);Debug.Log(origin_Mat == render.sharedMaterial);Debug.Log(origin_Mat == render.material);
// True Flase True True

很明顯 _material的初始化并未通過 material 屬性,因為未調用 material 屬性的 get 方法前,_sharedMaterial 和 _material并不相等。
推斷 sharedMaterial 的 set:

_sharedMaterial = value;
  • 第五個測試:

Material new_Mat = new Material(Shader.Find("Standard"));render.material = new_Mat;Debug.Log(new_Mat.name);Debug.Log(render.sharedMaterial.name);Debug.Log(render.material.name);// Standard Standard Standard(Instance)

推測 material 的 set:

_sharedMaterial = value;

綜上推斷:

public Material material {  
    get {  
        if (_sharedMaterial ~= _material) {
            _material = new Material (_sharedMaterial);  
            _sharedMaterial = _material;

        }        return _material;  
    }  
    set {          
        _sharedMaterial = value;  
    }  
}public Material sharedMaterial {  
    get {  
        return _sharedMaterial;  
    }  
    set {  
        _sharedMaterial = value;  
    }  
}

使用 material 時的內存泄漏問題

每一次引用 Renderer.material 的時候,都會生成一個新的 material 到內存中去,銷毀物體的時候需要我們手動去銷毀該material,否則會一直存在內存中。

官方文檔說:

This function automatically instantiates the materials and makes them unique to this renderer. It is your responsibility to destroy the materials when the game object is being destroyed. Resources.UnloadUnusedAssets also destroys the materials but it is usually only called when loading a new level.

此方法自動實例化該材質并且使其成為該渲染器獨有的材質。當該游戲物體被刪除時,你應該手動刪除該材質。當替換場景調用 Resources.UnloadUnusedAssets 也可以刪除該材質。


編輯器下使用 material, 其他平臺使用 sharedMaterial

public static Material GetMaterial(Renderer render)  
    {  #if UNITY_EDITOR  
        return render.material;  #else  
        return render.sharedMaterial;  #endif  
    }

如果是主角這一類gameobject身上需要修改材質的屬性或者shader屬性比較多的時候,可以第一次使用material,這樣可以動態的生成一個material實例,然后再使用sharedmaterial,動態的修改這個新生成的material,而且不會創建新的material。

https://blog.uwa4d.com/archives/optimzation_memory_2.html

一般情況下,資源屬性的改變情況都是固定的,并非隨機出現。比如,假設GameObject受到攻擊時,其Material屬性改變隨攻擊類型的不同而有三種不同的參數設置。那么,對于這種需求,我們建議你直接制作三種不同的Material,在Runtime情況下通過代碼直接替換對應GameObject的Material,而非改變其Material的屬性。這樣,你會發現,成百上千的instance Material在內存中消失了,取而代之的,則是這三個不同的Material資源。

上述內容就是Unity3D Mesh中material和sharedMaterial的區別及內部實現的推斷是怎樣的,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

沽源县| 富蕴县| 沙湾县| 化隆| 开原市| 信阳市| 高密市| 怀远县| 临城县| 乌苏市| 龙口市| 乌鲁木齐县| 涪陵区| 湖口县| 谷城县| 望都县| 吉林市| 赣州市| 浙江省| 上高县| 玉环县| 依兰县| 清徐县| 翁牛特旗| 烟台市| 垦利县| 垫江县| 偃师市| 潜山县| 夏河县| 孝昌县| 伊宁县| 桃源县| 西青区| 贺州市| 诸暨市| 邛崃市| 河北省| 长寿区| 延边| 晋江市|