Pixelate transition in SpriteKit using CIFilter

Working from Apple documentation I wanted to apply the CIPixellate filter to a SpriteKit Node and found that SKEffectNode grants access to CoreGraphic's filters and could be a good bridge.

I can get the image to pixelate, but I am looking for a smooth transition between the two stages and believe that I am having trouble with the "simd_smoothstep" function:

let pixelateNode: SKEffectNode = SKEffectNode()
let testSprite = SKSpriteNode(imageNamed: "testSprite")
let filter = CIFilter(name: "CIPixellate")!

let inputScale = simd_smoothstep(1, 0, abs(0.9))

let filter = CIFilter(name:"CIPixellate", parameters: [kCIInputImageKey: testSprite, kCIInputScaleKey: inputScale])

pixelateNode.filter = filter
pixelateNode.shouldEnableEffects = true
addChild(pixelateNode)

pixelateNode.addChild(testSprite)
ref: https://developer.apple.com/documentation/coreimage/customizing_image_transitions

ref: https://developer.apple.com/documentation/coreimage/customizing_image_transitions

nb. this is a repost in the SpriteKit forum. The old post can be removed: https://developer.apple.com/forums/thread/684687

Answered by forklift in 681772022

I have managed to simulate Apple's Core Image "CIPixelate" filter working with a transition.

Prepare by trawling all SKNodes on the scene and moving them to an SKEffectNode, which allows the filter to be applied to all its children in one go. Then place each iteration from a loop e.g. 1-20 (sweetspot) in a DispatchQueue with enough time for the pixelation effect to seem real.

//ITERATE OVER EACH PIXELATION REQUEST TO CREATE AN ANIMATION
for num in 1...20 {
        let seconds = 0.3 + 0.1 * Double(num)
        DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {     
            effectNode.filter = CIFilter(name       : "CIPixellate",
                                         parameters : [kCIInputScaleKey: (num)])
        }
    }

Finish by calling the scene transition function after the filter has had enough time to complete (I probably should use a dependency operation) gives the desired impression.

ref : https://github.com/rHockWorks/PixelationTransition/

Accepted Answer

I have managed to simulate Apple's Core Image "CIPixelate" filter working with a transition.

Prepare by trawling all SKNodes on the scene and moving them to an SKEffectNode, which allows the filter to be applied to all its children in one go. Then place each iteration from a loop e.g. 1-20 (sweetspot) in a DispatchQueue with enough time for the pixelation effect to seem real.

//ITERATE OVER EACH PIXELATION REQUEST TO CREATE AN ANIMATION
for num in 1...20 {
        let seconds = 0.3 + 0.1 * Double(num)
        DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {     
            effectNode.filter = CIFilter(name       : "CIPixellate",
                                         parameters : [kCIInputScaleKey: (num)])
        }
    }

Finish by calling the scene transition function after the filter has had enough time to complete (I probably should use a dependency operation) gives the desired impression.

ref : https://github.com/rHockWorks/PixelationTransition/

Pixelate transition in SpriteKit using CIFilter
 
 
Q