GLSL基礎


GLSL基礎

OpenGL Shading Language GLSL作為一種着色語言是純粹的和GPU打交道的計算機語言。
因為GPU是多線程並行處理器,所以GLSL直接面向SIMD模型的多線程計算。
GLSL編寫的着色器函數是對每個數據同時執行的。
每個頂點都會由頂點着色器中的算法處理,每個像素也都會由片段着色器中的算法處理。
因此,初學者在編寫自己的着色器時,需要考慮到SIMD的並發特性,並用並行計算的思路來思考問題。 

最常見用法是在頂點着色器里生成所需要的值,然后傳給片斷着色器用。  
GLSL能做什么?

  • 日以逼真的材質 -- 金屬,岩石,木頭,油漆等
  • 日益逼真的光照效果 -- 區域光和軟陰影
  • 非現實材質 -- 美術效果,鋼筆畫,水墨畫和對插畫技術的模擬
  • 針對紋理內存的新用途
  • 更少的紋理訪問 
  • 圖形處理 -- 選擇,邊緣鈍化遮蔽和復雜混合
  • 動畫效果 -- 關鍵幀插值,粒子系統
  • 用戶可編程的反走樣方法

GLSL注意

  • GLSL支持函數重載
  • GLSL不存在數據類型的自動提升,類型必須嚴格保持一致。
  • GLSL不支持指針,字符串,字符,它基本上是一種處理數字數據的語言
  • GLSL不支持聯合、枚舉類型、結構體位字段及按位運算符

數據類型


GLSL有三種基本數據類型:float,int和bool,以及由這些數據類型組成的數組和結構體。
需要注意的是,GLSL並不支持指針。與C/C++不同的是,GLSL將向量和矩陣作為基本數據類型。
注意:GLSL不存在數據類型的自動提升,類型必須嚴格保持一致。

標量

  • float 
  • int 
  • bool 
42   // 十進制  
042  // 八進制  
0x2A // 十六進制

 

GLSL不存在數據類型的自動提升,類型必須嚴格保持一致

矢量

矢量可以和標量甚至矩陣做加減乘除(必須符合規則) 

 vec2,  vec3,  vec4 // 包含2/3/4個浮點數的矢量
ivec2, ivec3, ivec4 // 包含2/3/4個整數的矢量
bvec2, bvec3, bvec4 // 包含2/3/4個布爾值的矢量

聲明:

vec3 v;             //聲明三維浮點型向量v  
v[1]=3.0;           //給向量v的第二個元素賦值  

// 下面兩種等價
vec3 v = vec3(0.6);
vec3 v = vec3(0.6, 0.6, 0.6);

注意: 除了用索引的方式外,還可以用選擇運算符的方式來使用向量。選擇運算符是對於向量的各個元素(最多為4個)約定俗成的名稱,用一個小寫拉丁字母來表示。根據向量表示對象的意義不同,可以使用以下選擇運算符:
表示頂點可以用 (x、y、z、w)
表示顏色可以用 (r、g、b、a)
表示紋理坐標用 (s、t、p、q)
用戶可以選擇其中任意一種選擇運算符,它們的作用是等效的。
也就是說,如果v是一個向量,那么 v[0]v.rv.x 和 v.s 都指的是向量v的第一個元素。  

例如:

vec4 v1=vec4(1.0, 2.0, 3.0, 4.0);   //用構造函數的方式聲明並初始化四維浮點型
vec4 v2;  
v2.xy=v1.yz;                    //將v1的第二個和第三個元素復制到v2的第一個和第二個元素 
v2.z=2.0;                       //給v2的第三個元素賦值  
v2.xy=v1.yx;                    //將v1的頭兩個元素互換,再復制到v2的頭兩個元素中

矩陣

mat2, mat3, mat4 -- 2x2/3x3/4x4/的矩陣
矩陣是按列順序組織的,先列后行

例如:

mat4 m;             //聲明四維浮點型方陣m  
m[2][3]=2.0;        //給方陣的第三列、第四行元素賦值 

// 下面兩種等價,初始化矩陣對角
mat2 m = mat2(1.0)
mat2 m = mat2(1.0, 0.0, 0.0, 1.0);

取樣器(Sampler)

紋理查找需要制定哪個紋理或者紋理單元將制定查找。

sampler1D           // 訪問一個一維紋理
sampler2D           // 訪問一個二維紋理           
sampler3D           // 訪問一個三維紋理
samplerCube         // 訪問一個立方貼圖紋理
sampler1DShadow     // 訪問一個帶對比的一維深度紋理
sampler2DShadow     // 訪問一個帶對比的二維深度紋理
uniform sampler2D grass;

vcc2 coord = vec2(100, 100);
vec4 color = texture2D(grass, coord);

如果一個着色器要在程序里結合多個紋理,可以使用取樣器數組

const int tex_nums = 4;
uniform sampler2D textures[tex_nums];

for(int i = 0; i < tex_nums; ++i) {
    sampler2D tex = textures[i];
    // todo ...
}

結構體:

這是唯一的用戶定義類型

struct light  
{  
    vec3 position;  
    vec3 color;  
};  

light ceiling_light;

數組

數組索引是從0開始的,而且沒有指針概念

// 創建一個10個元素的數組  
vec4 points[10];  

// 創建一個不指定大小的數組
vec4 points[]; 
points[2] = vec4(1.0);  // points現在大小為3
points[7] = vec4(2.0);  // points現在大小為8

void

只能用於聲明函數返回值

類型轉換

必須明確地進行類型轉換,不會自動類型提升

float f = 2.3; 
bool b = bool(f); // b is true

限定符


GLSL中有4個限定符(variable qualifiers)可供使用,它們限定了被標記的變量不能被更改的"范圍"。 

  • const
  • attribute
  • uniform
  • varying

const

const和C++里差不多,定義不可變常量
表示限定的變量在編譯時不可被修改

attribute

attribute是應用程序傳給頂點着色器用的
不允許聲明時初始化
attribute限定符標記的是一種全局變量,該變量在頂點着色器中是只讀(read-only)的,該變量被用作從OpenGL應用程序向頂點着色器中傳遞參數,因此該限定符僅能用於頂點着色器。

uniform

unifrom一般是應用程序用於設定頂點着色器和片斷着色器相關初始化值。
不允許聲明時初始化
uniform限定符標記的是一種全局變量,該變量對於一個圖元(primitive)來說是不可更改的 它可以從OpenGL應用程序中接收傳遞來的參數。

varying

varying用於傳遞頂點着色器的值給片斷着色器
不允許聲明時初始化
它提供了從頂點着色器向片段着色器傳遞數據的方法,varying限定符可以在頂點着色器中定義變量,然后再傳遞給光柵化器,光柵化器對數據插值后,再將每個片段的值交給片段着色器。 

限制


  • 不能在if-else中聲明變量
  • 用於判斷的條件必須是bool類型(if,while,for...)
  • (?:)操作符后兩個參數必須類型相同
  • 不支持switch語句
vec4 toonify(in float intensify) 
{
    vec4 color;
    color = vec4(0.8,0.8,0.8,0.8)
    return color;
}

discard


discard關鍵字可以避免片段更新幀緩沖區,當流控制遇到這個關鍵字時,正在處理的片段就會被標記為丟

函數


  • 函數名可以通過參數類型重載,但是和返回值類型無關
  • 所有參數必須完全匹配,參數不會自動
  • 函數不能被遞歸調用
  • 函數返回值不能是數組

函數參數標示符

in: 進復制到函數中,但不返回的參數(默認)
out: 不將參數復制到函數中,但返回參數
inout: 復制到函數中並返回 

混合操作


通過在選擇器(.)后列出各分量名,就可以選擇這些分量 

vec4 v4;
v4.rgba;    // 得到vec4
v4.rgb;     // 得到vec3
v4.b;       // 得到float
v4.xy;      // 得到vec2
v4.xgba;    // 錯誤!分量名不是同一類

v4.wxyz;    // 打亂原有分量順序
v4.xxyy;    // 重復分量

 最后推薦一個GLSL編輯調試工具 OpenGL Shader Builder (Mac OS X) 在蘋果的開發者中心的下載Graphics Tools.dmp


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM