shader打包到AB包後,沒有包含到UnityShaderVariant導致模型變黑的問題

ShaderVariant
    在shader最終編譯時,根據上層的宏定義,根據不同的組合編譯出多套底層shader.
    Unity的Shader中通過multi_compile和shader_feature來定義宏(keyword)。最終編譯的時候也是根據這些宏來編譯成多種組合形式的Shader源碼。其中每一種組合就是這個Uniy Shader的一個Variant
Material與ShaderVariant的關係
    一個Material同一時刻只能對應它所使用的Shader的一個variant。進行切換的要使用Material.EnableKeyword()和Material.DisableKeyword()來開關對應的宏,
    Unity會根據你設定的組合來匹配響應的shader variant進行渲染
    Shader.EnableKeyword,和Shader.DisableKeyword是對Shader進行全局宏設置
    built-in Shader的源碼中的StandardShaderGUI.cs可以看到unity是怎麼處理對於StandardShader的keyword設置的
multi_compile和shader_feature的區別
    如果你在shader中添加了
    #pragma multi_compile  _A _B
    #pragma multi_compile  _C _D
  那麼無論這些宏是否真的被用到,你的shader都會被Unity編譯成四個variant,分別包含了_A _C,_A _D, _B _C,_B _D四種keyword組合的代碼
    如果是
    #pragma shader_feature _A _B
    #pragma shader_feature _C _D
  那麼你的shader只會保留生成被用到的keyword組合的variant
判定feature是否被用到的機制
    1.如果shader沒有與使用它的材質打在一個AB中,那麼shader_feature的所有宏相關的代碼都不會被包含進AB包中(有一種例外,就是當shader_feature _A這種形式的時候是可以的),這個shader最終被程序從AB包中拿出來使用也會是錯誤的(粉紅色).
  2.把shader和使用它的材質放到一個AB包中,但是材質中沒有保存任何的keyword信息(你再編輯器中也是這種情況),shader_feature會默認的把第一個keyword也就是上面的_A和_C(即每個shader_feature的第一個)作爲你的選擇。而不會把_A _D,_B _C,_B _D這三種組合的代碼編譯到AB包中。
  3.把shader和使用它的材質放到一個AB包中,並且材質保存了keyword信息(_A _C)爲例,那麼這個AB包就只包含_A _C的shaderVariant.
解決方案是 ShaderVariantCollection
    ShaderVariantCollection(簡稱SVC),這個SVC文件可以指定某個shader要編譯都要編譯帶有哪些keyword的變種。並且在ProjectSetting->Graphics界面新加了一個Preloaded Shaders列表,
    可以把SVC文件放進去,編譯時指定的Shader就會按照SVC中的設置進行正確的variant生成,而不會像Always Include Shaders列表中的那樣全部變種都生成
另外2種方法,但會編譯所有變體,導致包體變大
1.把Shader放到在ProjectSetting->Graphics->Always Include Shaders列表裏,Unity就會編譯所有的組合變種。
2.把Shader放到Resources文件夾下,也會正確處理,也應該是全部keyword組合都編譯

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章