cocos3 shader怎么传入vec4数组

我是这样,会报错说: [Scene] Pass: setUniform is invoked with incompatible uniform data type for binding 1, expected type is FLOAT4。

我这个shader主要是想创建一块遮罩,但遮罩里面允许一部分矩形不被遮住当做高亮。之前只支持一块地方,现在我想支持多块。于是把center从vec2 center改成了vec4 center[6](其他帖子那里看来说要改成vec4…),rect同样地从vec2改成了center[6]。数组长度写6也只是随便限制一下。

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:
        # 方形区域的中心 (UV 坐标,范围 0~1)
        center: {
          value: [0, 0, 0, 0],
          editor: { tooltip: "方形高亮中心" }
        }
        # 方形区域的 “宽度 & 高度” (UV 单位,范围 0~1)
        rectSize: {
          value: [0, 0, 0, 0],
          editor: { tooltip: "方形高亮尺寸 (UV 单位, e.g. [0.4,0.3])" }
        }
        ui_resolution: {
          value: [1080, 1920],
          editor: { tooltip: "屏幕分辨率 (单位:像素)", type: vec2 }
        }
        # 整个遮罩的颜色 (通常黑色半透明)
        overlayColor: { 
          value: [0.0, 0.0, 0.0, 0.7],
          editor: { tooltip: "遮罩颜色 RGBA", type: color }
        }
        # 羽化宽度
        blur: {
          value: 10,
          editor: { tooltip: "羽化宽度 (UV 单位)" }
        }
}%
CCProgram sprite-vs %{
  precision highp float;
  #include <builtin/uniforms/cc-global>
  in vec3 a_position;
  in vec2 a_texCoord;
  out vec2 v_uv0;
  out vec4 v_color;
  vec4 vert () {
    v_uv0    = a_texCoord;
    v_color  = vec4(1.0);
    return cc_matViewProj * vec4(a_position, 1.0);
  }
}%
CCProgram sprite-fs %{
  precision highp float;
  #include <builtin/internal/alpha-test>
  in vec2 v_uv0;
  in vec4 v_color;
  #if USE_TEXTURE
    #pragma builtin(local)
    layout(set = 2, binding = 11) uniform sampler2D cc_spriteTexture;
  #endif
  uniform ARGS {
    vec4 center[6];      // 高亮中心(单位:像素)
    vec4 rectSize[6];    // 高亮区域尺寸(单位:像素)
    vec4 overlayColor;   // 遮罩颜色 RGBA
    vec2 ui_resolution;  // 屏幕分辨率(单位:像素)
    float blur;          // 羽化宽度(单位:像素)
  };
  vec4 frag () {
    // 当前像素的屏幕坐标(归一化到 0~1)
    vec2 st = gl_FragCoord.xy / ui_resolution;
    float alpha = 0.0;
    // 遍历每个高亮区域
    for (int i = 0; i < 6; i++) { // 假设最多支持6个高亮区域
      // 归一化坐标
      vec2 centerUV = center[i].xy / ui_resolution;
      vec2 rectSizeUV = rectSize[i].xy / ui_resolution;
      // 计算当前高亮区域的遮罩
      vec2 p = st - centerUV;
      vec2 halfSize = rectSizeUV * 0.5;
      vec2 dist = abs(p) - halfSize;
      vec2 cd = max(dist, vec2(0.0));
      float outsideDist = length(cd);
      float t = smoothstep(0.0, blur / max(ui_resolution.x, ui_resolution.y), outsideDist);
      alpha = max(alpha, overlayColor.a * t); // 合并所有高亮区域的效果
    }
    // 颜色贴图
    vec4 baseColor = vec4(1.0); // 默认纯白
    #if USE_TEXTURE
      baseColor = texture(cc_spriteTexture, v_uv0) * v_color;
    #endif
    return vec4(overlayColor.rgb, alpha);
  }
}%

center[6]这是啥意思

长度为六的数组,这个shader的解释补充在前面啦,麻烦大佬看看

可以看看这个,具体没试过

你在 properties 里定义的就是一个 vec4 而已,并非什么 6 个元素的数组

uniform 里应该写 vec4 center; 就行了而不是 vec4 center[6];

rectSize 同理.

你这个 vec4 xxx[6] 的写法很诡异,即使是「6个(float 类型)元素的数组」也应该写做 float xxx[6]

我试了不行

因为我要的实际上是个vec2的数组,但是uniform里面定义了vec4之后貌似就不让用vec2数组了,所以我用了vec4数组。
properties里面理论上用[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],但我试过还会多一个报错是这个type error: Error EFX3302: illegal property declaration for ‘center’: wrong array length,用[0,0,0,0]反而没错的。

谁说的定义了vec4之后貌似就不让用vec2数组了?:joy: 你是咋定义的?

你应该是定义顺序不对违反了 UBO 内存布局策略吧?

uniform vec2 center[6]: array UBO members need to be 16-bytes-aligned to avoid implicit padding
是的,但我找不到合适的顺序……不过用vec4还是vec2应该不影响都能实现吧

  uniform ARGS {
    vec4 overlayColor;   // 遮罩颜色 RGBA
    vec2 center[6];      // 高亮中心(单位:像素)
    vec2 rectSize[6];    // 高亮区域尺寸(单位:像素)
    vec2 ui_resolution;  // 屏幕分辨率(单位:像素)
    float blur;          // 羽化宽度(单位:像素)
  };

mat我去学习一下……我也是参考这里的链接,人家貌似就用了vec4数组没啥问题。
我的“vec4 之后就不支持 vec2 数组”表述的不准确,我用vec2数组的情况下尝试了各种,找不到合适的顺序。

你那链接里的是 Cocos 2.X 的语法,你一楼写的语法明显是 3.X 的,互不兼容的

嗯,2和3这点不兼容我就不知道了嘛…所以发帖注明是3.X的版本来问了

我用3.8.7试了,为啥没报错? 虽然没效果,实现有问题而已。

我用的3.8.5= =我也升级下试试吧

你参数怎么设置的? 是编辑器里就报错?还是预览报错?还是真机?

我在 3.8.6 也试了下,确实也没报错……



编辑器里就报错,运行的时候也粉红的

材质面板也确实可以支持定义6组 vec4,看来3.x也是支持 vec 数组的

发现没报错的原因了,你没开USE_TEXTURE