1. 程式人生 > >Unity Shader入門精要筆記(七):Unity Shader內建檔案、變數和語義

Unity Shader入門精要筆記(七):Unity Shader內建檔案、變數和語義

本系列文章由Aimar_Johnny編寫,歡迎轉載,轉載請標明出處,謝謝。

http://blog.csdn.net/lzhq1982/article/details/74279052

1、Unity提供的內建檔案和變數

上一篇我們學了一個簡單的頂點/片元著色器。複雜的著色器可能需要我們處理法線,光照,陰影等。為了方便開發者的編碼,Unity提供了很多內建檔案,包含了提前定義的函式、變數和巨集等。下面我們逐一講解。

內建包含檔案:類似於C++的include。在Unity中,包含檔案的字尾是.cginc。這樣我們就可以使用該包含檔案為我們提供的變數和函式。寫法如下:

CGPROGRAM

//...

#include "UnityCG.cginc"

//...

EndCG

這些檔案我們可以在官網下載(下載地址),在對應版本的下載的下拉框裡選內建著色器,下下來的樣子,這裡我用書上的截圖:


a、CGIncludes資料夾中包含的是內建的包含檔案。我們以後需要常去查閱一些內建函式的寫法,就在這裡找對應的包含檔案。

b、DefaultResources資料夾中包含了一些內建元件或功能所需要的Unity Shader。

c、DefaultResourcesExtra中包含了所有Unity內建的Shader,這也是我們常常光顧的地方,可以去學習並利用這些內建Shader。

d、Editor只包含了一個檔案,用於定義Unity5引入的Standard Shader所用的材質面板。

對於包含檔案我們也可以從Unity應用程式中找到CGIncludes資料夾。Mac位置:/Applications/Unity/Unity.app/Contents/CGIncludes;Windows位置:Unity安裝路徑/Data/CGIncludes。

下表給出了CGIncludes中主要的包含檔案以及他們的主要用處:


可以看出,像UnityShaderVariables.cginc和HLSLSupport.cginc,即使我們沒用#include包含進來,它們也會自動包含進來,例如UnityShaderVariables.cginc裡的UNITY_MATRIX_MVP,我們可以直接用。

UnityCG.cginc是最常接觸的包含檔案。我們常用的結構體和函式基本都在裡面。例如,我們可以直接使用其中預定義的結構體作為頂點著色器的輸入和輸出,如下:


此外,UnityCG.cginc也提供了一些常用的幫助函式。比如下面這些:


讀者感興趣可以自行閱讀他們的實現,這些我們在光照那裡會常用到,到時候可以回頭來查閱。

2、Unity提供的CG/HLSL語義

在前一篇的簡單的著色器中,我們看到了SV_POSITION,POSITION,COLOR0等。這些是CG/HLSL提供的語義。語義實際上就是一個賦給Shader輸入輸出的字串,這個字串表達了這個引數的含義。通俗的講,這些語義可以讓Shader知道從哪裡讀取資料,並把資料輸出到哪裡,這在Shader中是不可缺少的。

Unity為了方便對模型資料的傳輸,對一些語義進行了特別的規定。尤其是頂點著色器的輸入結構體,像POSITION,NORMAL,TANGENT,TEXCOORD0,Unity會自動識別這些語義,對應的把模型座標,法線,切線,第一組紋理座標賦給它們。但對於頂點著色器的輸出,也就是片元著色器的輸入結構體來說,我們可以自行決定一些語義傳遞的資料,比如我們在會常用TEXCOORD系列傳遞一些座標,顏色啥的資料,在這裡它就不是紋理座標了。

DirectX10以後,有了一種新的語義型別,就是系統數值語義(system-value semantics)。這類語義以SV開頭,SV代表系統數值。比如用SV_POSITION修飾頂點著色器的輸出變數pos,則pos就是齊次裁剪空間中的座標。這些語義描述的變數是不可以隨便賦值的,流水線需要使用它們完成特定的目的。比如SV_POSITION修飾的變數經過光柵化後會顯示在螢幕上。

下表總結了應用階段傳遞模型資料給頂點著色器是Unity常用的語義:


TEXCOORDn中n的數目和Shader Model有關,Shader Model 2(Unity預設的Shader Model版本)和3中,n等於8,Shader Model 4和5中,n等於16。通常一個模型的紋理座標組數不超過2,用TEXCOORD0和TEXCOORD1就夠了。在內建的結構體appdata_full中,最多使用6個紋理座標。


上圖是頂點著色器給片元著色器傳遞資料時用的語義,除了SV_POSITION有特別含義,其他語義沒有明確要求。也就是說我們可以存任何值到這些語義描述的變數中。通常我們習慣用TEXCOORDn來傳遞我們自定義的數值。


上圖是Unity中片元著色器的輸出語義。

3、Shader整潔之道

1)float、half還是fixed

在CG/HLSL中,有3種精度型別:float,half和fixed。這些精度將決定計算結果的數值範圍。如下表:


上面的精度並不是絕對正確的,尤其是在不同平臺和GPU上,實際精度可能與上面的範圍不一致。

a、大多數桌面GPU會按最高的浮點精度計算,也就是說float、half、fixed在這些平臺上是等價的。所以在PC上很難看出它們的不同。

b、重點是在移動平臺上,它們的精度範圍很重要,會導致運算速度有差異。如果做移動端產品,我們要確保在真正的移動裝置上驗證我們的Shader。

c、fixed精度實際上只在一些較舊的移動平臺上有用,在大多數現代GPU上,它們內部會把fixed和half當初同等精度對待。

儘管有上面的不同,但一個基本建議是,儘可能使用精度較低的型別,因為這可以優化Shader的效能,在移動平臺尤其重要。我們可以用fixed型別儲存顏色和單位向量,用half儲存較大精度範圍的資料,最差情況下用float。

2)避免不必要的計算

如果毫無節制的在Shader(尤其是片元著色器)中進行了大量計算,那麼我們可能很快就會收到Unity的錯誤提示:

temporary register limit of 8 exceeded

Arithmetic instruction limit of 64 exceeded; 65 arithmetic instructions needed to compile program

出現這些錯誤大多是因為我們在Shader中進行了過多的運算,使得需要的臨時暫存器數目或指令數目超過了當前可支援的數目。不同的Shader Target、不同的著色器階段,我們可用的臨時暫存器和指令數目不同。我們可以通過指定更高等級的Shader Target來消除這些錯誤。如下表:


注意,所有類似OpenGL的平臺(包括移動平臺)被當成是支援到Shader Model 3.0的。而WP8/WinRT平臺則只支援到Shader Model 2.0。

前面說的Shader Model是由微軟提出的一套規範,它們決定了Shader中各個特性的能力。而這些特性和能力體現在Shader能使用的運算指令數目、暫存器個數等各個方面。Shader Model等級越高,Shader的能力就越強。雖然這樣,但一個更好的方法是儘可能減少Shader中的運算,或通過預計算的方式提供更多資料。

3)慎用分支和迴圈

在各種程式語言中,類似分支、迴圈這樣的流程控制語言是最基礎的語法之一,但在Shader中,要對它們格外小心。

它們在GPU的實現和CPU有很大不同,在最壞的情況下,我們花在一個分支語句的時間相當於運算了所有分支語句的時間。所以我們不鼓勵使用流程控制語句,它們會降低GPU的並行處理操作。一個解決方案是我們儘量把計算向流水線上端移動,例如把片元著色器的運算放在頂點著色器,或在CPU預計算,把結果傳給Shader。如果非要用它們,建議是:

a、分支判斷語句中使用的條件變數最好是常數,不會發生變化。

b、每個分支中包含的操作指令儘可能少。

c、分支的巢狀層數儘可能少。

相關推薦

Unity Shader入門筆記Unity Shader檔案變數語義

本系列文章由Aimar_Johnny編寫,歡迎轉載,轉載請標明出處,謝謝。 http://blog.csdn.net/lzhq1982/article/details/74279052 1、Unity提供的內建檔案和變數 上一篇我們學了一個簡單的頂點/片元著色器。複雜的著

Unity Shader入門筆記其他數學相關介紹

本系列文章由Aimar_Johnny編寫,歡迎轉載,轉載請標明出處,謝謝。 http://blog.csdn.net/lzhq1982/article/details/73747162 前兩篇介紹了Unity Shader的主要數學部分,書上還有些相關的數學介紹,將在這

Unity Shader入門筆記十二紋理屬性

本系列文章由Aimar_Johnny編寫,歡迎轉載,轉載請標明出處,謝謝。 http://blog.csdn.net/lzhq1982/article/details/75045358 紋理從廣義上講不是一個普通的圖片,我們今後會遇到各種功能性紋理,比如法線紋理,立方體紋

Unity Shader入門筆記十八透明度混合

本系列文章由Aimar_Johnny編寫,歡迎轉載,轉載請標明出處,謝謝。 前面章節介紹過,透明度混合是實現了真正的半透效果。它會以當前片元透明度作為混合因子,與已經儲存在顏色緩衝區中的顏色進行混合,得到新的顏色。同時要關掉深度寫入,小心物體的渲染順序。 為了進行

Unity Shader入門筆記十九雙面渲染的透明效果

本系列文章由Aimar_Johnny編寫,歡迎轉載,轉載請標明出處,謝謝。 前面文章介紹了透明度測試和透明度混合,基本滿足了透明的效果需求,但嚴格來說,現實中透明除了能看到後面物體的樣子,也應該能看到透明物體內部的樣子,但前面的方法我們都看不到其內部結構,這是因為預

WPF and Silverlight 學習筆記WPF佈局管理之StackPanelWrapPanelDockPanel

一、StackPanel StackPanel是以堆疊的方式顯示其中的控制元件 1、可以使用Orientation屬性更改堆疊的順序 Orientation="Vertical"       預設,由上到下顯示各控制元件。控制元件在未定義的前提下,寬度為StackPa

C#入門經典 學習筆記類繼承

類繼承   通過繼承,可以定義一個新類,新類納入一個已經宣告的類並擴充套件。   1.已存在的類稱為基類;新類成為派生類,派生類包括了自己類宣告的成員和基類的成員。   2.每個派生類只能繼承一個基類,

程式設計師的機器學習入門筆記推薦系統入門介紹

介紹 背景 隨著網際網路行業的井噴式發展,獲取資訊的方式越來越多,人們從主動獲取資訊逐漸變成了被動接受資訊,資訊量也在以幾何倍數式爆發增長。舉一個例子,PC時代用google reader,常常有上千條未讀部落格更新;如今的微信公眾號,也有大量的紅點未閱

EF學習筆記讀取關聯數據

取數據 microsoft image zha 手動 模型 取數 foreach ret 總目錄:ASP.NET MVC5 及 EF6 學習筆記 - (目錄整理) 本篇參考原文鏈接:Reading Related Data 本章主要講述加載顯示關聯數據; 數據加載分為以下三

Python筆記字典屬性對象實例繼承

http 基礎 ima 字符 刪除重復 com 根據 模塊 none (一) 簡單說明 字典是Python的內置數據結構,將數據與鍵關聯(例如:姓名:張三,姓名是鍵,張三就是數據)。例如:下面這個就是一個字典 {‘姓名‘: ‘張三‘, ‘出生日期‘: ‘2899-0

Python+Selenium筆記WebDriverWebElement

關閉 tab keys selenium test self. reg selector tor (一) WebDriver WebDriver提供許多用來與瀏覽器交互的功能和設置,通過WebDriver的功能和一些方法,來實現與瀏覽器窗口、警告、框架和彈出窗口的交互

hadoop學習筆記Java HDFS API

on() apr name pin package 目錄 except 讀取 play 一、使用HDFS FileSystem詳解 HDFS依賴的第三方包:   hadoop 1.x版本:   commons-configuration-1.6.jar   comm

算法筆記復雜度分析

n+1 增長 角度 復雜 判斷 and 就是 ret 執行時間 (一)漸進符號(這裏暫時只考慮大O) 以輸入規模n為自變量建立的時間復雜度實際上還是較復雜的,例如an2+bn+c+1,不僅與輸入規模有關,還與系統a、b和c有關。此時對該函數進一步抽象,僅考慮運行時間的

javaweb學習筆記CSS

目錄 1.CSS 1.1 CSS的引入方式 1.2 CSS選擇器 1.3 CSS的盒子模型 1.4 CSS的屬性 1.CSS CSS(Cascade Style Sheet,層疊樣式表) html負責的是一個頁面的結構,css主要負責了頁面的資料樣式

學習筆記樸素貝葉斯在Web安全中的六個應用

一、檢測Web異常操作        1.資料蒐集:一樣        2.特徵化             使用詞集模型,統計全部操作命令,去重後形

機器學習筆記K-Means

1 - 前言 之前我們學習的演算法均為監督學習演算法,而K-means是我們所學習的第一個無監督學習演算法。所以首先讓我們瞭解一下監督學習和無監督學習的區別 1.1 - 監督學習(supervised learning) 從給定的訓練資料集中學習出一個函式(模型引數),當新的資料

【笨木頭Unity入門之旅010完結Demo之四處找死_UI

UI是遊戲裡必不可少的元素,在Unity裡新增UI是比較輕鬆的事情,但要玩好它,可就不那麼輕鬆了。 沒關係,先入門。   笨木頭花心貢獻,啥?花心?不,是用心。 轉載請註明,原文地址:http://www.benmutou.com/archives/2196

Java學習筆記JDBC

JDBC簡介 JDBC(Java Database Connected) 四種Java資料庫操作形式: 1.JDBC-ODBC橋接技術(不用); 2.JDBC直接連線; 3.JDBC網路連線; 4.模擬指定資料庫的通訊協議自己編寫資料庫操作。

機器學習筆記概率圖模型

機器學習最重要的任務,是根據一些已觀察到的證據(例如訓練樣本)來對感興趣的未知變數(例如類別標記)進行估計和推測。概率模型提供了一種描述框架,將學習任務歸結為計算變數的概率分佈。概率圖模型(probabilistic graphical model,簡稱PGM)是一類用圖來表達變數相關關係的概率模型

數字影象處理筆記頻域低通濾波平滑影象

1 - 傅立葉變換 在前面我們對空間濾波做了重點的研究,現在我們來介紹一下涉及頻率域中的各種濾波技術。影象從空間域轉換到頻率域使用的是二維傅立葉變換,一個畫素為M*N的影象f(x,y)進行傅立葉變換得到F(u,v),那麼一般的公式為: