[CC 3.7.3] Shader Error?

Hello Cocos Team.

I am having an issue with creating shader.
I couldn’t include the cc-local.

No errors were shown at the editor, but when I previewed I got the following error at the browser console.

CCProgram sprite-vs %{
....
  #if USE_LOCAL
    #include <builtin/uniforms/cc-local> // <-- Error Here

GL_INVALID_OPERATION: It is undefined behaviour to have a used but unbound uniform buffer.

Which uniform you need in cc-local and how did you use that ?

I’m just learning how a shader works.
So, I just copied from the built-in sprite effect file to mine.

Now, back to the issue, I think, only “cc_matWorld” is used from
#include <builtin/uniforms/cc-local>.

If I commented both of these lines, there were no error.
But, everything stopped working as intended.

Edit: mySprite.effect contents:

// Copyright (c) 2017-2020 Xiamen Yaji Software Co., Ltd.
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 }
}%

CCProgram sprite-vs %{
  precision highp float;
  #include <builtin/uniforms/cc-global>
  #if USE_LOCAL
    #include <builtin/uniforms/cc-local> // <-- Error Here
  #endif
  #if SAMPLE_FROM_RT
    #include <common/common-define>
  #endif
  in vec3 a_position;
  in vec2 a_texCoord;
  in vec4 a_color;

  out vec4 color;
  out vec2 uv0;

  vec4 vert () {
    vec4 pos = vec4(a_position, 1);

    #if USE_LOCAL
      pos = cc_matWorld * pos;
    #endif

    #if USE_PIXEL_ALIGNMENT
      pos = cc_matView * pos;
      pos.xyz = floor(pos.xyz);
      pos = cc_matProj * pos;
    #else
      pos = cc_matViewProj * pos;
    #endif

    uv0 = a_texCoord;
    #if SAMPLE_FROM_RT
      CC_HANDLE_RT_SAMPLE_FLIP(uv0);
    #endif
    color = a_color;

    return pos;
  }
}%

CCProgram sprite-fs %{
  precision highp float;
  #include <builtin/internal/embedded-alpha>
  #include <builtin/internal/alpha-test>

  in vec4 color;

  #if USE_TEXTURE
    in vec2 uv0;
    #pragma builtin(local)
    layout(set = 2, binding = 12) uniform sampler2D cc_spriteTexture;
  #endif

  vec4 frag () {
    vec4 o = vec4(1, 1, 1, 1);

    #if USE_TEXTURE
      o *= CCSampleWithAlphaSeparated(cc_spriteTexture, uv0);
      #if IS_GRAY
        float gray  = 0.2126 * o.r + 0.7152 * o.g + 0.0722 * o.b;
        o.r = o.g = o.b = gray;
      #endif
    #endif

    o *= color;
    ALPHA_TEST(o);
    return o;
  }
}%

Are you using this material with normal Sprite component ? If so, how did you activate USE_LOCAL for it ? by default it’s not activated in Sprite component because the commitComp was invoked without any transform data

In order for the local descriptor set to be bound, you must pass its node as the last parameter during the invocation.

Another thing to do is to set USE_LOCAL to its material like the following:

mat = sprite.getMaterialInstance(0);
mat.recompileShaders({ USE_LOCAL: true });

Then local descriptor set would be bound and updated in batcher2d.

The reason we haven’t supported USE_LOCAL mode for sprite is that the batcher 2d can only batch sprite draw calls while they share the same global matrix in the same vertex buffer.

Thanks for the reply :slight_smile:

Please kindly bare with me here since I’m very new to shader coding :stuck_out_tongue:

Another question: I couldn’t use “textureSize” or “texelFetch”.
Did I miss some libraries to be included?
I am getting this error:

‘texelFetch’ : no matching overloaded function found

They are available on WebGL2 (GLSL300) or native platforms, but not on WebGL1 (GLSL100), which platform did you test ?

https://wiki.davidl.me/view/WebGL

I’m using CC 3.7.3 on MacOS and I previewed it on Chrome web browser.

Make sure you are enabling WebGL2 module in feature cropping, and you also need to wrap your texelFetch code inside a version checker

#if __VERSION__ >= 300
#endif

If the problem persist, I want to know where you get this error, in chrome debugger or in project build phase.

1 Like

It still didn’t work, sadly. :frowning:

The error message shows that you are using it with unsupported parameter set, please check the type of all your parameters with the reference
https://registry.khronos.org/OpenGL-Refpages/gl4/html/texelFetch.xhtml

I will check and get back to you.

Another thing is I noticed that the FPS dropped after the shader was applied to some sprites. So, is there way to cache the rendered texture (including the shader effect) rather than recalculating the same thing every frame.

I’m not sure what you want to cache.
But depends on what you do with texelFetch it could be expensive, any read back from texture would be too. So if you heavily depending on this feature, it’s not a good idea