SKEffectNode to an SKTexture?

后端 未结 2 1539
礼貌的吻别
礼貌的吻别 2021-01-20 19:56

SKEffectionNodes have a shouldRasterise \"switch\" that bakes them into a bitmap, and doesn\'t update them until such time as the underlying nodes that are impa

相关标签:
2条回答
  • 2021-01-20 20:08

    I think you could try a code like this (it's just an example):

    if let effect = SKEffectNode.init(fileNamed: "myeffect") {
        effect.shouldRasterize = true
        self.addChild(effect)   
        ...         
        let texture = SKView().texture(from: self)
    }
    

    Update:

    After you answer, hope I understood better what do you want to achieve.

    This is my point of view: if you want to make a shadow of a texture, you could simply create an SKSpriteNode with this texture:

    let shadow = SKSpriteNode.init(texture: <yourTexture>)
    shadow.blendMode = SKBlendMode.alpha
    shadow.colorBlendFactor = 1
    shadow.color = SKColor.black
    shadow.alpha = 0.25
    

    What I want to say is that you could proceed step by step:

    • get your texture
    • elaborate your texture (add filters, make some other effect..)
    • get shadow

    This way of working produces a series of useful methods you could use in your project to build other kind of elements. Maybe, by separating the tasks you don't need to use texture(from:)

    0 讨论(0)
  • 2021-01-20 20:16

    I've figured this out, in a way that solves my problems, using a Factory.

    Read more on how to make a factory, from BenMobile's patient and clear articulation, here: Factory creation and use for making Sprites and Shapes

    There's an issue with blurring a SKTexture or SKSpriteNode in that it's going to run out of space. The blur/glow goes beyond the edges of the sprite. To solve this, in the below, you'll see I've created a "framer" object. This is simply an empty SKSpriteNode that's double the size of the texture to be blurred. The texture to be blurred is added as a child, to this "framer" object.

    It works, regardless of how hacky this is ;)

    Inside a static factory class file:

    import SpriteKit
    
    class Factory {
    
        private static let view:SKView = SKView()  // the magic. This is the rendering space
    
        static func makeShadow(from source: SKTexture, rgb: SKColor, a: CGFloat) -> SKSpriteNode {
            let shadowNode = SKSpriteNode(texture: source)
                shadowNode.colorBlendFactor = 0.5  // near 1 makes following line more effective
                shadowNode.color = SKColor.gray // makes for a darker shadow. White for "glow" shadow
            let textureSize = source.size()
            let doubleTextureSize = CGSize(width: textureSize.width * 2, height: textureSize.height * 2)
            let framer = SKSpriteNode(color: UIColor.clear, size: doubleTextureSize)
                framer.addChild(shadowNode)
            let blurAmount = 10
            let filter = CIFilter(name: "CIGaussianBlur")
                filter?.setValue(blurAmount, forKey: kCIInputRadiusKey)
            let fxNode = SKEffectNode()
                fxNode.filter = filter
                fxNode.blendMode = .alpha
                fxNode.addChild(framer)
                fxNode.shouldRasterize = true
            let tex = view.texture(from: fxNode) // ‘view’ refers to the magic first line
            let shadow = SKSpriteNode(texture: tex)  //WHOOPEE!!! TEXTURE!!!
                shadow.colorBlendFactor = 0.5
                shadow.color = rgb
                shadow.alpha = a
                shadow.zPosition = -1
    
            return shadow
        }
    }
    

    Inside anywhere you can access the Sprite you want to make a shadow or glow texture for:

    shadowSprite = Factory.makeShadow(from: button, rgb: myColor, a: 0.33)
    shadowSprite.position = CGPoint(x: self.frame.midX, y: self.frame.midY - 5)
    addChild(shadowSprite)
    

    - button is a texture of the button to be given a shadow. a: is an alpha setting (actually transparency level, 0.0 to 1.0, where 1.0 is fully opaque) the lower this is the lighter the shadow will be.

    The positioning serves to drop the shadow slightly below the button so it looks like light is coming from the top, casting shadows down and onto the background.

    0 讨论(0)
提交回复
热议问题