Android OpenGL ES 2.0 手把手教學(4)- 片斷着色器 fragment shader

你們好,下面和大學一塊兒學習如何使用片斷着色器fragment shader來渲染豐富多彩的顏色,在個人github上有一個項目OpenGLES2.0SamplesForAndroid,我會不斷地編寫學習樣例,文章和代碼同步更新,歡迎關注,連接:github.com/kenneycode/…java

在上一篇文章中,咱們介紹了渲染管線,下面來回顧一下fragment shader在渲染管線中的位置:git

fragment shader會在光柵化後,對每一個像素執行一次,先看一下咱們以前的例子中使用的fragment shader:github

precision mediump float;
void main() {
    gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}
複製代碼

在一開始聲明瞭float的精度爲中精度,接着和vertex shader同樣有一個main()方法做爲入口,fragment shader中有一個內置變量gl_FragColor表示fragment shader的輸出,在以前的例子咱們給gl_FragColor設置了一個固定值vec4(0.0, 0.0, 1.0, 1.0),這是一個RGBA的顏色值,所以咱們以前看到的三角形是一個純藍色的,如今,咱們來實現一個彩色的三角形,這須要vertex shaderfragment shader同時修改,來看看咱們修改後的shader學習

// vertex shader
precision mediump float;
attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main() {
    v_Color = a_Color;
    gl_Position = a_Position;
}
複製代碼
// fragment shader
precision mediump float;
varying vec4 v_Color;
void main() {
    gl_FragColor = v_Color;
}
複製代碼

修改後,gl_FragColor再也不是一個固定值,而是一個類型爲varying的顏色值v_Colorvarying類型變量是一種通過插值後獲得的變量,咱們能夠看到vertex shader中也聲明瞭一樣的varying vec4 v_Color,而後將a_Color賦給v_Colorfragment shader中的v_Color就是經過vertex shader傳遞過來的,而a_Colora_Position同樣是attribute類型。ui

上篇文章提到過,vertex shader會對每一個頂點都執行一次,而fragment shader會對每一個像素執行一次,那麼fragment shader中拿到的v_Color到底是什麼值?它是通過插值的值,這個如何理解呢?先來看一下咱們這個例子中傳遞的值:spa

// 顏色數據
// The color data
private val colorData = floatArrayOf(
                                    1.0f, 0.0f, 0.0f, 1.0f,
                                    0.0f, 1.0f, 0.0f, 1.0f,
                                    0.0f, 0.0f, 1.0f, 1.0f)
// 每一個顏色的成份數(RGBA)
// The num of components of per color(RGBA)
private val COLOR_COMPONENT_COUNT = 4
    
// 將三角形頂點數據放入buffer中
// Put the triangle vertex data into the buffer
val colorDataBuffer = ByteBuffer.allocateDirect(colorData.size * java.lang.Float.SIZE)
    .order(ByteOrder.nativeOrder())
    .asFloatBuffer()
colorDataBuffer.put(colorData)
colorDataBuffer.position(0)

// 獲取字段a_Color在shader中的位置
// Get the location of a_Color in the shader
val aColorLocation = GLES20.glGetAttribLocation(programId, "a_Color")

// 啓動對應位置的參數
// Enable the parameter of the location
GLES20.glEnableVertexAttribArray(aColorLocation)

// 指定a_Color所使用的頂點數據
// Specify the vertex data of a_Color
GLES20.glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GLES20.GL_FLOAT, false,0, colorDataBuffer)
複製代碼

咱們以與傳遞三角形頂點給a_Position相同的方式,將三個顏色值(1.0f, 0.0f, 0.0f, 1.0f)(0.0f, 1.0f, 0.0f, 1.0f)(0.0f, 0.0f, 1.0f, 1.0f)傳遞給a_Color,這時在vertex shader執行時會同時取到頂點和顏色數據的同一位置的數據,將這三個顏色值傳遞給v_Color後,在fragment shader中的v_Color就是通過這三個顏色值插值後的值,例如越靠近顏色(1.0f, 0.0f, 0.0f, 1.0f)對應的點的地方,顏色就越接近(1.0f, 0.0f, 0.0f, 1.0f),咱們來看下效果:code

代碼在我github的OpenGLES2.0SamplesForAndroid項目中,本文對應的是SampleFragmentShader,項目連接:github.com/kenneycode/…component

感謝閱讀!cdn

相關文章
相關標籤/搜索