天天看點

13 WebGL 着色器程式設計語言GLSL ES的精度限定字

GLSL ES新引入了精度限定字,目的是幫助着色器程式提高運作效率,消減記憶體開支。顧名思義,精度限定字用來表示每種資料具有的精度(比特數)。簡而言之,高精度的程式需要更大的開銷(包括更大的記憶體和更久的計算時間),而低精度的程式需要開銷則小得多。使用精度限定字,你就能精細地控制程式在效果和性能間的平衡。然而,精度限定字是可選的,如果你不确定,可以使用下面這個适中的預設值:

#ifdef GL_ES
    precision mediump float;
#endif
           

由于WebGL是基于OpenGL  ES 2.0 的,WebGL程式最後有可能運作在各種各樣的硬體平台上。肯定存在某些情況需要在低精度下運作程式,以提高記憶體使用效率,減少性能開銷,以及更重要的,降低能耗,延長移動裝置的電池續航能力。

注意,在低精度下,WebGL程式的裕興結果會教教粗糙或不準确,比必須在程式效果和性能間進行平衡。

如表6.15所示,WebGL程式支援三種精度,其限定字分别為highp(高精度)、mediump(中精度)和lowp(低精度)。

13 WebGL 着色器程式設計語言GLSL ES的精度限定字

還有兩點值得注意。首先,在某些WebGL環境中,片元着色器可能不支援highp精度,檢查(其是否支援)的方法稍後再讨論;其次,數值範圍和精度實際上也是與系統環境相關的,你可以使用gl.getShaderPrecisionFormat()來檢查。

下面是聲明變量精度的幾個例子:

mediump float size;//中精度的浮點型變量
highp vec4 position;//具有高精度浮點型元素的vec4對象
lowp vec4 color;//具有低精度浮點型元素的vec4對象
           

為每個變量都聲明精度很繁瑣,我們也可以使用關鍵字precision來聲明着色器的預設精度,這行代碼必須在頂點着色器或片元着色器的頂部,其格式如下:

precision 精度限定字 類型名稱;

這句代碼表示,在着色器中,某種類型的變量其預設精度有精度限定字指定。也就是說,接下來所有不以精度限定字修飾的該類型變量,其精度就是預設精度。比如:

precision mediump float; //所有浮點數預設為中精度
precision highp int; //所有整型數預設為高精度
           

上面這段代碼表示,所有float類型以及相關的vec2和mat3的變量都是中精度的,所有整型變量都是高精度的。比如,vec4類型變量的四個分量都是中精度的。

你也許已經注意到,在前幾章我們并沒有限定類型的精度(除了在片元着色器中對float類型做出限定)。這是因為,對于這些類型,着色器已經實作了預設的精度,隻有片元着色器中的float類型沒有預設精度。如表6.16所示。

13 WebGL 着色器程式設計語言GLSL ES的精度限定字

事實就是,片元着色器中的float類型沒有預設精度,我們需要手動指定。如果我們不在片元着色器中限定float類型的精度,就會導緻如下的編譯錯誤:

failed to compile shader: ERROR: 0:1 : No prceision specified for (float).  
           

我們說過,WebGL是否在片元着色器中支援highp精度,取決于具體的裝置。如果其支援的話,那麼着色器就會定義内置宏GL_FRAGMENT_PRECISION_HIGH。(見下一節)

繼續閱讀