亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

OpenGL ES著色器使用詳解(二)

發布時間:2020-10-19 09:47:17 來源:腳本之家 閱讀:178 作者:weiers 欄目:移動開發

本文介紹了OpenGL ES著色器使用的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下

1.著色器語言

著色器語言是一種高級圖形編程語言,和C/C++語言很類似,但存在很大差別,比如,不支持double,byte

,short,不支持unin,enum,unsigned以及位運算等,但其加入了很多原生的數據類型,如向量,矩陣等。

數據類型可分為標量、向量、矩陣、采樣器、結構體、數組等

OpenGL ES著色器使用詳解(二)

向量

向量傳遞參數,如果只提供一個標量,這個值用于設置所有向量的值;如果輸入是多個標量或者是矢量,從左到右設置矢量變量的參數,如果多個矢量作為參數,那么至少要有和變量一樣多的分量

vec4 myVec4 = vec4(1.0); // myVec4 = {1.0, 1.0, 1.0, 1.0}
vec3 myVec3 = vec3(1.0, 0.0, 0.5); // myVec3 = {1.0, 0.0, 0.5}
vec3 temp = vec3(myVec3); // temp = myVec3
vec2 myVec2 = vec2(myVec3); // myVec2 = {myVec3.x, myVec3.y}
myVec4 = vec4(myVec2, temp); // myVec4 = {myVec2.x, myVec2.y, temp.x, temp.y}

矩陣

矩陣操作在OpenGL ES中的使用非常廣泛,涉及到圖形的平移縮放旋轉等操作都是由矩陣來實現的.

向矩陣傳遞參數:

  • 提供的是一個標量,那么標量復制給與矩陣的主對角線
  • 一個矩陣能被多個向量賦值,如,mat2可以用兩個vec2賦值
  • 一個的矩陣被多個標量賦值,按列賦值

向量和矩陣的分量

向量一般用來存儲位置、顏色紋理坐標等包含不止一個的量,訪問向量中某個分量的方法為:<向量名.分量名>

  • 將向量看做顏色對待,四個分量為r、g、b、a,分別代表紅、綠、藍、透明度
  • 將向量看做位置對待,四個分量為x、y、z、w,分別代表x軸、y軸、z軸、w
  • 將向量看做紋理坐標對待,四個分量為s、t、p、q,分別代表紋理坐標的不同分量

這三種不同的命名方案不能混合使用,除此之外還可以將向量當做數組看待,用下表來訪問。

vec3 myVec3 = vec3(0.0, 1.0, 2.0); // myVec3 = {0.0, 1.0, 2.0}
float x = myVec3.x;
vec3 temp;
temp = myVec3.xyz; // temp = {0.0, 1.0, 2.0}
temp = myVec3.xxx; // temp = {0.0, 0.0, 0.0}
temp = myVec3.zyx; // temp = {2.0, 1.0, 0.0}
vec4 temp2 = myVec3.xxyz; // temp2 = {0.0, 0.0, 1.0, 2.0}

對矩陣的訪問當成一個二維數組即可,矩陣可以認為是由多個向量組成的

mat4 myMat4 = mat4(1.0); // Initialize diagonal to 1.0 (identity)
vec4 col0 = myMat4[0]; // Get col0 vector out of the matrix
float m1_1 = myMat4[1][1]; // Get element at [1][1] in matrix
float m2_2 = myMat4[2].z; // Get element at [2][2] in matrix

采樣器

采樣器專門用于進行紋理采樣的相關操作,一般情況下一個采樣器變量代表了衣服紋理切貼圖。

sampler2D/sampler3D/samplerCube

采樣器變量不是在著色器中初始化的,一般是由主程序傳遞進來的。

數組

聲明數組時指定數組大小,反之,訪問數組時的下表必須是編譯時常量,這樣的話,編譯器會自動創建適當大小的數組

類型轉換

著色器語言沒有自動提升的功能,也不能強制轉換,只能用構造器完成類型轉換,每中內建變量類型都有一組相關的構造器。

float f = 1; // error
int i = 0.0; // error
float f = 1.0 // ok
bool b = bool(f) // ok,非0當做true
float f = float(b) // ok,bool轉為浮點數,true轉為1.0,false轉為0.0
int i = 0; //ok
bool b = bool(i) // ok,int轉為bool

變量限定符

const:常量,編譯時常量,其值不可變,可以提高運行效率

attribute:屬性變量,僅僅用在頂點著色器,用該限定符修飾的變量用來接受從宿主程序傳進渲染管線的變量。一般用于每個頂點都不相同的量,比如頂點位置,顏色,法線等

uniform:統一變量,一般用于對同一組頂點組成的一個物體所有頂點都相同的量,比如光源位置,轉換矩陣,顏色,光照等

varying:變量被用來存儲頂點著色器的輸出和片元著色器的輸入,每個頂點著色器把輸出數據轉變成一個或更多片元著色器的輸入,在光柵化階段就會插值生成一系列變量

varying變量的原理

在線段上進行混合插值

OpenGL ES著色器使用詳解(二)

在三角形上進行混合插值

OpenGL ES著色器使用詳解(二)

獲取著色器變量

獲取attribute類型變量。對于attribute限定符修飾的變量的值是由宿主程序傳入渲染管線的,使用glGetAttribLocation函數獲得著色器中某屬性變量的引用

public static native int glGetAttribLocation(
  int program, // 創建的程序對象
  String name // 著色器中變量名
);

然后使用glVertexAttribPointer函數將數據傳遞到glGetAttribLocation返回的著色器變量引用所代表的變量中去

public static void glVertexAttribPointer(
  int indx, // 屬性變量的引用
  int size, //每個頂點的數據個數,比如x、y、z就是3
  int type, // 數據類型,如GLES20.GL_FLOAT
  boolean normalized, // 是否規格化,只有使用整形數據才有意義
  int stride, // 跨距,一個數組存儲多個屬性才有意義,指的是兩個點之間有多少個字節
  java.nio.Buffer ptr // 存放頂點數據緩沖
 )

獲取uniform類型的變量。使用glGetUniformLocation函數獲得著色器中某統一變量的引用

public static native int glGetUniformLocation(
  int program,
  String name
 );

然后使用glUniformXXX函數將數據傳遞到著色器中,比如glUniformMatrix4fv函數

public static native void glUniformMatrix4fv(
  int location, // 統一變量的引用
  int count, // 指明要更改的元素個數。如果變量不是數組,這個值應該設為1
  boolean transpose, // 是否要轉置矩陣,并將它作為uniform變量的值。必須為false
  float[] value, // 傳遞給統一變量的數組元素
  int offset // 偏移,取0
 );

glUniformNf/glUniformNfv:將N個浮點數傳入管線

glUniformNi/glUniformNiv:將N個整數傳入管線

glUniformMatrixNfv:將N個整數傳入管線,將N*N矩陣傳入管線

內建變量

內建變量不需要聲明即可使用,內建變量分為兩種,輸入與輸出變量。

輸入變量負責將渲染管線中固定功能部分生成的信息傳遞進著色器以供程序員使用,輸出變量負責將著色器產生的信息傳遞給渲染管線中的固定功能。

頂點著色器

頂點著色器的內建變量主要是輸出變量,即將著色器產生的值傳遞給渲染管線,因此在頂點著色器中要對這些內建變量賦值,包括gl_Position、gl_PointSize等。

  • gl_Position:在頂點著色器對獲取到的定點原始數據進行平移縮放旋轉等變換后,生成新的位置,新的頂點位置通過該變量傳遞給渲染管線的后續操作。
  • gl_PointSize:頂點著色器中可以計算一個點的大小,單位為像素,默認值為1,一般對點繪制方式有意義。

片元著色器

片元著色器中的內建輸入變量,gl_FragCoord、gl_FrontFacing,并且還是只讀的,是由渲染管線片元著色器之前階段生成的。

  • gl_FragCoord:vec4類型數據,含有當前片元相對窗口位置的坐標。
  • gl_FrontFacing:bool類型的內建輸入變量,該值表明當前正在處理的片元是否屬于在光柵化階段生成此片元對應圖元的正面。點、線段沒有正反面之分的圖元。其生成的偏遠都會被默認為是正面,三角形圖元其正面取決于程序中隊卷繞的設置及圖元中頂點的具體卷繞情況。

片元著色器中的內建輸出變量gl_FragColor、gl_FragData,在片元著色器中給這兩個內建變量寫入值。

  • gl_FragColo:vec4變量,用來傳入由片元著色器計算出來的片元顏色值。

函數

和其他語言一樣,差別在于參數可以指定用途,具體的有in,out,inout修飾符表明該參數是入參還是出參。

片元著色器浮點變量精度

片元著色器中的浮點類型數據必須制定精度,不指定精度可能引起編譯錯誤。有三種精度類型:lowp、mediump、highp,一般使用mediump類型即可。如果在開發中同一個片元著色器中浮點類型變涼都是同一種精度類型,可以整個指定著色器中浮點類型默認精度。

precision <精度> <類型>
precision mediump float;

2.著色器程序

需要創建兩個對象才能用著色器進行渲染:著色器對象和程序對象。

著色器源代碼被編譯成一個目標形式(類似obj文件),編譯之后,著色器對象可以連接到一個程序對象,程序對象可以連接多個著色器對象。

獲得連接后的著色器對象的過程:

  1. 創建一個頂點著色器和一個片元著色器:
  2. 將源代碼連接到每個著色器對象
  3. 編譯著色器對象
  4. 創建一個程序對象
  5. 將編譯后的著色器對象連接到程序對象
  6. 連接程序對象

如果沒有出錯,就可以在后面使用這個程序了,如從程序獲取某個著色器變量,接下來為其傳遞值等操作。

創建著色器對象

public static native int glCreateShader(
 int type // 著色器類型,GLES20.GL_VERTEX_SHADER或GLES20.GL_FRAGMENT_SHADER
);

連接源代碼到著色器對象

public static native void glShaderSource(
  int shader,
  String string // 著色器源碼
 );

編譯著色器對象

public static native void glCompileShader(
  int shader
 );

創建程序對象

mProgram = GLES20.glCreateProgram();

將編譯后的著色器對象連接到程序對象

public static native void glAttachShader(
  int program,
  int shader
 );

連接程序對象

public static native void glLinkProgram(
  int program
 );

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

黑龙江省| 凤台县| 天水市| 涟源市| 七台河市| 鄂伦春自治旗| 花垣县| 松潘县| 梁平县| 宝鸡市| 汝城县| 吉林市| 贵德县| 合山市| 夏邑县| 大埔区| 邻水| 额敏县| 横山县| 厦门市| 阜阳市| 镶黄旗| 十堰市| 望谟县| 容城县| 乐山市| 长寿区| 德庆县| 江西省| 离岛区| 上饶市| 灌南县| 寻甸| 云浮市| 林西县| 屏东县| 获嘉县| 河津市| 麻城市| 兴文县| 谢通门县|