New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

renderTexture->saveToFile() bugged for image alpha values #18193

Closed
hotcoco11 opened this Issue Aug 27, 2017 · 12 comments

Comments

Projects
None yet
3 participants
@hotcoco11

hotcoco11 commented Aug 27, 2017

  • cocos2d-x version: 3.15.1
  • devices test on: Windows

Steps to Reproduce:

Take any image that has transparent pixels in it and try to save it as a png using renderTexture. The transparent pixels will get added with the background color of the renderTexture despite setting the background's alpha channel to zero with clear(0,0,0,0). Below is the code I used:

auto sprite = Sprite::create("original.png");
auto renderTexture = RenderTexture::create(64, 64, Texture2D::PixelFormat::RGBA8888);
renderTexture->clear(0,0,0,0);
renderTexture->begin();
sprite->setAnchorPoint(Vec2(0, 0));
sprite->setPosition(Vec2(0,0));
sprite->visit();
renderTexture->end();
renderTexture->saveToFile("rendertexture.png", Image::Format::PNG);

So in the above case because I cleared with rgba(0,0,0,0), my transparent pixels will end up being darker. One would assume that having an alpha of zero shouldn't change the image at all.

I posted an example image on the forums:
http://discuss.cocos2d-x.org/t/rendertexture-savetofile-bugged-for-image-alpha-values/38810

@KAMIKAZEUA

This comment has been minimized.

Show comment
Hide comment
@KAMIKAZEUA

KAMIKAZEUA Aug 27, 2017

@minggo I've reproduced this bug in the latest cocos.

KAMIKAZEUA commented Aug 27, 2017

@minggo I've reproduced this bug in the latest cocos.

@KAMIKAZEUA

This comment has been minimized.

Show comment
Hide comment

@minggo minggo added this to the next milestone Sep 7, 2017

@KAMIKAZEUA

This comment has been minimized.

Show comment
Hide comment
@KAMIKAZEUA

KAMIKAZEUA Sep 26, 2017

Hey @minggo currently I'm start using RenderTexture in my game and it's really broken.
It's renders that artefacts to my image. Thats really like urgent, because for other people RenderTexture is really used component.
Just take code and images to test from this post

KAMIKAZEUA commented Sep 26, 2017

Hey @minggo currently I'm start using RenderTexture in my game and it's really broken.
It's renders that artefacts to my image. Thats really like urgent, because for other people RenderTexture is really used component.
Just take code and images to test from this post

@KAMIKAZEUA

This comment has been minimized.

Show comment
Hide comment
@KAMIKAZEUA

KAMIKAZEUA Dec 3, 2017

@minggo

Just want to assume this bug and add something.

For image:
1

Use code:

Create a simple HelloWorld project add transparent image bellow and add this code.

auto sprite = Sprite::create("1.png");
sprite->setPosition(Vec2(visibleSize.width * 0.5, visibleSize.height * 0.5));
addChild(sprite);
    
auto render = RenderTexture::create(visibleSize.width, visibleSize.height);
render->begin();
visit();
render->end();
render->saveToFile("rendered.png");

I have this scene:

sceme

Result rendered image of this scene:

rendered

Take a closer look:

screen shot

Notice that not only transparent image but text has some artefacts.

Even more:

Add this code on top of code posted before:

auto gradient = LayerGradient::create(Color4B(100, 250, 100, 255.0), Color4B(5, 5, 5, 0.0));
gradient->setContentSize(visibleSize);
addChild(gradient);

Result of rendered image compare to actual scene with gradient:

Left - rendered. Right - actual scene.

screen shot 1

Notice - rendered gradient is different than actual saved file.

It’s like has some transparency where it should’t have. Top of gradient isn’t transparent, but on rendered image - it’s transparent:

screen shot

KAMIKAZEUA commented Dec 3, 2017

@minggo

Just want to assume this bug and add something.

For image:
1

Use code:

Create a simple HelloWorld project add transparent image bellow and add this code.

auto sprite = Sprite::create("1.png");
sprite->setPosition(Vec2(visibleSize.width * 0.5, visibleSize.height * 0.5));
addChild(sprite);
    
auto render = RenderTexture::create(visibleSize.width, visibleSize.height);
render->begin();
visit();
render->end();
render->saveToFile("rendered.png");

I have this scene:

sceme

Result rendered image of this scene:

rendered

Take a closer look:

screen shot

Notice that not only transparent image but text has some artefacts.

Even more:

Add this code on top of code posted before:

auto gradient = LayerGradient::create(Color4B(100, 250, 100, 255.0), Color4B(5, 5, 5, 0.0));
gradient->setContentSize(visibleSize);
addChild(gradient);

Result of rendered image compare to actual scene with gradient:

Left - rendered. Right - actual scene.

screen shot 1

Notice - rendered gradient is different than actual saved file.

It’s like has some transparency where it should’t have. Top of gradient isn’t transparent, but on rendered image - it’s transparent:

screen shot

@minggo

This comment has been minimized.

Show comment
Hide comment
@minggo

minggo Dec 4, 2017

Contributor

it is in my task list, i will take a look after fixing some other issues

Contributor

minggo commented Dec 4, 2017

it is in my task list, i will take a look after fixing some other issues

@KAMIKAZEUA

This comment has been minimized.

Show comment
Hide comment
@KAMIKAZEUA

KAMIKAZEUA Dec 4, 2017

Thats just currently deal breaker for me. Before that, I've found way to not use RenderTexture in my game. But currently I have situation where I can't not to use it, but it's broken.

KAMIKAZEUA commented Dec 4, 2017

Thats just currently deal breaker for me. Before that, I've found way to not use RenderTexture in my game. But currently I have situation where I can't not to use it, but it's broken.

@minggo

This comment has been minimized.

Show comment
Hide comment
@minggo

minggo Dec 5, 2017

Contributor

The default blend function of Sprite is BlendFunc::ALPHA_NON_PREMULTIPLIED, which will blend with background. So you should change the blend function before visit, such as


auto sprite = Sprite::create("original.png");
auto renderTexture = RenderTexture::create(64, 64, Texture2D::PixelFormat::RGBA8888);
renderTexture->clear(0,0,0,0);
renderTexture->begin();
sprite->setAnchorPoint(Vec2(0, 0));
sprite->setPosition(Vec2(0,0));
sprite->setBlendFunc({GL_ONE, GL_ZERO});   ---》 change the blend function
sprite->visit();
renderTexture->end();
renderTexture->saveToFile("rendertexture.png", Image::Format::PNG);

And you may change to default blend function after rendering into render texture. Because saveToFile is finished in next frame, so you'd better change to use original blend function in the call back of saveToFile.

Contributor

minggo commented Dec 5, 2017

The default blend function of Sprite is BlendFunc::ALPHA_NON_PREMULTIPLIED, which will blend with background. So you should change the blend function before visit, such as


auto sprite = Sprite::create("original.png");
auto renderTexture = RenderTexture::create(64, 64, Texture2D::PixelFormat::RGBA8888);
renderTexture->clear(0,0,0,0);
renderTexture->begin();
sprite->setAnchorPoint(Vec2(0, 0));
sprite->setPosition(Vec2(0,0));
sprite->setBlendFunc({GL_ONE, GL_ZERO});   ---》 change the blend function
sprite->visit();
renderTexture->end();
renderTexture->saveToFile("rendertexture.png", Image::Format::PNG);

And you may change to default blend function after rendering into render texture. Because saveToFile is finished in next frame, so you'd better change to use original blend function in the call back of saveToFile.

@minggo minggo closed this Dec 5, 2017

@KAMIKAZEUA

This comment has been minimized.

Show comment
Hide comment
@KAMIKAZEUA

KAMIKAZEUA Jan 4, 2018

@minggo If I have a design in my game so I can't change sprite->setBlendFunc?

Just simple fact: I’m using RenderTexture for some sprites and got artifacts on final image.
I’m not sure, but in some old previous versions I haven’t faced with this problem for same situation with my same game. Other users reported, that cocos v2 has no this problem.
Also, I can’t change blending of sprite to visit, by my game design. How to solve this?
This is an issue.

KAMIKAZEUA commented Jan 4, 2018

@minggo If I have a design in my game so I can't change sprite->setBlendFunc?

Just simple fact: I’m using RenderTexture for some sprites and got artifacts on final image.
I’m not sure, but in some old previous versions I haven’t faced with this problem for same situation with my same game. Other users reported, that cocos v2 has no this problem.
Also, I can’t change blending of sprite to visit, by my game design. How to solve this?
This is an issue.

@KAMIKAZEUA

This comment has been minimized.

Show comment
Hide comment
@KAMIKAZEUA

KAMIKAZEUA Apr 14, 2018

@minggo any comments? I can't change BlendFunc before visit. Also, I'm visit a Node but not a just some single Sprite, and on my Node there are a lot of other objects: LayerGradient, ClippingNode, 'Sprite' s and LayerColor and more. Some of them have a children added.

upd: even with just tested 1 sprite with mask, I'm getting this bug. Disable blend not helped me.

KAMIKAZEUA commented Apr 14, 2018

@minggo any comments? I can't change BlendFunc before visit. Also, I'm visit a Node but not a just some single Sprite, and on my Node there are a lot of other objects: LayerGradient, ClippingNode, 'Sprite' s and LayerColor and more. Some of them have a children added.

upd: even with just tested 1 sprite with mask, I'm getting this bug. Disable blend not helped me.

@KAMIKAZEUA

This comment has been minimized.

Show comment
Hide comment
@KAMIKAZEUA

KAMIKAZEUA Jun 28, 2018

@minggo @drelaptop this issue is not fixed.

Other developers faced this same problem, see details in this post:
https://discuss.cocos2d-x.org/t/rendertexture-savetofile-bugged-for-image-alpha-values/38810/6

@minggo with ClippingNode your fix with disabling blendfunc does not work.

KAMIKAZEUA commented Jun 28, 2018

@minggo @drelaptop this issue is not fixed.

Other developers faced this same problem, see details in this post:
https://discuss.cocos2d-x.org/t/rendertexture-savetofile-bugged-for-image-alpha-values/38810/6

@minggo with ClippingNode your fix with disabling blendfunc does not work.

@minggo

This comment has been minimized.

Show comment
Hide comment
@minggo

minggo Jun 28, 2018

Contributor

Ok, it can be another issue.

Contributor

minggo commented Jun 28, 2018

Ok, it can be another issue.

@KAMIKAZEUA

This comment has been minimized.

Show comment
Hide comment
@KAMIKAZEUA

KAMIKAZEUA Jun 28, 2018

@minggo Yea, that’s the same problem, this issue was closed wrongly, reopen it and assign to drela.

KAMIKAZEUA commented Jun 28, 2018

@minggo Yea, that’s the same problem, this issue was closed wrongly, reopen it and assign to drela.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment