Unity Shader ToggleDrawer [Toggle] 設(shè)置屬性,真機(jī)失效

ToggleDrawer

把一個(gè)類型的屬性顯示為一個(gè)開(kāi)關(guān),它的值要么是0要么是1。

當(dāng)選中它時(shí),Unity還會(huì)設(shè)置一個(gè)名為大寫(xiě)屬性名_ON(可以自定義名字)的shader feature

#pragma shader_feature _SELECTED_ON

我們可以在shader里用過(guò)#if、#ifdef或者#if defined關(guān)鍵詞來(lái)判斷它當(dāng)前是否被開(kāi)啟。

shader文件:

Properties
{
    ...
    [Toggle]_selected("selected", Int) = 0
    ...
}
...
SubShader
{
    ...
    #pragma shader_feature _SELECTED_ON
    ...
    #ifdef _SELECTED_ON
        ...
    #else
        ...
    #endif
    ...
}
ToggleDrawer.png

設(shè)置屬性

1. 設(shè)置接口 EnableKeyword/DisableKeyword

At runtime, the appropriate shader variant is picked up from the Material keywords (Material.EnableKeyword and DisableKeyword) or global shader keywords (Shader.EnableKeyword and DisableKeyword).

2. keyword的兩種方式

Toggle displays a float as a toggle. The property value will be 0 or 1, depending on the toggle state.

When it is on, a shader keyword with the uppercase property name +"_ON" will be set, or an explicitly specified shader keyword.

  1. uppercase property name +"_ON"
// Will set "_INVERT_ON" shader keyword when set
[Toggle] _Invert ("Invert?", Float) = 0
  1. an explicitly specified shader keyword
// Will set "ENABLE_FANCY" shader keyword when set.
[Toggle(ENABLE_FANCY)] _Fancy ("Fancy?", Float) = 0

我們使用的而是第一種方式.

設(shè)置代碼如下:

self._fogMaterial = self.fogObj:GetComponent("Renderer").material

  1. 選中
    self._fogMaterial:EnableKeyword("_SELECTED_ON")

  2. 禁用
    self._fogMaterial:DisableKeyword("_SELECTED_ON")

遇到的問(wèn)題

問(wèn)題: 打包后,真機(jī)運(yùn)行時(shí)EnableKeyword失效了。
原因: Unity在Build時(shí)自動(dòng)把沒(méi)有被任何用到的材質(zhì)使用的variant裁切了(Shader build time stripping

While building the game, Unity can detect that some of the internal shader variants are not used by the game, and skip them from build data. Build-time stripping is done for:

生成游戲包時(shí),Unity可以檢測(cè)到某些內(nèi)在著色器變體沒(méi)有被使用,然后stripping(裁切、忽略)它們。生成時(shí)去除可用于:

  • Individual shader features, for shaders that use #pragma shader_feature. If none of the used materials use a particular variant, then it is not included into the build. See internal shader variants documentation. Out of built-in shaders, the Standard shader uses this.

  • 個(gè)別著色器特性,使用 #pragma shader_feature的著色器。如果一個(gè)變體沒(méi)有被任何用到的材質(zhì)使用,那么生成時(shí)就不把它打進(jìn)去。參考內(nèi)在著色器文檔 ,內(nèi)置著色器中的標(biāo)準(zhǔn)著色器使用這種方式。

方案很多:

  1. Shader加入到Edit->Project Settings->Graphics->Always Included Shaders這個(gè)列表里

加入AlwaysIncludedShaders的shader是開(kāi)始游戲的時(shí)候就全部編譯了嗎?

答案是不會(huì),加到always include 的shader,會(huì)將shader的所有變體打包到游戲,用到的時(shí)候才會(huì)加載用到的變體到內(nèi)存!

相關(guān)文檔:https://docs.unity3d.com/Manual/OptimizingShaderLoadTime.html

Under all default settings, Unity loads the object into memory, but does not create the until they are actually needed.
This means that shader variants that are included into the game build can still potentially be used, but there’s no memory or load time cost paid until they are needed. For example, shaders always include a variant to handle point lights with shadows, but if you never end up using a point light with shadows in your game, then there’s no point in loading this particular variant.

  1. 新建一個(gè)材質(zhì),將被裁切的variant選中,這樣被材質(zhì)使用到的variant不會(huì)stripping ( If none of the used materials use a particular variant, then it is not included into the build)

  2. 修改Shader -- multi_compile

#pragma shader_feature 改為 #pragma multi_compile

舊版:#pragma shader_feature _SELECTED_ON
新版:#pragma multi_compile __ _SELECTED_ON

Individual shader features, for shaders that use #pragma shader_feature. shader_feature才會(huì)Shader build time stripping

我采用方案3.

參考鏈接

Making multiple shader program variants : https://docs.unity3d.com/Manual/SL-MultipleProgramVariants.html

MaterialPropertyDrawer : https://docs.unity3d.com/ScriptReference/MaterialPropertyDrawer.html

Optimizing Shader Load Time

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 11,013評(píng)論 0 23
  • 一、生活事件 今天與女兒一起出門,我開(kāi)車。一路上她總是指指點(diǎn)點(diǎn),很不放心讓我開(kāi)車,我們兩個(gè)人都不開(kāi)心。我很...
    Cyylinxi閱讀 253評(píng)論 0 0
  • 昨晚晚自習(xí)還剩五分鐘的時(shí)候班長(zhǎng)提示孩子們寫(xiě)反思,我在稿紙上寫(xiě)下了“我是領(lǐng)航人,我怎樣,領(lǐng)航就怎樣”,寫(xiě)后內(nèi)心有種難...
    張珍珍zzz閱讀 587評(píng)論 3 11
  • 有一句經(jīng)典的廣告詞 “只有更好,沒(méi)有最好!” 是啊,遇見(jiàn)更好的自己,我們一直在路上。 每個(gè)人都有一個(gè)自我成就的夢(mèng),...
    齊齊樂(lè)閱讀 1,749評(píng)論 2 11
  • 前言 前幾個(gè)月一直忙碌公司iOS端App開(kāi)發(fā),所以沒(méi)時(shí)間管理自己博客,最近看到一篇文章,讓我鼓足勇氣開(kāi)通自己的Bl...
    scyworld閱讀 878評(píng)論 0 5

友情鏈接更多精彩內(nèi)容