Unable to apply shader properly

Version 2.4.0

I created a custom shader and applied to a sprite (right) in ide

however, in preview/build, it looks like this

is there anything I need to set besides applying the material? or is there any differences between ide and preview?


if I set the spriteframe to be unpackable it will work properly
image.spriteFrame._texture.packable = false;
but what if I need to use atlas and shader on the same spriteframe at the same time?

If you want to use atlases you have to calculate sprites coords in an atlas.

For example:

private material: cc.Material

onLoad() {
        material.setProperty('u_trimPoint', cc.v2(this.cardSprite.spriteFrame.getRect().x, this.cardSprite.spriteFrame.getRect().y))
        material.setProperty('u_spriteSize', cc.v2(this.cardSprite.spriteFrame.getRect().width, this.cardSprite.spriteFrame.getRect().height))
        material.setProperty('u_atlasSize', cc.v2(this.cardSprite.spriteFrame.getTexture().width, this.cardSprite.spriteFrame.getTexture().height))
void main () {
    vec2 st = v_uv0;
    st *= u_atlasSize;
    st -= u_trimPoint;
    st /= u_spriteSize;

can you explain what this part does?

void main () {
    vec2 st = v_uv0;
    st *= u_atlasSize;
    st -= u_trimPoint;
    st /= u_spriteSize;

It almost worked, except it shows the whole atlas inside the sprite (please ignore the words on top)

Please show your shader code. It will be easier to help

This part runs in build
this.images[0] is a sprite component
“m101” is the spriteframe I want to use

cc.resources.load(`PokerCards/cards`, cc.SpriteAtlas, (err, atlas: cc.SpriteAtlas) => {
    let image = atlas.getSpriteFrame("m101");
    this.images[0].spriteFrame = image;
    let imageRect= image.getRect();
    this.images[0].getMaterial(0).setProperty("u_trimPoint", cc.v2(imageRect.x, imageRect.y));
    this.images[0].getMaterial(0).setProperty("u_spriteSize", cc.v2(imageRect.width, imageRect.height));
    this.images[0].getMaterial(0).setProperty("u_atlasSize", cc.v2(image.getTexture().width, image.getTexture().height));

fragment shader

CCProgram frag-shader %{
  precision highp float;

  #include <alpha-test>

  in vec4 v_color;

      in vec2 v_uv0; //coordinate of processing point?
      uniform sampler2D texture;

  uniform Round {
    float radius;
    float feather;
    vec2 u_trimPoint;
    vec2 u_spriteSize;
    vec2 u_atlasSize;

  void main() {
    vec2 center = vec2(0.5, 0.5);

    vec2 st = v_uv0;
    st *= u_atlasSize;
    st -= u_trimPoint;
    st /= u_spriteSize;

    float dis = distance(st, center);

    if (dis > radius) { discard; }

    vec4 newColor = vec4(1.0, 1.0, 1.0, 1.0);
    if (feather > 0.0) { newColor.a = smoothstep(radius, radius - feather, dis); }
    newColor *= texture(texture, st);
    newColor *= v_color;
    gl_FragColor = newColor;


Change only this line:

newColor *= texture(texture, st);

To this:

newColor *= texture(texture, v_uv0);

Unfortunately, I am a not native speaker, so I can not clearly explain of this.

no you helped me a lot. I also just found out the solution. I will post the updated code with comments for others who are interested later

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.