本文介紹了OpenGL ES著色器使用的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括同安網(wǎng)站建設(shè)、同安網(wǎng)站制作、同安網(wǎng)頁(yè)制作以及同安網(wǎng)絡(luò)營(yíng)銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,同安網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到同安省份的部分城市,未來相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!
1.著色器語(yǔ)言
著色器語(yǔ)言是一種高級(jí)圖形編程語(yǔ)言,和C/C++語(yǔ)言很類似,但存在很大差別,比如,不支持double,byte
,short,不支持unin,enum,unsigned以及位運(yùn)算等,但其加入了很多原生的數(shù)據(jù)類型,如向量,矩陣等。
數(shù)據(jù)類型可分為標(biāo)量、向量、矩陣、采樣器、結(jié)構(gòu)體、數(shù)組等
向量
向量傳遞參數(shù),如果只提供一個(gè)標(biāo)量,這個(gè)值用于設(shè)置所有向量的值;如果輸入是多個(gè)標(biāo)量或者是矢量,從左到右設(shè)置矢量變量的參數(shù),如果多個(gè)矢量作為參數(shù),那么至少要有和變量一樣多的分量
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中的使用非常廣泛,涉及到圖形的平移縮放旋轉(zhuǎn)等操作都是由矩陣來實(shí)現(xiàn)的.
向矩陣傳遞參數(shù):
向量和矩陣的分量
向量一般用來存儲(chǔ)位置、顏色紋理坐標(biāo)等包含不止一個(gè)的量,訪問向量中某個(gè)分量的方法為:<向量名.分量名>
這三種不同的命名方案不能混合使用,除此之外還可以將向量當(dāng)做數(shù)組看待,用下表來訪問。
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}
對(duì)矩陣的訪問當(dāng)成一個(gè)二維數(shù)組即可,矩陣可以認(rèn)為是由多個(gè)向量組成的
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
采樣器
采樣器專門用于進(jìn)行紋理采樣的相關(guān)操作,一般情況下一個(gè)采樣器變量代表了衣服紋理切貼圖。
sampler2D/sampler3D/samplerCube
采樣器變量不是在著色器中初始化的,一般是由主程序傳遞進(jìn)來的。
數(shù)組
聲明數(shù)組時(shí)指定數(shù)組大小,反之,訪問數(shù)組時(shí)的下表必須是編譯時(shí)常量,這樣的話,編譯器會(huì)自動(dòng)創(chuàng)建適當(dāng)大小的數(shù)組
類型轉(zhuǎn)換
著色器語(yǔ)言沒有自動(dòng)提升的功能,也不能強(qiáng)制轉(zhuǎn)換,只能用構(gòu)造器完成類型轉(zhuǎn)換,每中內(nèi)建變量類型都有一組相關(guān)的構(gòu)造器。
float f = 1; // error int i = 0.0; // error float f = 1.0 // ok bool b = bool(f) // ok,非0當(dāng)做true float f = float(b) // ok,bool轉(zhuǎn)為浮點(diǎn)數(shù),true轉(zhuǎn)為1.0,false轉(zhuǎn)為0.0 int i = 0; //ok bool b = bool(i) // ok,int轉(zhuǎn)為bool
變量限定符
const:常量,編譯時(shí)常量,其值不可變,可以提高運(yùn)行效率
attribute:屬性變量,僅僅用在頂點(diǎn)著色器,用該限定符修飾的變量用來接受從宿主程序傳進(jìn)渲染管線的變量。一般用于每個(gè)頂點(diǎn)都不相同的量,比如頂點(diǎn)位置,顏色,法線等
uniform:統(tǒng)一變量,一般用于對(duì)同一組頂點(diǎn)組成的一個(gè)物體所有頂點(diǎn)都相同的量,比如光源位置,轉(zhuǎn)換矩陣,顏色,光照等
varying:變量被用來存儲(chǔ)頂點(diǎn)著色器的輸出和片元著色器的輸入,每個(gè)頂點(diǎn)著色器把輸出數(shù)據(jù)轉(zhuǎn)變成一個(gè)或更多片元著色器的輸入,在光柵化階段就會(huì)插值生成一系列變量
varying變量的原理
在線段上進(jìn)行混合插值
在三角形上進(jìn)行混合插值
獲取著色器變量
獲取attribute類型變量。對(duì)于attribute限定符修飾的變量的值是由宿主程序傳入渲染管線的,使用glGetAttribLocation函數(shù)獲得著色器中某屬性變量的引用
public static native int glGetAttribLocation( int program, // 創(chuàng)建的程序?qū)ο? String name // 著色器中變量名 );
然后使用glVertexAttribPointer函數(shù)將數(shù)據(jù)傳遞到glGetAttribLocation返回的著色器變量引用所代表的變量中去
public static void glVertexAttribPointer( int indx, // 屬性變量的引用 int size, //每個(gè)頂點(diǎn)的數(shù)據(jù)個(gè)數(shù),比如x、y、z就是3 int type, // 數(shù)據(jù)類型,如GLES20.GL_FLOAT boolean normalized, // 是否規(guī)格化,只有使用整形數(shù)據(jù)才有意義 int stride, // 跨距,一個(gè)數(shù)組存儲(chǔ)多個(gè)屬性才有意義,指的是兩個(gè)點(diǎn)之間有多少個(gè)字節(jié) java.nio.Buffer ptr // 存放頂點(diǎn)數(shù)據(jù)緩沖 )
獲取uniform類型的變量。使用glGetUniformLocation函數(shù)獲得著色器中某統(tǒng)一變量的引用
public static native int glGetUniformLocation( int program, String name );
然后使用glUniformXXX函數(shù)將數(shù)據(jù)傳遞到著色器中,比如glUniformMatrix4fv函數(shù)
public static native void glUniformMatrix4fv( int location, // 統(tǒng)一變量的引用 int count, // 指明要更改的元素個(gè)數(shù)。如果變量不是數(shù)組,這個(gè)值應(yīng)該設(shè)為1 boolean transpose, // 是否要轉(zhuǎn)置矩陣,并將它作為uniform變量的值。必須為false float[] value, // 傳遞給統(tǒng)一變量的數(shù)組元素 int offset // 偏移,取0 );
glUniformNf/glUniformNfv:將N個(gè)浮點(diǎn)數(shù)傳入管線
glUniformNi/glUniformNiv:將N個(gè)整數(shù)傳入管線
glUniformMatrixNfv:將N個(gè)整數(shù)傳入管線,將N*N矩陣傳入管線
內(nèi)建變量
內(nèi)建變量不需要聲明即可使用,內(nèi)建變量分為兩種,輸入與輸出變量。
輸入變量負(fù)責(zé)將渲染管線中固定功能部分生成的信息傳遞進(jìn)著色器以供程序員使用,輸出變量負(fù)責(zé)將著色器產(chǎn)生的信息傳遞給渲染管線中的固定功能。
頂點(diǎn)著色器
頂點(diǎn)著色器的內(nèi)建變量主要是輸出變量,即將著色器產(chǎn)生的值傳遞給渲染管線,因此在頂點(diǎn)著色器中要對(duì)這些內(nèi)建變量賦值,包括gl_Position、gl_PointSize等。
片元著色器
片元著色器中的內(nèi)建輸入變量,gl_FragCoord、gl_FrontFacing,并且還是只讀的,是由渲染管線片元著色器之前階段生成的。
片元著色器中的內(nèi)建輸出變量gl_FragColor、gl_FragData,在片元著色器中給這兩個(gè)內(nèi)建變量寫入值。
函數(shù)
和其他語(yǔ)言一樣,差別在于參數(shù)可以指定用途,具體的有in,out,inout修飾符表明該參數(shù)是入?yún)⑦€是出參。
片元著色器浮點(diǎn)變量精度
片元著色器中的浮點(diǎn)類型數(shù)據(jù)必須制定精度,不指定精度可能引起編譯錯(cuò)誤。有三種精度類型:lowp、mediump、highp,一般使用mediump類型即可。如果在開發(fā)中同一個(gè)片元著色器中浮點(diǎn)類型變涼都是同一種精度類型,可以整個(gè)指定著色器中浮點(diǎn)類型默認(rèn)精度。
precision <精度> <類型>
precision mediump float;
2.著色器程序
需要?jiǎng)?chuàng)建兩個(gè)對(duì)象才能用著色器進(jìn)行渲染:著色器對(duì)象和程序?qū)ο蟆?/p>
著色器源代碼被編譯成一個(gè)目標(biāo)形式(類似obj文件),編譯之后,著色器對(duì)象可以連接到一個(gè)程序?qū)ο?,程序?qū)ο罂梢赃B接多個(gè)著色器對(duì)象。
獲得連接后的著色器對(duì)象的過程:
如果沒有出錯(cuò),就可以在后面使用這個(gè)程序了,如從程序獲取某個(gè)著色器變量,接下來為其傳遞值等操作。
創(chuàng)建著色器對(duì)象
public static native int glCreateShader( int type // 著色器類型,GLES20.GL_VERTEX_SHADER或GLES20.GL_FRAGMENT_SHADER );
連接源代碼到著色器對(duì)象
public static native void glShaderSource( int shader, String string // 著色器源碼 );
編譯著色器對(duì)象
public static native void glCompileShader( int shader );
創(chuàng)建程序?qū)ο?/p>
mProgram = GLES20.glCreateProgram();
將編譯后的著色器對(duì)象連接到程序?qū)ο?/p>
public static native void glAttachShader( int program, int shader );
連接程序?qū)ο?/p>
public static native void glLinkProgram( int program );
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。
標(biāo)題名稱:OpenGLES著色器使用詳解(二)
鏈接分享:http://www.rwnh.cn/article20/ipcsjo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供商城網(wǎng)站、自適應(yīng)網(wǎng)站、響應(yīng)式網(wǎng)站、虛擬主機(jī)、移動(dòng)網(wǎng)站建設(shè)、做網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)