1 Star 4 Fork 1

dony / 学习笔记

Create your Gitee Account
Explore and code with more than 8 million developers,Free private repositories !:)
Sign up
This repository doesn't specify license. Please pay attention to the specific project description and its upstream code dependency when using it.
Clone or Download
cocoscreator用shader实现扫光效果.md 3.67 KB
Copy Edit Web IDE Raw Blame History
dony authored 2022-01-16 13:22 . shader实现扫光效果

用shader实现扫光效果

原理

1,画一个平行四边形

2,四边形的的水平中心线高亮,透明度=1.0,上下两边的透明度=0.0,从中心线向上下两边渐变过去

3,在原图像上叠加四边形, 混合原图像和四边形的颜色

实现功能

1,变换光束颜色

2,变换光束倾斜角度

3,变换光束的宽度

4,光速渐变

5,裁剪掉透明区域上的光

6,光束迷雾效果

实现步骤

根据要实现的功能,首先添加响应的属性如下:

uniform Light {
    // 光束颜色
    vec4 lightColor;

    // 光束中心点坐标
    vec2 lightCenterPoint;
    
    // 光束倾斜角度
    float lightAngle;

    // 光束宽度
    float lightWidth;

    // 启用光束渐变
    // ps:编辑器还不支持 bool 类型的样子,因此用float来定义
    float enableGradient;

    // 裁剪掉透明区域上的光
    // ps:编辑器还不支持 bool 类型的样子,因此用float来定义
    float cropAlpha;   

    // 是否启用迷雾效果
    // ps:编辑器还不支持 bool 类型的样子,因此用float来定义
    float enableFog;
};

添加光束颜色

/**
   * 添加光束颜色
   */
  vec4 addLightColor(vec4 textureColor, vec4 lightColor, vec2 lightCenterPoint, float lightAngle, float lightWidth) {
    // 边界值处理,没有宽度就返回原始颜色
    if (lightWidth <= 0.0) {
      return textureColor;
    }

    // 计算当前 uv 到 光束 的距离
    float angleInRadians = radians(lightAngle);

    // 角度0与非0不同处理
    float dis = 0.0;
    if (mod(lightAngle, 180.0) != 0.0) {
      // 计算光束中心线下方与X轴交点的X坐标
      // 1.0 - lightCenterPoint.y 是将转换为OpenGL坐标系,下文的 1.0 - y 类似
      float lightOffsetX = lightCenterPoint.x - ((1.0 - lightCenterPoint.y) / tan(angleInRadians));

      // 以当前点画一条平行于X轴的线,假设此线和光束中心线相交的点为D点
      // 那么
      // D.y = uv0.y
      // D.x = lightOffsetX + D.y / tan(angle)
      float dx = lightOffsetX + (1.0 - v_uv0.y) / tan(angleInRadians);

      // D 到当前 uv0 的距离就是
      // dis = |uv0.x - D.x|
      float offsetDis = abs(v_uv0.x - dx);

      // 当前点到光束中心线的的垂直距离就好算了
      dis = sin(angleInRadians) * offsetDis;
    } else {
      dis = abs(v_uv0.y - lightCenterPoint.y);
    }
    
    float a = 1.0 ;
    // 裁剪掉透明区域上的点光
    if (bool(cropAlpha)) {
      a *= step(0.01, textureColor.a);
    }

    // 裁剪掉光束范围外的uv(迷雾效果)
    if (!bool(enableFog)) {
      a *= step(dis, lightWidth * 0.5);
    }

    // 加入从中心往外渐变的效果
    if (bool(enableGradient)) {
      a *= 1.0 - dis / (lightWidth * 0.5);
    }

    // 计算出扩散范围内,不同 uv 对应的实际扩散颜色值
    vec4 finalLightColor = lightColor * a;

    // 混合颜色:在原始图像颜色上叠加扩散颜色
    return textureColor * textureColor.a + finalLightColor;
  }

在片元着色器片段的最后,把光速叠加上去

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);

    gl_FragColor = o;
    
    #if ENABLE_LIGHT
    gl_FragColor = addLightColor(gl_FragColor, lightColor, lightCenterPoint, lightAngle, lightWidth);
    #endif
}

主要代码上完后,通过开关改变这些属性,就可以看效果

Comment ( 0 )

Sign in to post a comment

1
https://gitee.com/dony1122/note.git
git@gitee.com:dony1122/note.git
dony1122
note
学习笔记
master

Search