• Editor
  • Alpha strange on cocos2D for iphone

Related Discussions
...

Hi!

I set an alpha=2 on differents slots of the explosion in Spine, but this is the result on cocos2d:

Image supprimée en raison de l'absence de support de HTTPS. | Afficher quand même

it seems multiplied or additive, instead of a real alpha.

Any solution? Or what I am doing wrong?

Thanks!

Colors in spine-c are floats with a range of 0 to 1. You can use 2/255f.

5 jours plus tard

Thanks for your response Nate, but I think we're talking about different things.
I'll show you our problem with better screenshots

This is our explosion animation without Alpha:

Image supprimée en raison de l'absence de support de HTTPS. | Afficher quand même


This is what we need/want (photoshop):

Image supprimée en raison de l'absence de support de HTTPS. | Afficher quand même


But this is what we get setting alpha=2 in Slot Color option in Spine,
this is the same result as setting alpha via runtime:

Image supprimée en raison de l'absence de support de HTTPS. | Afficher quand même


What do you think about?

It's hard to see exactly what happens there. I can say that a Spine skeleton is made up of many images. When you draw, they will be blended with the background, but they will also blend on top of each other. If you want your whole skeleton to be translucent, making the images translucent won't be sufficient unless you draw only one image. When you draw the second translucent image on top, it will be blended with the first where they overlap.

What you can do is render your skeleton to a texture (an FBO aka frame buffer object), then render the resulting texture with alpha. Since the resulting texture is just one image, the entire thing can be drawn translucent.

This is a common approach taken for blending particles. You want the particles to blend with each other additively, but then you want to draw the result with normal blending on top of your game. If you draw the particles additively on top of your game and the background is a light color, the particles blended with the background will be mostly white.

You might want to use premultiplied alpha images. I'm not sure if this would help your problem though.

Shouldn't the runtime do this? I would've expected so.

In fact, how does it work in the editor then? does that not uses libgdx?

And why does the editor show us something we won't get without other advanced opengl programing (framebuffers aren't introduced in some opengl books at all, and appear late in all the books I've been reading).. I don't want to be a pain; but I think your answer of "go and make your own framebuffer" is not satisfactory - you guys should fix this.

It has to do with how OpenGL blending works. The editor will show the same issue. Eg, here I've reduced the alpha on spineboy's head and eyes slots to 25%:

Image supprimée en raison de l'absence de support de HTTPS. | Afficher quand même

First the head is drawn, then the eyes are drawn on top. The eyes are blended on top of the head, so the eyes appear more opaque. In you wanted to make spineboy as a whole translucent, you can't just set the alpha on the images, else you get the above. You would need to render him as normal to an FBO, then render the FBO as translucent. This way the spineboy images blend together as intended, and then the combined result is made translucent as a whole.

If it turned out to be very common, we could had some utilities to assist with rendering to an FBO. These would be runtime specific, since not all runtimes are OpenGL.

I guarantee it will be really common. Please supply utilities on cocos2d. you have ZERO idea how much I'm getting shafted over FBO's right now. I'm actually reading heavily on the subject but the last thing I want is to have to play with this kind of thing to get it to render correctly for the animations I have that depend on it..

As it goes I've already gone some way to making my own skelenton class with animation finish callbacks, chained animations, multiple animations, and I'm constantly adding features.

I'll put it on github tomorrow/thursday.. I think it'll make some people in cocos2d community happy. A very very nice addition would be code to fix this exact issue you talk about here.

If you could donate the code to me, I'd add a flag to my class - "useAlphaFriendlyRendering", so that it could be turned on or off when wanted.

Look.. no videos- no nasty comments. I can be nice too 🙂

Yes, I like the new infrid! :makeup: 😃

I'm sure cocos2d has something to help with using FBOs. Doing it with OpenGL is a bit of a pain. You'll love me pointing you to Java code, but libgdx has a nice FrameBuffer class. If you can ignore the Java, it has all the GL calls necessary. However, I'm sure whatever cocos2d has is much easier to use than direct OpenGL. I haven't done it in cocos2d so it would take some exploring and there are tons of others things to do at the moment. Unless you are shipping soon, you could put it off until later and live with blending that isn't quite right until someone gets to it.

ok. That sounds good - already someone in the community has pointed out CCTexture.

If that doesn't work out for you, I use FBOs in my C++ framework, and I'd be glad to help out. Let me know.

18 jours plus tard

I had the similar misfortune of getting stuck by turning the Slot object alpha down and not getting the transparent result in Cocos2d-x.

By default the CCSkeleton source blend function is being set to GL_ONE.
On Slots that need full alpha I'm setting blendFunc.src = GL_SRC_ALPHA

Changing the blendFunc is fine if that works for you. GL_ONE is used by default because it is intended to be set up for premultiplied alpha for proper blending. I see this doesn't work quite right though, so I have fixed it. If you use images with premultipled alpha cocos2d-x and cocos2d-iphone should work out of the box without having to change the blendFunc. If you don't use premultiplied images, be sure to call setOpacityModifyRGB(false).

Very cool Thanks - git:a4bd912
This fix looks good, I'm going to undo my blendFunc change, I was noticing poor anti-alasing edges because of that mode.

9 mois plus tard

I dont think the current solution is correct. The image ends darker. See the attached image.
A CCSkeletonAnimation and a CCsprite objects with the same opacity over a gray background to compare. The CCSkeletonAnimations is darker with the same opacity.

Ive fixed this by removing [self setOpacityModifyRGB:YES] and changing _blendFunc.src to GL_SRC_ALPHA
at CCSkeleton.m

This left an ugly border around the images as jllust said.

So I put [self setOpacityModifyRGB:YES] and changed to the original _blendFunc.src =GL_ONE again and made a change in draw:

Just remove
if (_premultipliedAlpha) {
_skeleton->r *= _skeleton->a;
_skeleton->g *= _skeleton->a;
_skeleton->b *= _skeleton->a;
}

Check attachements

Im not sure why this works btw Im a noob =)

This thread is pretty old. What isn't a correct solution to what? Are your images using premultiplied alpha? Your attached image didn't come through.

Nate a écrit

This thread is pretty old. What isn't a correct solution to what? Are your images using premultiplied alpha? Your attached image didn't come through.

I updated my post.

Nate a écrit

Are your images using premultiplied alpha?

Nate a écrit
Nate a écrit

Are your images using premultiplied alpha?

When I exported the images I clicked on premultiply alpha on atlas settings inside Spine, that removed the bleed option. I tested but gave me the same results. A black opacity. Also using premultiply alpha creates a black border around the image parts inside the atlas, its thin but its there.

Check attachements