在unity中,標准的shader語言是HLSL,一般的HLSL數據類型都是支持的。然而,Unity有一些額外的HLSL類型,對移動平台有更好的支持。
基礎數據類型
在shader中,主要的計算數據類型是 浮點數據(在普通的變成語言中,比如C#中等於float)。幾種浮點類型的變種是: float、half 和 fixed(和 它們的向量/矩陣一樣,變種為 half3,float4x4)。這些類型精度不同(而且,因此,性能或者功效使用):
高精度:float
最高精度的浮點數值;一般來說是32位值。
全浮點數值精度類型一般用來表達世界空間位置,貼圖坐標或者涉及復雜運算的函數標量,比如三角函數、冪運算。
中精度:half
中等精度浮點數值;一般為16位值。
半精度類型一般用來表示短向量、方向、物體空間坐標,高動態范圍顏色。
低精度:fixed
最低精度固定點數值。一般為11位值,范圍為-2.0~+2.0和 1/256精度。
固定精度用來表示普通顏色和對顏色簡單的操作。
整型數據類型
整型數據經常用來表示循環計數或者數組指數。為此,他們通常在不同平台上都能夠很好的工作。
根據平台不同,整型數據可能不被GPU所兼容。比如,D3D9和 OpenGL ES2.0 GPU只能夠操作浮點數據,而簡單整數表達式(涉及位或邏輯運算)則可能使用相當復雜的浮點數學指令來模擬。
D3D 11,OpenGL ES 3,Metal和其它現代平台則對整型數據類型擁有較好的支持,所以使用位移位和位掩蔽可以如預期一樣工作。
復合 向量/矩陣類型
HLSL有內置的由基礎數據類型衍生而來的向量和矩陣類型。比如,float3是一個擁有x、y、z分量的三維向量,half4則是中等精度的擁有x、y、z、w分量的4維向量。當然,向量也可以被用來表達 顏色的r、g、b、a分量。
矩陣類型和向量類型差不多。比如,一個float4x4就是 4x4 維度的矩陣。注意一些平台只支持正方形矩陣,特別是OpenGL ES 2.0.
貼圖/采樣器類型
典型的你在HLSL代碼中聲明貼圖變量和下面類似:
sampler2D _MainTex; samplerCUBE _Cubemap;
對於移動平台,這些將翻譯成“低精度采樣器”,比如,紋理被期望具有低精度的數據。如果你知道你的貼圖包含了HDR顏色,那么你需要用半精度采樣器:
sampler2D_half _MainTex; samplerCUBE_half _Cubemap;
如果你的貼圖包含全浮點精度數據(比如 深度貼圖),使用全精度采樣器:
sampler2D_float _MainTex; samplerCUBE_float _Cubemap;
精度、硬件支持和表現
在PC 的GPU上使用 float/half/fixed數據類型時,會出現一個問題,那就是全部都會變成高精度。也就是說,對於所有的 PC GPU,你在shader中使用啥子數據類型根本沒什么影響。他們在計算時,總是使用32位的全精度浮點數。
只有當針對移動gpu的時候,一半和固定的類型才會變得有意義,這些數據類型主要是從耗電量來考慮。記住你需要在移動平台上測試你的shader,來看看有沒有精度問題。
即便在移動GPU上,不同的GPU家族對精度支持也不同。下面是一些數據:
GPU Family | float | half | fixed |
---|---|---|---|
PowerVR Series 6/7 | 32 | 16 | |
PowerVR SGX 5xx | 32 | 16 | 11 |
Qualcomm Adreno 4xx/3xx | 32 | 16 | |
Qualcomm Adreno 2xx | 32 vertex 24 fragment | ||
ARM Mali T6xx/7xx | 32 | 16 | |
ARM Mali 400/450 | 32 vertex 16 fragment | ||
NVIDIA X1 | 32 | 16 | |
NVIDIA K1 | 32 | ||
NVIDIA Tegra 3/4 | 32 | 16 |
大部分現代移動GPU實際上只支持 32位(float)或者16位(half/fixed)類型。一些老的GPU則對頂點shader和片段shader計算指令有不同的精度。
使用較低的精度通常會更快,這可能是由於GPU寄存器分配的改進,或者是由於特殊的“快速路徑”執行單元,用於某些較低精度的數學運算。即使沒有原始的性能優勢,使用更低的精度也會減少GPU上的電量,從而提高電池的使用壽命。
一般的經驗法則是,除了位置和紋理坐標之外,所有的東西都要有half精度。如果half精度不足以計算,才提高精度。
對無窮大、不是數值或者其他特殊浮點值的支持
對於特殊浮點值的支持,這要根據你的GPU來分別討論。
所有支持 D3D 10的 PC GPU都能很好地支持IEEE 754浮點數據標准。這也就意味着浮點數在GPU上表現和在編程語言在CPU中表現一樣的好。
移動GPU則有一些輕微的不同等級的支持。在一些平台上, 0除以0結果不是一個數值;在其它平台則可能結果為無窮大,0或者任何其它隨機的值。一定要在你的目標平台上測試你的shader來確保他們是被支持的。
外部的GPU文檔
GPU供應商對於他們的GPU提供了一個全方位的說明文檔,包括GPU的表現和能力,詳細情況請看下面:
- ARM Mali Guide for Unity Developers
- Qualcomm Adreno OpenGL ES Developer Guide
- PowerVR Architecture Guides