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
protected _render (render: IBatcher) {
render.commitComp(this, this.renderData, this._spriteFrame, this._assembler, null);
}
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
Please kindly bare with me here since I’m very new to shader coding
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
pandamicro:
#if __VERSION__ >= 300
It still didn’t work, sadly.
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