How do you add a CIPixellate Core Image Filter to

2019-06-23 04:26发布

问题:

How do you add a CIPixellate Core Image Filter to a Sprite Kit scene?

I have a SpriteKit scene that is an SKScene or subclass of it. I want to add a Core Image filter to the scene. Specifically a CIPixellate filter, so I can have 8-bit game heaven for free.

How do I do that?

回答1:

It turns out this is not hard at all. It's just that the Core Image Filter docs are OLD and crufty and in the case of SpriteKit, the docs are flat out misleading or incomplete, including the SKEffectNode docs. The SKEffectNode docs have this to say (as of this post) on the filter property of SKEffectNode:

The Core Image filter must have a single inputImage parameter and produce a single outputImage parameter. The default value is nil. If the value is nil and the effect node is enabled, no filtering takes place. However, its children are still rendered in a separate pass and blended to the parent’s framebuffer.

Well that's sort of informative, but not terribly informative, because the Core Image Filter catalog says CIPixellate has the following keys for parameters: inputImage inputCenter inputScale It doesn't say anything about an outputImage or that the inputScale is "how pixellated".

Well, that's that... let's look at how to.

First off, note that SKScene inherits from SKEffectNode. That means you can add CIFilters to it. Awesome.

All you need to do is this.

First create a CIFilter.

CIFilter *pixellateFilter;
pixellateFilter = [CIFilter filterWithName:@"CIPixellate"];
[pixellateFilter setDefaults]; // Remember to setDefaults...
// We could change some value but for this one we won't.
//  [pixellateFilter setValue:@(10.0) forKey:@"inputScale"];

Then configure your SKEffectNode to actually render effects!.

[aScene setShouldEnableEffects:YES];

It's not a bad idea to center the filter. But your mileage may vary.

[aScene setShouldCenterFilter:YES];

Next add the filter.

[aScene setFilter:pixellateFilter];

Note that you can add this before or after it is added to a parent node and before or after it is on screen. You can even build custom SKActions to do this... :)

From all of this, one thing you can note is that the Core Image Filter catalog, as old as it is, does tell you that various filters are members of various CICategory types, even though those are poorly documented as well. But you can basically assume that anything that works in a given category implies that other filters in that category might also work :)