Shader中的shader_feature與multi_compile
問題是這樣的,我照著Unity5 的Standard shader寫了一個給我們工程用的簡化版的標準Shader以及配合使用的ShadergGUI,裡面融合了很多功能,包括支援法線啊、uv動畫啊、半透鏤空等等,通過shader_feature定義的巨集將這些效果融合到一個shader裡,這樣既方便了美術,也方便了shader的管理,不用像原來一樣工程裡亂七八糟的一堆shader了。
不過後期在真機測試的時候遇到了一個問題,就是我通過EnableKeyword來動態修改材質表現在裝置上不好使了。當時第一想法就是Shader中那麼多條件巨集在build的時候被Unity自動strip掉了,因為我們大部分的資源都打包成了Assetbundle包,工程實際只有一個空場景,Shader資源都放在了Resources目錄下。如果說因為build的場景和資源裡不包含shader的一些variant而被Unity自動去掉了這也是可以理解的。於是我就想GraphicsSettings裡不是有個Always Included Shaders麼,按照字面意思理解把shader放到那裡去總是可以了吧,於是我就按下圖設定了下。嘿!還真就好了!
既然這樣好了,那看來真機除錯時其他的一些問題比如角色表現增強效果應該也是這個原因嘍,那索性把其他的shader也都加進來吧,省的後面再出問題。別說這招真是包治百病,單機介面裡我們還用了不少Standar shader,也就新增進來吧。ok,一切問題解決。。。。。。了嗎?
第二天測試就告訴我這個版本閃退頻繁,一查都是記憶體爆了。拿Instrument一看我靠,一登入就快300MB了,看下Allocation,編譯Shader居然就用了100多MB。難道說跟昨天把Standard Shader加進去導致的?雖然是很懷疑不過既然除錯已經定位到這裡還是試一下吧,於是乎把Standard shader從Always Included Shaders列表中移除再發布,嘿!還真就好了!
現在的情況就是
1.真機執行時Shader.EnableKeyword不好使,應該是因為Unity在Build時自動把沒有用到的variant刪減掉了(不是結論)
2.通過Always Included Shaders設定解決了問題,不過導致記憶體大量增加,應該是因為Unity在啟動時把該列表內的Shader的全部variant都展開編譯了出來,所以一方面解決了上面的問題,一方面卻增大了記憶體,而至於記憶體為什麼會增加如此之多,那隻能靠猜的了。
既然這樣,那就要想辦法解決Shader的記憶體佔用了,既然全部variant佔據的空間太大就部分載入唄,正好Unity5增加了個ShaderVariantCollection這麼個東西,看看好不好用。結果。。。。。多天的各種實驗全部以失敗告終,這包括:
1.建立ShaderVariantCollection資源,包含目標shader的全部variant,並新增到GraphicsSettings的Preload Shaders列表中
2.通過程式碼建立ShaderVariantCollection,並呼叫WarmUp介面
下面總結下我分析出來的Unity5.0 - 5.2的Shader編譯載入策略
1. 釋出工程時,Unity 會將全部multi_compile定義巨集組合成的variant編譯並加入包中
2. 釋出工程時,Unity 會將全部關聯材質引用到的variant編譯並加入包中
3. 釋出工程時,Unity會將Always Included Shaders列表中全部Shader的全部variant編譯並加入包中
4. Build Assetbundle時,Unity會將關聯的Shader的全部由multi_compile定義的variant以及使用到的variant編譯並加入包中
實測,使用multi_compile,是可以在執行時(真機上)用EnableKeyword和DisableKeyword動態改變材質,而shader_feature不行
文件中也寫到:
So shader_feature makes most sense for keywords that will be set on the materials, while multi_compile for keywords that will be set from code globally.
shader_feature適合在材質中設定,而multi_compile 適合用程式碼全域性設定
相關文章
- Shader 中的隨機與噪聲隨機
- Shader 中的顏色計算
- Shader 中的座標計算
- Shader 中的顏色混合模式(Blend Mode)模式
- Unity Shader 00 - 梳理 Unity Shader 的基本結構Unity
- Unity3D中的shader基礎知識Unity3D
- 【Shader】ComputeScreenPos 的使用
- 【Unity Shaders】Mobile Shader Adjustment—— 什麼是高效的ShaderUnity
- Unity Shader之磨砂玻璃與水霧玻璃效果Unity
- Compute Shader
- 【GLSL教程】(三)在OpenGL中向shader傳遞資訊
- GPU精粹與Shader程式設計(四):真實感渲染GPU程式設計
- 【Unity3D Shader程式設計】之二 雪山飛狐篇:Unity的基本Shader框架寫法&顏色、光照與材質Unity3D程式設計框架
- 一個簡單的Tessellation Shader
- godot shader 升級Go
- GPU精粹與Shader程式設計(二):次表面散射與環境光遮蔽GPU程式設計
- 寫 Shader 轉場的幾點思考
- Unity 的 Surface Shader有關記錄Unity
- 使用Shader進行UGUI的優化UGUI優化
- Android 中 Canvas 繪圖之 Shader 使用圖文詳解AndroidCanvas繪圖
- Android中Canvas繪圖之Shader使用圖文詳解AndroidCanvas繪圖
- Unity開發--(三)Shader程式設計:寫一個shader讓圖片的背面不被剔除Unity程式設計
- Compute Shader 簡介
- WebGL Shader 環境搭建Web
- OpenGL shader 程式基礎
- Cesium渲染模組之Shader
- Shader:常用結構體結構體
- Android著色器——ShaderAndroid
- 寫一個Geometry Shader
- Godot 字型邊框shaderGo
- GPU精粹與Shader程式設計(一):關於基礎物理渲染GPU程式設計
- Unity3D Shader官方教程翻譯(三)----Shader語法:屬性Unity3D
- Unity3D Shader官方教程翻譯(四)----Shader語法:SubShaderUnity3D
- [ARKit]4-著色器Shader的應用
- Tessellation Shader的GLSL入門實現: 平面
- 基於Pixel Shader的FFT已經完成FFT
- GPU精粹與Shader程式設計(三):實時輝光與透視陰影貼圖GPU程式設計
- unity 統一替換shaderUnity