OpenGL著色器(shader)語言
典型結構:
基本數據類型:int, float, double, uint, bool?
GLSL容器類型:vector, matrix
使用.操作符引用成員,如坐標(x, y, z, w),顏色(r, g, b, a),紋理坐標(s, t, p, q)
分量重組:
vec2 someVec;
vec4 differentVec = someVec.xyxx;
vec3 anotherVec = differentVec.zyw;
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;
vec2 vect = vec2(0.5f,0.7f);
vec4 result = vec4(vect,0.0f,0.0f);
vec4 otherResult = vec4(result.xyz,1.0f);
頂點著色器:使用location這一元數據指定輸入變量,這樣我們才可以在CPU上配置頂點屬性。頂點著色器需要為它的輸入提供一個額外的layout標識,這樣我們才能把它鏈接到頂點數據。
片段著色器:使用vec4顏色輸出變量,若未定義輸出顏色,則默認為黑色或白色
各著色器數據交流:從一個著色器向另一個著色器發送數據,必須在發送方著色器中聲明一個輸出,在接收方著色器中聲明一個類似的輸入。當類型和名字都一樣的時候,OpenGL就會把兩個變量鏈接到一起,它們之間就能發送數據了(這是在鏈接程序對象時完成的)。
Uniform是一種從CPU中的應用向GPU中的著色器發送數據的方式,但uniform和頂點屬性有些不同。首先,uniform是全局的(Global)。全局意味著uniform變量必須在每個著色器程序對象中都是獨一無二的,而且它可以被著色器程序的任意著色器在任意階段訪問。第二,無論你把uniform值設置成什么,uniform會一直保存它們的數據,直到它們被重置或更新。
我們可以通過glUniform4f函數設置uniform值。注意,查詢uniform地址不要求你之前使用過著色器程序,但是更新一個unform之前你必須先使用程序(調用glUseProgram),因為它是在當前激活的著色器程序中設置unform的。
uniform函數有許多,但命名方式遵循一定的規律:
支持多屬性:
高級GLSL
GLSL的內建變量
gl_Position:頂點著色器裁剪空間輸出的位置向量
gl_PointSize:用于基本圖元GL_POINTS,設置點的大小,類型為float;使用前需開啟
glEnable(GL_PROGRAM_POINT_SIZE);
gl_VertexID:整型變量,存儲繪制的當前頂點的id。進行索引渲染是,它保存著當前繪制頂點的索引,其他時候保存的是從渲染開始起直到當前處理的這個頂點的編號。
片段著色器的變量
gl_FragCoord:它的z元素和特定的片段的深度相等;x,y是當前片段的窗口坐標
gl_FrontFacing:bool型,若當前片段是正面的一部分值為true,反之為false。可以根據其值為內外賦予不同的紋理
gl_FragDepth:設置當前片段的深度值,若不設置值則采用gl_FragCoord.z的值。可以使用深度條件重新聲明這個變量
layout (depth_<condition>) out float gl_FragDepth;
condition可能取值:例如depth_greater
any ? ? ? ? ? ? ? 默認值. 前置深度測試是關閉的
greater ? ? ? ? 深度值只能比gl_FragCoord.z大
less ? ? ? ? ? ? ? 深度值只能設置得比gl_FragCoord.z小
unchanged ?如果寫入gl_FragDepth, 就會寫gl_FragCoord.z
接口塊
使用in, out關鍵字聲明,如果接口塊的名字一致,in塊和out塊的數據會聯系起來
out ?VS_OUT{
? ? ? vec2 TexCoords;
} vs_out;
in VS_OUT{
? ? ? ?vec2 TexCoords;
} fs_in;
塊的成員使用.運算符來引用;
Uniform緩沖對象
uniform緩沖對象比單獨的uniform有很多好處。第一,一次設置多個uniform比一次設置一個速度快。第二,如果改變一個橫跨多個著色器的uniform,在uniform緩沖中只需更改一次。第三,使用uniform緩沖對象可以在著色器中使用更多的uniform。OpenGL有一個對可使用uniform數據的數量的限制,可以用GL_MAX_VERTEX_UNIFORM_COMPONENTS來獲取。當使用uniform緩沖對象中,這個限制的閾限會更高。所以無論何時,當達到了uniform的最大使用數量(比如做骨骼動畫的時候),可以使用uniform緩沖對象。
GLSL 默認使用的uniform內存布局叫做共享布局(shared layout),叫共享是因為一旦偏移量被硬件定義,它們就會持續地被多個程序所共享。使用共享布局,GLSL可以為了優化而重新放置uniform變量,只要變量的順序保持完整。
使用uniform緩沖
之后往緩沖中更新或插入數據,可綁定到uboExampleBlock上,并使用glBufferSubData來更新它的內存。只需要更新這個uniform緩沖一次,所有的使用這個緩沖著色器就都會使用它更新的數據了。
在OpenGL環境(context)中,定義了若干綁定點(binding points),可以把一個uniform緩沖鏈接上去。當創建了一個uniform緩沖,把它鏈接到一個綁定點上,同時也把著色器中uniform塊鏈接到同一個綁定點上,這樣就把它們鏈接到一起了。下面的圖標表示了這點:
必須為每個著色器共用的uniform設置綁定點。
之后將uniform緩沖對象綁定到同樣的綁定點上,
從OpenGL4.2起,可以在著色器中通過添加另一個布局標識符來儲存一個uniform塊的綁定點,顯式設置綁定點:
最后向uniform緩沖中添加數據,
圖片和一些文字來源于https://learnopengl-cn.github.io,本人收集作為筆記,如有侵權,望告知