Unity Shader開發-著色器變體(2)-定義著色器變體

一.定義著色器變體

定義一個著色器變體(Shader Variant)從概念和實現上講,主要包括以下幾個核心部分

1.使用預編譯指令來聲明變體關鍵字

關鍵字是驅動變體生成的“開關”。它們是簡單的字符串標識符,用于在 Shader 代碼中標記不同的功能路徑。

以multi_compile類型為例在ShaderLab中聲明自定義變體關鍵字:

#pragma?multi_compile _ _CustomKeyWord

這里用到了關鍵字的組合寫法(下劃線+自定義關鍵字名),默認會使用第一個變體(這里的?_代表的是 默認狀態或無關鍵字激活的狀態

(*)使用下劃線組合寫法的好處

清晰性:它明確指出了當該組功能都未開啟時的 Shader 行為。這使得 Shader 代碼更易讀、更易于理解。

智能裁剪:對于 shader_feature,Unity 在構建游戲時會執行 Shader Stripping(著色器裁剪)。如果你的項目中,沒有任何一個材質勾選了“開啟功能 A”,那么與 MY_FEATURE_ON 對應的變體就不會被編譯和打包。但由于有 _ 的存在,默認的、不帶該功能的變體始終會被包含(只要這個 Shader 被使用了)。

優化包體:這意味著你不需要為每個可選功能都強制打包“開啟”和“關閉”兩個版本。如果“開啟”版本根本沒用,它就不會被打包,從而節省了存儲空間。

注意:Unity有變體數量的限制

(*)使用multicompile時可以不明確使用 _

隱含的默認狀態:當 multi_compile 列表中沒有 _ 且沒有其他關鍵字被激活時,Unity 仍然會生成一個變體,這個變體是 沒有任何該 multi_compile 行中關鍵字定義的。這其實就等同于“默認”或“無宏定義”的狀態。但如果使用了 _ ,那么監視器面板里默認顯示為未激活狀態。

總結:使用下劃線可以節省變體數量

(*)multi_compile與shader_feature的區別

1.概述

#pragma multi_compile指令會強制編譯所有可能的關鍵字組合對應的 Shader 變體,無論這些變體是否在你的項目中被實際使用。

#pragma shader_feature指令會按需編譯 Shader 變體,它只會編譯和包含那些在你的項目中被 材質實際使用 的關鍵字組合對應的變體。

2.區別

功能獨立:它們各自執行的任務是獨立的。shader_feature 的核心是裁剪(stripping),而 multi_compile 的核心是強制編譯所有變體。一個不能替代另一個的功能。

目的不同

shader_feature 主要服務于優化構建包體大小和編譯時間,針對的是那些通過材質屬性控制的“可選”功能。

multi_compile 主要服務于保證運行時功能的完整性,針對的是那些引擎內部控制的“必需”功能。

2.靜態分支代碼塊

在 Shader 源代碼內部,需要使用 條件編譯宏(#ifdef / #ifndef / #else 來包裹那些受關鍵字控制的代碼邏輯。這些宏在編譯時根據關鍵字的激活狀態,決定哪些代碼會被包含在最終的變體中,哪些會被剔除.

一般在頂點或片元著色器中常使用如下格式分別書寫變體分支的邏輯:

   #ifdef _CustomKeyword_ONxxxxxxxxxxx;#elsexxxxxxxxxxx;#endif

3.關鍵字與材質屬性的關聯(可選,但常用)

為了方便美術師和設計師在 Unity 編輯器中控制這些變體,通常需要將 Shader 關鍵字與材質的 Properties 塊中的屬性 關聯起來。這通過使用像 [Toggle][KeywordEnum] 這樣的屬性修飾符來實現。

變體開關的實現
1.ShaderLab屬性塊

可以發現在Property中命名相同的屬性會指向ShaderLab中的同一變體關鍵字。

注意命名的匹配規則

SubShader中的關鍵字命名:(全大寫)自定義關鍵字名"+"?_ON"

  #pragma shader_feature _CustomKeyword_ON

Proprty中聲明的屬性名命名:(大小寫可混搭,但要與SubSahder中關鍵字的字符組成保持一致)自定義關鍵字名

  [Toggle]_CustomKeyword_ON ("Toggle MyOn", Float) = 1

另外,如果你使用不同形式(如[Toggle]和[MaterialToggle])定義了屬性名完全相同的變量開關,在監視器面板中,它們將同時切換狀態。

2.C#代碼

1.單個材質實例

(1)啟用關鍵字:Material.EnableKeyword(string keyword)

作用: 激活此 Material 實例上 Shader 的特定關鍵字

(2)禁用關鍵字:Material.DisableKeyword(string keyword)

作用: 禁用此 Material 實例上 Shader 的特定關鍵字。

(3)檢查關鍵字狀態:Material.IsKeywordEnabled(string keyword)

作用: 檢查此 Material 實例上 Shader 的某個關鍵字是否處于激活狀態。

2.全局材質

(1)啟用關鍵字:Shader.EnableKeyword(string keyword)

作用: 激活一個全局著色器關鍵字。一旦激活,所有使用該關鍵字的 Shader 都會切換到對應的變體(如果該變體存在)。

(2)禁用關鍵字:Shader.DisableKeyword(string keyword)

作用: 禁用一個全局著色器關鍵字。

(3)檢查關鍵字狀態:Shader.IsKeywordEnabled(string keyword)

作用: 檢查一個全局著色器關鍵字當前是否處于激活狀態。

(4)重置所有全局關鍵字:Shader.DisableAllKeywords()

作用: 禁用所有當前激活的全局著色器關鍵字。這是一個比較少用的操作,因為它會影響所有 Shader 的行為。

二.著色器變體的限制

Unity中的著色器變體也存在著一些限制。

1.變體數量限制與關鍵字的關系

Unity 的變體數量限制主要體現在 關鍵字數量的限制 上,而不是直接的“變體”數量限制。這是因為每一個變體都是由一套激活的關鍵字組合來定義的。

(1)全局關鍵字限制:

Unity 對項目中所有著色器使用的全局關鍵字總數有一個限制。這個限制是 256 個。Unity 引擎自身也會使用大約 60 多個內部關鍵字(如用于光照、陰影、霧效等),這會進一步減少你可以使用的自定義關鍵字數量。無論是 multi_compile 還是 shader_feature 定義的關鍵字,只要它們是全局的(即沒有使用 _local 后綴),都會計入這 256 個全局關鍵字的限制。

(2)局部關鍵字限制(Local Keywords):

從 Unity 2019.1 版本開始,引入了 局部關鍵字 的概念,通過 #pragma shader_feature_local#pragma multi_compile_local 來聲明。每個獨立的 Shader 文件可以有最多 64 個獨特的局部關鍵字

局部關鍵字不計入全局關鍵字的 256 個限制。這是解決全局關鍵字限制的一種重要方式,尤其適用于那些只在該特定 Shader 內部使用的功能。注意:局部關鍵字不能與 Shader.EnableKeywordCommandBuffer.EnableShaderKeyword 等全局關鍵字 API 一起使用。

2.變體爆炸 (Shader Variant Explosion)

雖然有關鍵字數量的限制,但更直接的問題是 “變體爆炸”。即使你沒有達到關鍵字數量的硬性限制,但如果你使用了過多的 multi_compile 指令,或者在shader_feature中定義了太多未優化的組合,仍然會導致天文數字的變體數量:

變體數量是關鍵字組合的乘積。 例如,如果你有 10 個multi_compile?指令,每個指令定義了兩個關鍵字,那么總的變體數量可能是 210=1024 個。如果其中一些是三個或更多關鍵字的組合,這個數字會呈指數級增長。

本篇完

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/87895.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/87895.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/87895.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

sql server耗時模擬

REATE PROCEDURE SimulateDelay AS BEGINPRINT 開始耗時操作...;-- 模擬等待 5 秒WAITFOR DELAY 00:00:05;PRINT 耗時操作完成。; END 方法二:使用忙循環(不推薦,CPU 占用高) CREATE PROCEDURE SimulateBusyLoop AS BEGINDECLARE start DATETIME GETDAT…

Zookeeper的典型應用場景?

大家好,我是鋒哥。今天分享關于【Zookeeper的典型應用場景?】面試題。希望對大家有幫助; Zookeeper的典型應用場景? 超硬核AI學習資料,現在永久免費了! Zookeeper 是一個分布式協調服務,廣泛應用于需要高可用性、分…

STM32F103_LL庫+寄存器學習筆記12.3 - 串口DMA高效收發實戰3:支持多實例化的版本

導言 《STM32F103_LL庫寄存器學習筆記12.2 - 串口DMA高效收發實戰2:進一步提高串口接收的效率》基于上一個版本,進一步提升代碼的模塊化水平,支持多實例化。 如上所示,收發大量的數據,沒有丟包。 項目地址&#xff1a…

跨平臺的重構版Notepad++文本編輯器

跨平臺 Notepad 替代方案 Notepad 是 Windows 平臺上的流行文本編輯器,但其原生版本不支持跨平臺。以下是功能相似且支持多平臺的替代工具: Notepadqq(Linux/macOS/Windows) Notepadqq 是 Notepad 的開源跨平臺版本&#xff0c…

意法STM32F103C8T6 單片機ARM Cortex-M3 國民MCU 電機控制到物聯網專用

STM32F103C8T6 單片機全面解析 1. 產品定位 STM32F103C8T6 是意法半導體(ST)推出的 經典ARM Cortex-M3內核單片機,采用 LQFP48封裝,以 高性能、豐富外設和超高性價比 成為嵌入式開發領域的"國民MCU"。 2. 核心功能特…

Sui 技術如何助力 Claynosaurz 成功推出 Popkins NFT

像 Claynosaurz 這樣的品牌利用 Sui 推動鏈上創新的邊界,展示了 Web3 如何結合互動娛樂并帶來獨特全新的體驗。Claynosaurz 最近在 Sui 上推出的 Popkins NFT 系列及其大型抽獎活動,不僅在社區參與度上取得了成功,也有力地展示了 Sui 獨特的技…

OpenCV CUDA模塊設備層-----反正弦運算函數asin()

操作系統:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 編程語言:C11 算法描述 對一個 uchar 類型的像素值(范圍 [0, 255]),先歸一化到浮點范圍 [0.0, 1.0],然后計算其反正弦值 …

PixiJS 中 HTMLText 富文本渲染問題探究與優化思考?

起因 在使用 PixiJS 進行富文本渲染開發過程中,遭遇 HTMLText 組件處理中文字體加載時出現顯著卡頓現象。針對此問題,在開源社區提交 issue 并附上相關技術細節與運行表現,期望獲得解決方案。 提issues 從 issue 反饋內容來看,項目…

五、Redis的IO模型

簡介 在談及Redis為什么快的時候,很多人都只能回答redis是基于內存,所以快。但他們往往不知道,決定redis快的因素,還有它的IO模型-Reactor模型。談及Redis的IO模型之前,先補充一下IO模型的基礎知識。 IO模型演化 1.堵塞…

Cesium、ThreeWebGL詳解(二)渲染引擎向GPU傳數據、性能優化、引擎對比

下面從 API 定位、坐標體系、性能表現、面試常問點幾個維度詳細對比 Cesium、Three.js 與原生 WebGL 的繪制差異。 🧭 1. API 定位與典型應用 Cesium 聚焦全地球 GIS 場景,支持地形、影像、時空動態等地理信息功能,是專業級地圖應用首選。 T…

單點登錄(SSO)系統

設計一個 Java 單點登錄(SSO)系統需要解決跨系統認證和會話共享問題。以下是核心設計和實現方案,包含關鍵組件和代碼示例: 一、核心概念 認證中心 (Auth Center):中央身份驗證服務令牌 (Token):用戶身份憑…

《信息技術》科技核心期刊推薦

【科研必看】《信息技術》——科技核心期刊,助力你發表高影響力論文! 如果你是一位科研工作者、學者或者在校學生,正在為發表論文而努力,那么《信息技術》期刊無疑是你不可錯過的選擇!這本期刊以其卓越的學術影響力&am…

界面組件DevExpress WPF中文教程:Grid - 如何遍歷節點?

DevExpress WPF擁有120個控件和庫,將幫助您交付滿足甚至超出企業需求的高性能業務應用程序。通過DevExpress WPF能創建有著強大互動功能的XAML基礎應用程序,這些應用程序專注于當代客戶的需求和構建未來新一代支持觸摸的解決方案。 無論是Office辦公軟件…

2D寫實交互數字人:讓AI形象擁有“真人溫度“的技術革命

在人工智能技術日新月異的今天,數字人已不再是科幻電影中的概念,而是逐步滲透到我們日常生活的各個領域。然而,市場上大多數數字人產品仍停留在"能說會動"的初級階段,缺乏真正的情感交互能力,這種"機械…

2025 年拓客系統排行榜

在數字化營銷時代,拓客系統成為企業獲取客戶資源、提升銷售效率的關鍵工具。以下為您盤點 2025 年表現出色的中文名字拓客系統,其中 微拓客 憑借強大功能脫穎而出,成為眾多從業者的首選。 一、微拓客:精準拓客的全能王者 微拓客堪…

TikTok 矩陣如何快速漲粉

在社交媒體的廣袤天地里,TikTok 以其強大的影響力和龐大的用戶基礎,成為眾多創作者和品牌競相角逐的舞臺。構建 TikTok 矩陣,是擴大影響力、實現快速漲粉的有效策略。那么,究竟如何讓 TikTok 矩陣快速漲粉呢?下面將為您…

基于微信小程序和云開發的企業綠色融資平臺的設計與實現

文章目錄 摘要前言緒論1. 課題背景2. 國內外現狀與趨勢2.1 國內研究現狀2.2 國外研究現狀2.3 發展趨勢3. 課題內容相關技術與方法介紹1. 微信小程序開發技術2. 騰訊云開發平臺3. 綠色項目評估模型4. 智能匹配算法5. 碳核算方法系統分析1. 需求分析1.1 用戶需求1.2 功能需求1.3 …

如何自建服務器并開啟公網IP:本地內網網址讓外網訪問詳細教學

本地內網環境自建服務器后,如何讓外網訪問,提供互聯網連接服務呢?有不少方法都可以實現,常見的有如公網IP、DDNS動態域名、nat123內網穿透等,下面詳細教學。 一、申請開公網IP-----------------公網IP篇-------------…

企業公用電腦登錄安全管控的終極方案:ASP操作系統安全登錄管控方案

一、引言:公用電腦——企業安全管理的“灰色地帶” 在企業辦公場景中,公用電腦(如會議室電腦、生產線終端、客服工位)因多用戶共用、權限復雜,往往成為安全管理的薄弱環節。員工隨意登錄、弱密碼泛濫、敏感數據泄露事…

HarmonyOS-ArkTS開發指南:從基礎到實戰

目錄 一、基礎語法 二、聲明式 UI 開發 基本組件結構 三、狀態管理 四、生命周期鉤子 五、組件化開發 1. 創建自定義組件 2. 組件嵌套 六、事件處理 七、布局系統 八、樣式設置 九、條件渲染與列表渲染 十、異步操作 十一、路由導航 開發建議 一、基礎語法 ArkT…