// Copyright (c) 2017-2018 Xiamen Yaji Software Co., Ltd.  
// 马赛克特效
// 原理： n x n 方块内取同一颜色

CCEffect %{
  techniques:
  - passes:
    - vert: unlit-vs
      frag: unlit-fs
      blendState:
        targets:
        - blend: true
      rasterizerState:
        cullMode: none
      properties:
        mainTexture: { value: white }
        alphaThreshold: { value: 0.5 }
        # X轴方块数量
        xBlockCount: {
          value: 30.0,
          editor: {
            tooltip: "X轴方向马赛克方块数量"
          }
        }
        # Y轴方块数量
        yBlockCount: {
          value: 30.0,
          editor: {
            tooltip: "Y轴方向马赛克方块数量"
          }
        }
}%


CCProgram unlit-vs %{
  precision highp float;

  #include <builtin/uniforms/cc-global>
  #include <builtin/uniforms/cc-local>

  in vec3 a_position;
  in vec4 a_color;
  out vec4 v_color;

  #if USE_TEXTURE
  in vec2 a_uv0;
  out vec2 v_uv0;
  #endif

  void main () {
    vec4 pos = vec4(a_position, 1);

    #if CC_USE_MODEL
    pos = cc_matViewProj * cc_matWorld * pos;
    #else
    pos = cc_matViewProj * pos;
    #endif

    #if USE_TEXTURE
    v_uv0 = a_uv0;
    #endif

    v_color = a_color;

    gl_Position = pos;
  }
}%


CCProgram unlit-fs %{
  precision highp float;
  
  #include <builtin/internal/alpha-test>

  in vec4 v_color;

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

  #if USE_MOSAIC
  uniform Mosaic {
    // X轴方块数量
    float xBlockCount;
    // Y轴方块数量
    float yBlockCount;
  };

  /**
   * 获取v_uv0最终映射的马赛格格子的坐标
   *
   * @return 映射后坐标
   */
  vec2 getUvMapPos() {
    // 计算x轴格子宽度
    float xCount;
    if (xBlockCount <= 0.0) {
      xCount = 1.0;
    } else {
      xCount = xBlockCount;
    }
    float blockWidth = 1.0 / xCount;

    // 计算当前 v_uv0 在x轴的哪个格子上
    float blockXIndex = floor(v_uv0.x / blockWidth); 

    // 同理，求出当前 v_uv0 在y轴上的哪个格子
    float yCount; 
    if (yBlockCount <= 0.0) {
      yCount = 1.0;
    } else {
      yCount = yBlockCount;
    }
    float blockHeight = 1.0 / yCount;
    float blockYIndex = floor(v_uv0.y / blockHeight);

    // 找到该格子的中心点实际对应的uv坐标
    return vec2(blockWidth * (blockXIndex + 0.5), blockHeight * (blockYIndex + 0.5));
  }

  
  #endif

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

    vec2 realPos = v_uv0;
    #if USE_MOSAIC
    realPos = getUvMapPos();
    #endif

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

    o *= v_color;

    ALPHA_TEST(o);

    gl_FragColor = o;
  }
}%
