Swift 3 (SpriteKit): Changing the alpha value of the parent which affects all children
Asked Answered
R

1

7

Say for instance I create SKShapeNode and create children for it (an example is a cross and its two intersecting lines). The cross is the parent, and the intersecting lines are the children. How could you change the alpha value of all the parent's children? Currently just using:

parent.alpha = 0.5

doesn't change the alpha value of its children.

If anyone is able to maybe create a shader that could solve this issue or use any other way, please reply. This post is in response to my previous post: (Swift: Make translucent overlapping lines of the same color not change color when intersecting) I am trying to make the darker spots where translucent lines intersect disappear if someone is able to solve this issue.

Here is some code as an example:

let nodeParent = SKShapeNode()
let nodeOne = SKShapeNode(circleOfRadius: 5)
let nodeTwo = SKShapeNode(circleOfRadius: 5)

//Set the color of the circles, I'm not sure if this is the right way 
nodeOne.fillColor = UIColor.init(red: 0.0, green: 1.0, blue: 0.0, alpha: 1.0)
nodeTwo.fillColor = UIColor.init(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)

nodeParent.addChild(nodeOne)
nodeParent.addChild(nodeTwo)
addChild(nodeParent)

nodeParent.alpha = 0.5

I have taken a screenshot of the problem while using lines instead of circles:

Thanks.

Resin answered 22/12, 2016 at 4:36 Comment(11)
This should work. A parent node that has children, that have children, that have children... that parent's transparency impacts all of its children equally. If all the children were at an opacity of 1.0, and the parent is changed to 0.5, then all the children will become 0.5. If the children started life at 0.5, and the parent at 1.0, then changing the parent to 0.5 halves the children's opacity to 0.25Cornwallis
I add all of the children to the parent with an alpha of 1.0, and changing the alpha of the parent doesn't affect that for some reason. That's what I'm trying to figure out.Resin
argh, there's definitely something wrong with the relationship, between parent and children, then. Can you show more code? This really should work.Cornwallis
I edited my post.Resin
try making nodeParent an SKNode() instead of a SKShapeNode(). Shouldn't make any difference, but worth a try.Cornwallis
That didn't help unfortunately.Resin
Can you show me a screenshot of your results?Cornwallis
My post is now edited with it.Resin
argh, so you're trying to use KnightOfDragon's technique?Cornwallis
doing it my way, node parent must be an effect node, since it renders to a separate buffer. Not sure how this question is any different than the last.Odelet
Read my comment to @Confused's answer - I'll try that instead nowResin
C
3

This is the correct and intended behaviour, for SpriteKit blendModes, largely because they don't have a like-for-like blending mode that ignores anything the same as itself.

When you reduce the opacity of several nodes, that are still drawn sequentially, as these are, you get a cumulative result under any blending positions. That's why the bright part at the middle.

In my answer to your previous question, I was avoiding cumulative rendering by "flattening" both axis of the cross into a texture, then loading that texture as a SpriteNode, a one time rendering object that has no intersections because it's all one thing.

Anything you want to have avoid this kind of cumulative, sequential rendering effect of less than full opacity will require you to first "flatten" it with all objects/lines/shapes at 100% opacity, first, then apply Opacity changes to get alpha effects.

This is why I said, in that first "answer", that it's not really a solution for your bigger problem, just a way to get the desired result.

Without a like-to-like ignores rendering mode, SpriteKit isn't able to do overlays without a cumulative impact on anything that's got less than full opacity.

Cornwallis answered 22/12, 2016 at 12:29 Comment(3)
Ok I was just trying to get a different opinion on this to see if anyone had any other workarounds. Seems not so you're right. The problem with textures is that they are slow, and I'm creating a new one several times a second.Resin
@Resin Those SKShapeNodes you are using are what makes your game slow, not the textures. SpriteKit can render a lot of textures in a performant way ( by using atlases). This can't be said for SKShapeNode. It requires (at least) one draw call when rendered. Read more here or here If you are having like 50+ SKShapeNodes on the screen, then you will be likely experience some serious performance issues. As pointed in docs, it should be used sparingly.Deventer
@Resin Read more here about batch rendering : https://mcmap.net/q/1007303/-render-nodes-in-single-drawing-pass-with-spritekit/3402095 (see posts of LearnCocos2D).Deventer

© 2022 - 2024 — McMap. All rights reserved.