临时使用方法
1.描边的用
代码中将num的数值改为1.0
const float num = 1.0;
2.外发光的用法
代码中将num的数值改为20.0
const float num = 20.0;
完整Effect代码如下:
CCEffect %{
techniques:
- passes:
- vert: sprite-vs:vert
frag: sprite-fs:frag
depthStencilState:
depthTest: false
depthWrite: false
blendState:
targets:
- blend: true
blendSrc: src_alpha
blendDst: one_minus_src_alpha
blendDstAlpha: one_minus_src_alpha
rasterizerState:
cullMode: none
properties:
alphaThreshold: { value: 0.5 }
# 自定义参数
colorLight : { value : [1.0,0.0,0.0,1.0] , editor: { type: color }}
m_alpha : { value : 0.5 , editor : { slide : true , range : [0.00,1], step: 0.1} }
outlineNum : { value : 1.0 , editor : { slide : true , range : [1.0,20], step: 1.0} }
outlineSlider : { value : 0.1 , target : outlineW , editor : { slide : true , range : [0.00,10], step: 0.01} }
textureSize: { value: [100.0, 100.0], editor: { tooltip: "纹理尺寸 " } }
}%
CCProgram sprite-vs %{
precision highp float;
#include <builtin/uniforms/cc-global>
#if USE_LOCAL
#include <builtin/uniforms/cc-local>
#endif
in vec3 a_position;
in vec2 a_texCoord;
in vec4 a_color;
out vec4 v_color;
out vec2 v_uv0;
#if USE_TEXTURE
in vec2 a_uv0;
#endif
vec4 vert () {
vec4 pos = vec4(a_position,1.0);
pos = cc_matProj * cc_matView * pos;
v_uv0 = a_texCoord;
v_color = a_color;
return pos;
}
}%
CCProgram sprite-fs %{
precision highp float;
#include <builtin/internal/embedded-alpha>
#include <builtin/internal/alpha-test>
in vec4 v_color;
in vec2 v_uv0;
#if USE_TEXTURE
#pragma builtin(local)
layout(set = 2, binding = 11) uniform sampler2D cc_spriteTexture;
#endif
uniform Constant {
vec4 colorLight;
float m_alpha;
float outlineNum;
vec2 textureSize;
float outlineW;
};
#define SAMPLE 128
#define PI 3.14159265359
float getBackArea(float ass) {
float wight = textureSize.x;
float hight = textureSize.y;
float uv_x = v_uv0.x * wight;
float uv_y = v_uv0.y * hight;
float left_x = (uv_x -ass)/wight;
float left_y = (uv_y -ass)/hight;
float right_x = (uv_x +ass)/wight;
float right_y = (uv_y +ass)/hight;
float left_x_h = (uv_x -ass)/wight;
float left_y_h = (uv_y -ass)/hight;
float right_x_h = (uv_x +ass)/wight;
float right_y_h = (uv_y +ass)/hight;
// float a1 = texture(cc_spriteTexture,vec2(v_uv0.x ,left_y)).a*1.0;
// float a2 = texture(cc_spriteTexture,vec2(v_uv0.x, right_y)).a*1.0;
// float a3 = texture(cc_spriteTexture,vec2(left_x, v_uv0.y)).a*1.0;
// float a4 = texture(cc_spriteTexture,vec2(right_x, v_uv0.y)).a*1.0;
// float a5 = texture(cc_spriteTexture,vec2(right_x_h , right_y_h )).a*1.0;
// float a6 = texture(cc_spriteTexture,vec2(left_x_h , right_y_h )).a*1.0;
// float a7 = texture(cc_spriteTexture,vec2(right_x_h ,left_y_h )).a*1.0;
// float a8 = texture(cc_spriteTexture,vec2(left_x_h , left_y_h )).a*1.0;
// float sum = a1+a2+a3+a4+a5+a6+a7+a8;
float angle =0.0;
float maxAlpha=0.0;
float sum=1.0;
for(int i=0;i<SAMPLE;i++){
angle+=1.0/float(SAMPLE)*2.0*PI; //角度每个循环增加一次,循环结束时角度为2PI,整好一个圆的角度,圆的精度由SAMPLE决定,SAMPLE越高圆越精细,但运算量也会增加
vec2 testPoint_uv=vec2((ass*cos(angle)+uv_x)/wight,(ass*sin(angle)+uv_y)/hight);//该点的圆上该角度的相对UV坐标
testPoint_uv=clamp(testPoint_uv,vec2(0,0),vec2(1,1));//加上该点的UV坐标变为绝对UV坐标
float tempAlpha=texture(cc_spriteTexture,testPoint_uv).a;//用绝对UV坐标从texture读取颜色,看它的透明度
maxAlpha=max(maxAlpha,tempAlpha);//把透明度结果保存起来
if(maxAlpha>0.8){
break;
}
sum += tempAlpha;
}
float isBack = clamp(sum, 0.0, 1.0)*1.0;
return clamp(maxAlpha, 0.0, 1.0);
}
vec4 frag () {
vec4 o = vec4(1, 1, 1, 1);
o *= texture(cc_spriteTexture, v_uv0);
o *= v_color;
float ass = outlineW;
if(outlineW == 0.0){
return o;
}
const float num = 1.0;
// 只有寬度大於0.02才發光
if(o.a <m_alpha){
float isBack =0.0;
float t=outlineNum;
float w = 1.0 / num;
float minBack = 1.0;
for (float i = 1.0; i <= num; i++) {
isBack = getBackArea(w*i*ass);
if(isBack>0.8){
// if(i==num){
isBack = min(w*(num-i+1.0)*isBack,minBack) ;
minBack = isBack ;
// }else{
// isBack = w*(num-i+1.0)*0.5 +0.5;
// }
break;
}else{
if(i==num){
isBack = min(w*(num-i+1.0)*isBack,minBack) ;
}
}
}
o = vec4( (1.0 - o.a)* colorLight.rgb , isBack);
}
ALPHA_TEST(o);
return o;
}
}%