Unity Shader開發-著色器變體(1)-著色器變體概述

? ? ? 有時我們希望一份 Shader 源代碼可能滿足多種功能(如處理法線貼圖、自發光、不同光照模式、陰影,支持GPUInstacing等多種功能)。所以我們需要能夠實現Shader分支的方法。

一.Shader分支實現

主要有三種手段實現Shader分支:

1.靜態分支

(1)定義:

在 Shader 代碼中,使用#define定義激活分支。

使用 #if/#ifdef/#elif/#else/#endif 這樣的預處理器指令實現的條件判斷。這些判斷在 Shader 編譯階段 就已經完成,而不是在運行時。(編譯時選擇代碼分支)

#define LIGHT_ONhalf4 frag(v2f i):SV_Target
{#if defined(LIGHT_ON)return xxx;#elsereturn xxx;#endif
}

(2)優點

零運行時開銷:由于分支在編譯時就確定了,運行時 GPU 不需要做任何判斷,從而避免了動態分支的所有性能缺點。

更小的指令數量:最終的 Shader 代碼只包含必需的指令,更加精簡。

(3)缺點

不夠靈活:(運行時無法動態切換)一旦 Shader 編譯完成,其行為就固定了。不能在運行時通過改變一個浮點數或整數來切換靜態分支。

需要 Shader 變體來配合:如果想在運行時切換靜態分支的不同版本,就需要為每個不同的靜態分支組合生成一個獨立的 Shader 變體。

2.動態分支

定義:在 Shader 代碼中,使用 if/elsefor 循環(條件在運行時決定)或 switch 語句來實現的條件判斷。GPU 在 運行時 根據輸入數據的值來決定執行哪個代碼路徑。(運行時選擇代碼分支)

優點

靈活性高:可以在 Shader 內部根據每個像素或頂點的數據實時調整行為。

代碼簡潔:無需為每種組合編寫單獨的 Shader。不會造成代碼膨脹(與著色器變體相比,著色器變體會為每一種分支生成一份Shader文件,相當于空間換時間)

缺點

性能開銷:可能引入額外的計算、內存訪問、分支預測失敗的懲罰,或者占用更多的寄存器資源。這會導致 GPU 無法充分發揮其并行處理的優勢。

流水線停頓:復雜的分支邏輯可能導致 GPU 渲染流水線停頓,降低吞吐量。

3.著色器變體

著色器變體是實現運行時靜態分支的一種核心手段(我稱它為一種加強版靜態分支)。 它不是一種獨立的分支類型,而是 靜態分支在 Unity 中最主要的表現形式和管理機制。通過 Unity 的 #pragma shader_feature#pragma multi_compile 指令,可以讓編譯器根據不同的 Shader 關鍵字組合 來生成多個獨立的 Shader 程序(即變體)

優點:(結合了動態分支和靜態分支的優點)

結合了靜態分支的性能優勢:運行時沒有動態分支的開銷。

提供了運行時的靈活性:雖然每個變體內部是靜態的,但可以在運行時動態切換選擇不同的變體,從而實現功能的動態切換(例如,在材質面板勾選“啟用法線貼圖”)。

優化包體大小和編譯時間(特別是 shader_feature:通過只編譯和包含實際使用的變體。

缺點

變體爆炸:如果關鍵字數量過多且使用不當(尤其是 multi_compile),會生成海量變體,導致編譯時間超長和包體巨大。

管理復雜性:需要仔細規劃關鍵字和變體。

下面我們了解一下Unity中著色器變體(ShaderVariant)的概念和意義。

二.著色器變體(ShaderVariant)概述

? ? ? ?在 Unity 中,Shader 變體(Shader Variants) 是一個重要的概念,它允許你用一份 Shader 源代碼來支持多種不同的視覺效果或功能,同時還能優化性能和最終的游戲包體大小。你可以把它理解為同一個 Shader 的不同“編譯版本”,每個版本都針對特定的功能組合進行了定制。

1.ShaderVariant是什么?

? ? ? ?有時我們希望一份 Shader 源代碼可能滿足多種功能(如處理法線貼圖、自發光、不同光照模式、陰影,支持GPUInstacing等多種功能)。Unity 允許你在一個 Shader 文件中通過使用 預編譯指令(#pragma)和 Shader 關鍵字(Keywords) 來定義這些可選功能。

? ? ? 然而并不是所有的物體都需要所有這些功能。

? ? ? 當 Unity 編譯 Shader 時,它會根據這些指令和項目中的實際使用情況,為所有可能的 關鍵字組合 生成一份份獨立的、經過編譯的 Shader 程序。這些獨立的程序就是 Shader 變體。本質是一種靜態分支的思想。

2.為什么需要ShaderVariant?

Shader 變體的存在是為了解決幾個關鍵問題:

1. 性能優化(靜態分支)

這是 Shader 變體最核心的優勢。在 Shader 編程中,有兩種方式實現條件邏輯:

(1)動態分支:在 Shader 代碼中使用if/else語句。GPU 在運行時需要判斷條件,這可能會導致性能下降,因為它可能需要執行兩條分支的所有代碼,或者引起管道停頓。

(2)靜態分支:Shader 變體就是靜態分支的體現。在編譯時,Unity 已經根據關鍵字的狀態,為每個功能組合生成了獨立的 Shader 程序。運行時,GPU 直接加載并執行與當前渲染狀態(例如,材質上是否開啟了法線貼圖)匹配的那個特定變體,無需進行額外的條件判斷。這通常比動態分支更高效。

2. 代碼復用與維護

? ? ? ?通過在一個 Shader 文件中包含所有可選功能,你可以避免為類似的功能編寫大量重復的 Shader 文件。這使得 Shader 代碼更易于管理、修改和維護。

3. 靈活性與可配置性

? ? ? ?Shader 變體允許你在 Unity 編輯器中通過材質屬性或 C# 腳本輕松地開啟或關閉 Shader 的特定功能,從而實現豐富的視覺效果定制,而無需修改 Shader 代碼。

3.Unity中變體類型

Shader Variant的類型主要有2種:multi_compileshader_feature。后篇中會介紹二者使用和管理上的區別。簡單來說:

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

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

本篇完

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

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

相關文章

ECK 簡化:在 GCP GKE Autopilot 上部署 Elasticsearch

作者:來自 Elastic Eduard Martin 學習如何使用 GKE Autopilot 和 ECK 在 GCP 上部署 Elasticsearch 集群。 想要獲得 Elastic 認證?了解下一次 Elasticsearch Engineer 培訓的時間! Elasticsearch 擁有豐富的新功能,可以幫助你為…

測試一個軟件的性能有哪些指標?

在測試軟件性能時,通常會關注多個維度的指標,以評估系統在不同負載下的表現。以下是關鍵的性能測試指標分類和詳細說明: ?? 核心性能指標分類 1. 響應時間(Response Time) 定義:從發送請求到接收到響應所花費的時間 細分: 平均響應時間:所有請求的平均耗時 *P90/P95…

淺析std::atomic<T>::compare_exchange_weak和std::atomic<T>::compare_exchange_strong

目錄 std::atomic ::compare_exchange_weak 和 std::atomic ::compare_exchange_strong 核心原理 函數簽名 核心區別 典型用法 1. compare_exchange_weak(循環內重試) 2. compare_exchange_strong(單次嘗試) 底層機制 總…

舉出一個異步接口測試的例子

以下是一個完整的 ?異步接口測試? 實際案例,包含問題場景、解決方案、代碼實現和面試回答技巧,適合在面試中展示技術深度: ?案例背景? ?業務場景?: 測試一個AI圖片生成平臺的異步接口,用戶提交生成請求后&#…

更新麒麟連不上外網

問題:更新麒麟連不上外網 處理:本地建個下載地址 建立文件夾/root/x86.rpm,子文件夾:Packages、repodata,和在線站點建的一樣:Index of /NS/V10/V10SP1.1/os/adv/lic/base/x86_64/,然后就下載…

TensorFlow深度學習實戰——使用Hugging Face構建Transformer模型

TensorFlow深度學習實戰——使用Hugging Face構建Transformer模型 0. 前言1. 安裝 Hugging Face2. 文本生成3. 自動模型選擇和自動分詞4. 命名實體識別5. 摘要生成6. 模型微調相關鏈接 0. 前言 除了需要實現特定的自定義結構,或者想要了解 Transformer 工作原理外&…

SAP-ABAP:SAP全模塊的架構化解析,涵蓋核心功能、行業方案及技術平臺

一、核心業務模塊(Logistics & Operations) 模塊代號核心功能典型流程關鍵事務碼物料管理MM采購/庫存/發票校驗采購到付款 (P2P)ME21N(采購訂單), MI31(庫存盤點)銷售與分銷SD訂單/定價/發貨/開票訂單…

實時預警!機場機坪井室無線智能液位監測系統助力安全降本

某沿海機場因地處多雨區域,每年雨季均面臨排水系統超負荷運行壓力。經勘測發現,5個井室因長期遭受地下水滲透侵蝕,井壁出現細微結構性裂縫,導致內部水位異常升高。作為機坪地下管網系統的核心節點,這些井室承擔著雨水導…

邊云協同 AI 視頻分析系統設計方案

目錄 一、項目背景與目標 二、系統架構概述 總體架構圖 三、ER 圖(核心數據庫設計) 實體關系圖簡述 數據表設計(簡要) 四、模型結構圖(邊緣云端AI推理架構) 邊緣模型(YOLOv5-tiny/PP-YO…

vue3整合element-plus

為項目命名 選擇vue 框架 選擇TS 啟動測試: npm run dev 開始整合 element-plus npm install element-plus --save npm install unplugin-vue-components unplugin vitejs/plugin-vue --save-dev 修改main.ts import { createApp } from vue import ./style.cs…

【AI 測試】測試用例設計:人工智能語言大模型性能測試用例設計

目錄 一、性能測試可視化架構圖 (1)測試整體架構圖 (2)測試體系架構圖 (3)測試流程時序圖 二、性能測試架構總覽 (1)性能測試功能點 (2)測試環境要…

Windsurf SWE-1模型評析:軟件工程的AI革命

引言 軟件開發領域正經歷著前所未有的變革,AI輔助編程工具層出不窮,但大多數僅專注于代碼生成這一環節。Windsurf公司近期推出的SWE-1系列模型打破了這一局限,首次將AI應用擴展至軟件工程的全流程。這一舉措不僅反映了行業對AI工具認知的深化…

Qt for OpenHarmony 編譯鴻蒙調用的動態庫

簡介 Qt for Harmony? 是跨平臺開發框架 ?Qt? 與華為 ?OpenHarmony? 操作系統的深度集成方案,由 Qt Group 與華為聯合推動。其核心目標是為開發者提供一套高效工具鏈,實現 ??“一次開發,多端部署”?,加速 OpenHarmony 生…

退休時,按最低基數補繳醫療保險15年大概需要多少錢

在南京退休時,如果醫保繳費年限不足(男需滿25年/女需滿20年),需補繳差額年限。若按最低基數一次性補繳15年醫保,費用估算如下(以2024年政策為例): 一、補繳金額計算公式 總補繳費用…

wireshark過濾顯示rtmp協議

wireshark中抓包顯示的數據報文中,明明可以看到有 rtmp 協議的報文,但是過濾的時候卻顯示一條都沒有 查看選項中的配置,已經沒有 RTMP 這個協議了,已經被 RTMPT 替換了,過濾框中輸入 rtmpt 過濾即可

《哈希表》K倍區間(解題報告)

文章目錄 零、題目描述一、算法概述二、算法思路三、代碼實現四、算法解釋五、復雜度分析 零、題目描述 題目鏈接:K倍區間 一、算法概述 計算子數組和能被k整除的子數組數量的算法。通過前綴和與哈希表的結合,高效地統計滿足條件的子數組。??需要注…

OpenShift 在 Kubernetes 多出的功能中,哪些開源?

OpenShift 在 Kubernetes 基礎上增加的功能中,部分組件是開源的(代碼可公開訪問),而另一些則是 Red Hat 專有(閉源)。以下是詳細分類: 1. 完全開源的功能(代碼可查) 這些…

【每天一個知識點】CITE-seq 技術

一、技術背景 單細胞RNA測序(scRNA-seq)自問世以來,極大推動了細胞異質性和組織復雜性的研究。但RNA水平并不能完全代表蛋白質水平,因為蛋白質的表達受轉錄后調控、翻譯效率及蛋白降解等多種因素影響。此外,許多細胞類…

中文Windows系統下程序輸出重定向亂碼問題解決方案

導言 最近我在用 Rust 開發時,遇到了一個讓人頭疼的問題:運行 cargo run -- version Cargo.toml > output.txt 將輸出重定向到文件后,打開 output.txt 卻發現里面全是亂碼!我的程序確實是UTF8但是輸出的文件卻是UTF16LE編碼的…

Python管理工具UV

常用 UV 命令 安裝 pip install uv 版本相關 uv python list 打印所有uv支持的python版本uv python install cpython-3.12 安裝指定的python版本uv run -p 3.12 test.py 用指定的python版本運行python代碼uv run -p 3.12 python 進入python執行環境。假如輸入的版本是一個本…