版本:3.8.4
需求:做一个适用于spine的shader特效:让spine动效从上往下动态置灰
shader代码:
CCEffect %{
techniques:
- name: opaque
passes:- vert: vs:vert
frag: fs:frag
blendState:
targets:- blend: true
blendSrc: src_alpha
blendDst: one_minus_src_alpha
rasterizerState:
cullMode: none
properties:
greyPercent: {value: 0.0, editor: {range:[0.0, 1.0, 0.01], slide: true, tooltip: “置灰百分比”}}
depthStencilState:
depthTest: false
depthWrite: false
}%
- blend: true
- vert: vs:vert
CCProgram vs %{
precision highp float;
#include
#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 uv;
out float worldY;
vec4 vert() {
vec4 pos = vec4(a_position, 1);
vec4 worldPos = pos;
#if USE_LOCAL
worldPos = cc_matWorld * pos;
pos = worldPos;
#endif
vec4 screenPos = cc_matViewProj * pos;
uv = a_texCoord;
v_color = a_color;
worldY = screenPos.y / screenPos.w;
return screenPos;
}
}%
CCProgram fs %{
precision highp float;
#include
in vec2 uv;
in vec4 v_color;
in float worldY; // 接收屏幕空间的Y坐标
uniform GreyParams{
vec4 blendColor;
float greyPercent;
float fullColor;
};
vec4 frag() {
vec4 color = texture(cc_spriteTexture, uv);
color *= v_color;
float greyProgress = (worldY + 1.0) * 0.5; // 将-1到1映射到0到1
greyProgress = 1.0 - greyProgress; // 翻转,使顶部为1.0,底部为0.0
float edgeSoftness = 0.1;
float greyFactor = smoothstep(greyPercent - edgeSoftness, greyPercent + edgeSoftness, greyProgress);
float gray = dot(color.rgb, vec3(0.299, 0.587, 0.114));
color.rgb = mix(vec3(gray), color.rgb, greyFactor);
return color;
}
}%
描述:
通过外部修改greyPercent【0,1】动态控制置灰的百分比。
问题:
现在置灰效果是有了,但是worldY好像控制的是整个屏幕的Y坐标所以最终greyPercent控制的是整个屏幕的占比,greyPercent=0.5的时候,整个屏幕50%的上部分绑定了这个shader的spine(加上10%的羽化部分一共60%)都是置灰的状态,而我想要的是基于这个spine自己本身的高度比做置灰。但是我不知道要怎么拿到这个值去修改。
另外如果我直接通过uv.y的话他是按照spine的图集顺序置灰的所以也不行