游戏引擎 —— cocos creator 3.52
此动效给动态修改尺寸的图片增加一层刷光的效果,直接贴代码
CCEffect %{techniques:- passes:- vert: sprite-vs:vertfrag: sprite-fs:fragdepthStencilState:depthTest: falsedepthWrite: falseblendState:targets:- blend: trueblendSrc: src_alphablendDst: one_minus_src_alphablendDstAlpha: one_minus_src_alpharasterizerState:cullMode: noneproperties:alphaThreshold: { value: 0.5 }# 自定义参数# 光束颜色lightColor: {value: [1.0, 1.0, 0.0, 1.0], editor: { type: color,tooltip: "光束颜色"} }# 光束中心点坐标lightCenterPoint: {value: [0.2, 0.2],editor: {tooltip: "光束中心点坐标" }}# 光束倾斜角度lightAngle: {value: 36.0,editor: {tooltip: "光束倾斜角度",range: [0.0, 360],} }# 光束宽度lightWidth: {value: 0.2,editor: {tooltip: "光束宽度"}}# 启用光束渐变enableGradient: {value: 1.0,editor: {tooltip: "是否启用光束渐变。0:不启用,非0:启用"}}# 裁剪掉透明区域上的光cropAlpha: {value: 1.0,editor: {tooltip: "是否裁剪透明区域上的光。0:不启用,非0:启用"}}# 是否启用迷雾效果enableFog: {value: 0.0,editor: {tooltip: "是否启用迷雾效果。0:不启用,非0:启用"}}# 横向自动扫光速度crossSpeed: {value: 0.0,editor: {tooltip: "横向自动扫光速度。0:不自动,非0:自动扫光的速度"}}# 纵向自动扫光速度verticalSpeed: {value: 0.0,editor: {tooltip: "纵向自动扫光速度:不自动,非0:自动扫光的速度"}}
}%CCProgram sprite-vs %{precision highp float;#include <cc-global>#include <output>#if USE_LOCAL#include <cc-local>#endifin vec3 a_position;in vec2 a_texCoord;in vec4 a_color;out vec4 v_color;out vec2 v_uv0;#if USE_TEXTUREin vec2 a_uv0;#endifvec4 vert () {vec4 pos = vec4(a_position, 1);#if USE_LOCALpos = cc_matWorld * pos;#endif#if USE_PIXEL_ALIGNMENTpos = cc_matView * pos;pos.xyz = floor(pos.xyz);pos = cc_matProj * pos;#elsepos = cc_matViewProj * pos;#endif#if USE_TEXTUREv_uv0 = a_uv0;#endifv_color = a_color;v_uv0 = a_texCoord;return pos;}
}%CCProgram sprite-fs %{precision highp float;#include <embedded-alpha>#include <alpha-test>#include <cc-global>in vec4 v_color;#if USE_TEXTUREin vec2 v_uv0;#pragma builtin(local)layout(set = 2, binding = 11) uniform sampler2D cc_spriteTexture;#endif#if ENABLE_LIGHTuniform PROPERTIES {// 光束颜色vec4 lightColor;// 光束中心点坐标vec2 lightCenterPoint;// 光束倾斜角度float lightAngle;// 光束宽度float lightWidth;// 启用光束渐变// ps:编辑器还不支持 bool 类型的样子,因此用float来定义float enableGradient;// 裁剪掉透明区域上的光// ps:编辑器还不支持 bool 类型的样子,因此用float来定义float cropAlpha; // 是否启用迷雾效果// ps:编辑器还不支持 bool 类型的样子,因此用float来定义float enableFog;// 横向自动扫光速度// ps:编辑器还不支持 bool 类型的样子,因此用float来定义float crossSpeed;// 纵向自动扫光速度// ps:编辑器还不支持 bool 类型的样子,因此用float来定义float verticalSpeed;};/*** 添加光束颜色*/vec4 addLightColor(vec4 textureColor, vec4 lightColor, vec2 lightCenterPoint, float lightAngle, float lightWidth) {if(crossSpeed > 0.0){float time = cc_time.x * crossSpeed;lightCenterPoint.x = time - floor(time / (1.0 + lightWidth)) * (1.0 + lightWidth);}if(verticalSpeed > 0.0){float time = cc_time.x * verticalSpeed;lightCenterPoint.y = time - floor(time / (1.0 + lightWidth)) * (1.0 + 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.5, textureColor.a);}// 裁剪掉光束范围外的uv(迷雾效果)if (!bool(enableFog)) {a *= step(dis, lightWidth * 0.5);}// 加入从中心往外渐变的效果if (bool(enableGradient)) {a *= 1.0 - dis / (lightWidth * 0.5);a*=lightColor.a;}// 计算出扩散范围内,不同 uv 对应的实际扩散颜色值vec4 finalLightColor = lightColor * a;// 混合颜色:在原始图像颜色上叠加扩散颜色return textureColor * textureColor.a + finalLightColor;}#endifvec4 frag () {vec4 o = vec4(1, 1, 1, 1);#if USE_TEXTUREo *= CCSampleWithAlphaSeparated(cc_spriteTexture, v_uv0);#if CC_USE_ALPHA_ATLAS_TEXTUREo.a *= CCSampleWithAlphaSeparated(cc_spriteTexture, v_uv0 + vec2(0, 0.5)).r;#endif#endifo *= v_color;ALPHA_TEST(o);#if ENABLE_LIGHTo = addLightColor(o, lightColor, lightCenterPoint, lightAngle, lightWidth);#endifreturn o;}
}%
编辑器:
勾选ENABLE LIGHT开关,可以设置刷光的颜色、位置、角度、刷光的宽度等等属性,根据实际需求选择;
增加横向和纵向自动扫光速度,为0时不会自动,大于0时会根据设置的值播放动画,代码中也可以动态修改该参数
代码播放:
//先获取到材质,如果是编辑器绑好的只需要获取cc.Sprite组件下的customMaterial就能获取到this.sprArrowMat = this.sprArrow.getComponent(cc.Sprite).customMaterial;//在计时器里面动态修改Center Pointupdate(dt){if (this.sprArrowMat ) {if (this.sprArrowChgValue <= -0.1) {this.sprArrowChgValue = 1;}else {this.sprArrowChgValue -= dt / 2;}//动态设置刷光的位置this.sprArrowMat.setProperty("lightCenterPoint", cc.v2(0, this.sprArrowChgValue));//动态设置颜色,渐变效果this.sprArrowMat.setProperty("lightColor", cc.color(255, 200 - 120 * this.sprArrowChgValue ,0));}}