CocosCreator Shader學習(一):描邊效果

最近研究了一下CocosCreator的shader使用方法,並把自己學習期間寫的一些效果分享出來。

CocosCreator版本:v2.3.2

官方學習鏈接:Material 材質介紹Effect介紹(官方文檔是最好的學習文檔,一定要反覆多看)

描邊效果

原理:1.判斷圖片中的某個點周圍8個點的alpha值。2.判斷某點是否處於圖片邊緣。

如上3圖就是給精靈換材質並選定自定義的Effect。

頂點着色器代碼不用修改。

片元着色器代碼如下:

CCProgram fs %{
  precision highp float;
  
  #include <alpha-test>
  #include <cc-global>

  in vec4 v_color;

  #if USE_TEXTURE
  in vec2 v_uv0;
  uniform sampler2D texture;
  #endif

  //cocos規定在shader中所有非sampler的uniform都應以block形式聲明
  uniform InputData{
    float outlineWidth;  //外部程序輸入描邊寬度1-1.0。
  };

  //檢查pos點是否需要描邊
  bool checkIsMakeOutline(vec2 pos){
    //alpha檢測值
    float alpha = 0.1;
    vec4 color = texture(texture, pos);
    if(color.a <= alpha || outlineWidth == 0.0)return false;

    //檢測當前點周圍的8個點的alpha值
    color = texture2D(texture, pos + vec2(0, outlineWidth));
    if(color.a <= alpha)return true;
    color = texture2D(texture, pos + vec2(outlineWidth, outlineWidth));
    if(color.a <= alpha)return true;
    color = texture2D(texture, pos + vec2(outlineWidth, 0));
    if(color.a <= alpha)return true;
    color = texture2D(texture, pos + vec2(outlineWidth, -outlineWidth));
    if(color.a <= alpha)return true;
    color = texture2D(texture, pos + vec2(0, -outlineWidth));
    if(color.a <= alpha)return true;
    color = texture2D(texture, pos + vec2(-outlineWidth, -outlineWidth));
    if(color.a <= alpha)return true;
    color = texture2D(texture, pos + vec2(-outlineWidth, 0));
    if(color.a <= alpha)return true;
    color = texture2D(texture, pos + vec2(-outlineWidth, outlineWidth));
    if(color.a <= alpha)return true;
    
    //當前點已是紋理邊緣
    if(pos.x <= outlineWidth || pos.x >= 1.0 - outlineWidth)return true;
    if(pos.y <= outlineWidth || pos.y >= 1.0 - outlineWidth)return true;

    return false;
  }

  void main () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
    o *= texture(texture, v_uv0);
      #if CC_USE_ALPHA_ATLAS_TEXTURE
      o.a *= texture2D(texture, v_uv0 + vec2(0, 0.5)).r;
      #endif
    #endif

    o *= v_color;

    ALPHA_TEST(o);

    if(checkIsMakeOutline(v_uv0)){
      //檢查到v_uv0點需要描邊,直接改變顏色值
      o = vec4(1, 0, 0, 1);
    }

    gl_FragColor = o;
  }
}%

註釋寫的很詳細,大家應該都看得懂。

運行效果圖如下:

如果大家描邊寬度在編輯器中顯示和運行起來的效果相差很大(這個坑,在論壇看了很多大神的帖子,才爬出來)。

主要原因:cocos運行的時候默認會自動合圖,合圖之後導致Effect中接收到的紋理uv座標不是單個圖的紋理座標,大概就是這個意思吧。

解決方法:取消單個圖自動合圖。

 

 

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