游戲引擎 —— 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));}}