//扫光-纹理

CCEffect %{
  techniques:
  - passes:
    - vert: vs
      frag: fs
      blendState:
        targets:
        - blend: true
      rasterizerState:
        cullMode: none
      properties:
        texture: { value: white }
        u_fluxayTexture: { value: white }
        u_time: { value: 0 }
        u_scale: { value: 1.0 }
        u_angle: { value: 30.0 }
        u_uvRotated: { value: 0.0 }
        u_uvOffset: { value: [0.0,0.0,1.0,1.0] }
}%

// Vertex Shader(顶点着色器) 
// 将顶点从模型空间坐标系统转化到屏幕空间坐标系统
// 顶点着色器分为输入和输出两部分
// 负责的功能是把输入的数据进行矩阵变换位置,计算光照公式生成逐顶点颜⾊,⽣成/变换纹理坐标
// 并且把位置和纹理坐标这样的参数发送到片段着色器
CCProgram vs %{
  precision highp float;

  #include <cc-global>
  #include <cc-local>

  // 输入的顶点坐标
  in vec3 a_position;
  // 输入的顶点颜色
  in vec4 a_color;
  // 输出的顶点颜色
  out vec4 v_color;

  #if USE_TEXTURE
    // 输入的纹理坐标
    // UV坐标：原点在左上角，u轴是向右，v轴是向下，范围是0-1
    in vec2 a_uv0;
    // 输出的纹理坐标
    out vec2 v_uv0;
  #endif

  void main () {
    mat4 mvp;
    
    #if CC_USE_MODEL
      mvp = cc_matViewProj * cc_matWorld;
    #else
      mvp = cc_matViewProj;
    #endif

    v_uv0 = a_uv0;

    v_color = a_color;

    gl_Position = mvp * vec4(a_position, 1);
  }
}%

// Fragment Shader(片段着色器)
// 片元着色器的作用是处理由光栅化阶段生成的每个片元，最终计算出每个像素的最终颜色(RGBA)
CCProgram fs %{
  precision highp float;

  #include <alpha-test>
  #include <texture>
  
  in vec4 v_color;

  in vec2 v_uv0;

  uniform sampler2D texture;

  uniform sampler2D u_fluxayTexture;  //流光纹理

  // 自定义属性
  // 所有非 sampler 的 uniform 都必须以 UBO 形式声明
  // UBO 成员声明类型和顺序有严格的校验机制，以排除 GL 标准下隐式布局对齐带来的内存消耗
  // u_uvRotated图片是否旋转
    // u_uvOffset 图片minx,miny,maxx,maxy

  uniform ARGS {
    float u_time;
    float u_scale;
    float u_angle;
    float u_uvRotated;
    vec4  u_uvOffset;
  };

  vec2 transformUV(vec2 UV,float angle){
      float rotate = (angle * 3.1415926) / 180.0;
      vec2 di = vec2(0.5, 0.5); // 旋转的中心位置 
      //float a = cos(rotate);
      mat3 m = mat3(cos(rotate), -sin(rotate), 0.0,sin(rotate), cos(rotate), 0.0,0.0, 0.0, 1.0);
      //vec3 uv = vec3(UV.x-di.x,UV.y+di.y, 1.0)* m;
      //return vec2(uv.x,uv.y)+vec2(di.x,-di.y);
      vec3 uv = vec3(UV.x,UV.y, 1.0)* m;
      return vec2(uv.x,uv.y);
  }

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

    #if USE_TEXTURE
      // texture.inc 核心函数
      // o = texture2D(texture, v_uv0);
      // texture: 纹理，v_uv0: 纹理坐标，通过 GLSL 的内建函数 texture2D 来获取纹理上对应UV坐标的颜色(RGBA)
      o = texture2D(texture, v_uv0);
    #endif

    // 纹理颜色和顶点颜色（节点颜色）叠加得到最终颜色
    o *= v_color;

    // alpha-test.inc 核心函数
    // if (color.a < alphaThreshold) discard;
    // discard：退出片段着色器，不执行后面的片段着色操作，片段也不会写入帧缓冲区
    ALPHA_TEST(o);


    //纹理的xMin
    float xMin = u_uvOffset.x;
    float xWidth = u_uvOffset.z - u_uvOffset.x;
    //x 转换成扫光图片上的位置
    float x = (v_uv0.x - xMin)/xWidth;

    float yMin = u_uvOffset.y;
    float yWidth = u_uvOffset.w- u_uvOffset.y;
    //y 转换成扫光图片上的位置
    float y = (v_uv0.y - yMin)/yWidth;
    float angle = u_angle;
    if(u_uvRotated >= 1.0)
    {
       x = (v_uv0.y - yMin)/yWidth;
       y = (v_uv0.x - xMin)/xWidth;
       angle = -u_angle;
    }
    
    // 在底图不透明的地方叠加流光纹理的颜色
    if(o.a >= 1.0) {    
      // 根据时间设置流光纹理的UV
      vec2 fluxayUV = vec2(x, y);
      x +=  u_scale;
      float time = u_time*(1.0+u_scale);
      //if(fluxayUV.x > u_time-u_scale && fluxayUV.x <u_time)
      if(o.a >= 1.0)
      {
        // 获取流光纹理上UV的颜色
        fluxayUV.x = (x-time)/ u_scale;
        fluxayUV = transformUV(fluxayUV,angle);
        vec4 fluxay = texture2D(u_fluxayTexture, fluxayUV);
        o.a = fluxay.a;
        // 叠加颜色
        gl_FragColor = o;
      }
      else {
        o.a = 0.0;
        gl_FragColor = o;
      }
    } else {
      o.a = 0.0;
      gl_FragColor = o;
    }
  }


}%
