cocos creator shader如何获取spine自身的高度(非纹理非屏幕高)

版本: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
        }%

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的图集顺序置灰的所以也不行

1赞

如果由顶点属性或者贴图来提供信息不现实的话,可以考虑用本地坐标的Y值来计算,此时需要得知最大、最小的本地Y值,可以通过给头脚放置挂点获取。

实际中还可以根据实际情况简化和烘培这个最大最小值的获取。

感谢提供思路,通过这种思路修改了一下,感觉是可行的。但是在update设置灰度百分比不知道为什么不生效。

已经解决了,参考了这个链接的做法动态修改spine属性不生效

这个问题的本质是spine组件渲染中使用的材质是cache里的,而非组件所引用的模板材质,这样改原生平台应该还是有问题的,原生平台的cache没有绑定到js供访问。
如果你使用的是3.8.x版本,可以看看是否修复,以下的版本应该都是有问题的。