學習ShaderToy第一天: glsl語言內置函數gl_FragCoord


運行環境:Android
opengl es版本: 2.0
3D引擎庫 : Rajawali3D


ShaderToy上用的shader語言 爲glsl , 效果是用webgl跑的,而webgl封裝了opengl es,  所以ShaderToy上的例子同樣使用於Android端。

ShaderToy基本上 都是用fragment shader 對柵格化後的像素進行處理。  大部分會用到紋理來豐富最終渲染結果的形狀和質地,有些也會用到聲音,鍵盤等外部輸入信息。    但是,最終都是歸結爲對柵格化區域內的每個像素進行處理,因此,我們首先來認識gl_FragCoord這個內置變量以及其與屏幕座標的關係。

 gl_FragCoord根據glsl language spec的解釋爲:
   它是fragment shaders的輸入變量,並持有該framgent的屏幕相對座標(x, y, z, 1/w)

  什麼是屏幕相對座標,它的座標範圍是多少,這些都沒有告訴我們。需要我們實驗
     

  假設我們採用2d ortho projection的方式來渲染,輸入的頂點信息爲屏幕的4個頂點座標,這樣我們最終渲染出來的是一個 鋪滿屏幕的圖。
 由於是2D渲染,最終每個fragment的 gl_FragCoord的z接近0.0, 而w 爲1.0, 而它的x, y分量,是相對於屏幕左下角爲原點的屏幕座標。什麼意思?
   假如,我們設定的viewport的渲染區域爲(0, 0, 1280, 574) 這麼大,那麼,gl_Fragment的x分量 範圍就在0~1280之間, y分量就在0~574之間。

  我們可以用一下測試用例來進行測試:
   vertex shader:
  
precision mediump float ;

  uniform mat4 uMVPMatrix;
  attribute vec4 aPosition;

  void main(){
      position = vec3 (uMVPMatrix*aPosition);
      gl_Position = uMVPMatrix*aPosition;
  }


 
  fragment shader:

   
precision mediump float ;
  
  uniform vec2 screenSize;  // step  1

  void main()
  {
     vec2 uv = vec2(gl_FragCoord.xy/screenSize.xy);  // step 2

    //Calculate polar coordinates
     float r = length(uv);
     float c = 0.0;

    if(uv.x>0.98 &&uv.x<1.0 )                       // step 3
    {
       c = 1.0;
    }

     if(uv.y>0.98 &&uv.y<1.0 )                     // step 4
     {
       c = 1.0;
     }

     //Calculate the final color mixing lines and backgrounds.
     vec3 bg = mix(vec3(0.93 , 0.71 ,  0.62 ),  vec3(0.9 , 0.44 , 0.44),   r);  // step 5
     bg = mix(bg, vec3 (0.9 , 0.91 , 0.62 ), c);                                //  step 6

     gl_FragColor = vec4(bg, 1.0);
}

運行後,效果圖如下:
  

這裏主要說下 fragment shader:
   step 1: 之前說到, gl_FragCoord的座標範圍, 這裏screenSize 表示屏幕的寬高。
   step 2 :   將每個fragment的 每個gl_FragCoord歸一化,這是一個慣例,利於後面計算
   step3: 和 step4:  這兩個分別表示,當fragment的座標(x, y) 的x和y分量分別落在這個範圍時(即中間)c 的值會發生變化
   step5:  step5 和 step6都用到了glsl 的 mix內置函數,  考慮到 bg = mix(color1, color2, r)它的意思,就是將color1和color2 兩種顏色,按照bg = color1*(1-r)+r*color2的方式混合,其中bg, color1, color2都是表示顏色,有三個分量。 那麼,當r=0.0時,表示的是color1顏色,當r = 1.0表示的是color2顏色。 我們利用mix可以在一種背景上標記出另一種顏色。

 step3 和 step4 表示,當x, y 分別落在值範圍的中間時,c的值從0.0變爲1.0, 即在這個範圍內,背景色變爲我們設置的顏色。


當我們把step3 和 step4 改爲:
    if (uv.x>0.09 &&uv.x<0.11 )                       // step 3
    {
       c = 1.0;
    }

     
if (uv.y>0.09 &&uv.y<0.11 )                     // step 4
     {
       c = 1.0;
     }

效果圖如下:


通過,以上的例子我們得出gl_FragCoord的正確表示方式。

   




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章