What's wrong with blend function?

Hi Everyone!

I have tested this code on the cocos2d-x 2.2.2 (left part of picture) and cocos2d-x 3.0rc0 (right part of picture).

auto back = cocos2d::CCSprite::create("back.png");
back->setPosition(CVisibleRect::Center());
addChild(back);

auto test = cocos2d::CCSprite::create("test.png");
test->setPosition(CVisibleRect::Center());
test->setBlendFunc({ GL_ONE, GL_ONE_MINUS_SRC_ALPHA });
addChild(test);

{ GL_ONE, GL_ONE_MINUS_SRC_ALPHA } - is a ALPHA_PREMULTIPLIED mode.
Also, different result and for other blenfFunc.

Example of wrong blending.

Why on different versions of the engine different result of the same code?


Config.txt.zip (0.5 KB)


Diff.png (149.4 KB)

any ideas?

Who can say anything?

This seems to be a blocker for me.
Thanks for reporting it.

Hi, PNG file does not support premultiplied alpha internally.
In version 2.x, PNG file are force read as premultiplied alpha by some extra processing.
In V3.x, it has been removed. So PNG file are read as non premultiplied alpha image. Which is not the same as V2.x.
If you set a manual premultiplied alpha blend mode for sprite create from png file, it will be wrong.
It is better set blend mode given the hasPremultipliedAlpha status of Texture2D of the sprite.

so there’s no way for png to use those blend func? I tried to use some patch code found from github to solve the problem, but if I do so, the label’s opacity( whose parent is sprite and need parent’s opacity cascade ) will become weird.

below is the code I found from https://github.com/cocos2d/cocos2d-x/pull/6954/files:

    CCASSERT(_renderFormat == Texture2D::PixelFormat::RGBA8888, "The pixel format should be RGBA8888!");
unsigned int* fourBytes = (unsigned int*)_data;
for(int i = 0; i < _width * _height; i++)
{
    unsigned char* p = _data + i * 4;
    fourBytes[i] = CC_RGB_PREMULTIPLY_ALPHA(p[0], p[1], p[2], p[3]);
}

_preMulti = true;