Core Image Kernels using Metal

Beginning with FxCore 8.0.14 you can code and deploy Core Image Kernels based on the Metal Shading Language with the same set of features available for the older Core Image Kernel Language.

Getting Started

You can find the Custom Shader node under the 2D category:

Core Image Metal Shader

Core Image Metal Shader

On its default configuration, the source code is missing the set of #include and using namespace statements that you would expect for a Metal-based Core Image kernel:


FxCore decorates the source code with glue code appropriate for writing Core Image Metal shaders. The above source code is compiled as if it were entered as follows:


When the default behavior is not appropriate for your use, insert explicit #include statements to prevent FxCore from decorating your source code.

Image and Color Inputs

Any sampler arguments to your kernel are automatically advertised through an Image-based input port. Some special considerations are necessary for color inputs and/or when writing a CIColorKernel, i.e. a kernel with no sampler inputs, but whose intention is to process images by accessing the sample at the current coordinate only.


The Metal compiler makes no difference between sample_t, __color and float4 arguments. FxCore will therefore advertise all such arguments as 4 numeric inputs or as a single vector input, depending on how you have configured the node:

Displaying vector arguments through vector inputs

Displaying vector arguments through vector inputs

This is insufficient for creating a well-behaved kernel. While technically speaking a __color input is a 4-element vector, your kernel should correctly assume that RGB color values are expressed in the working color space. When you leave the input as a vector, those values are not converted to the working color space during execution.

Leaving __color arguments as vector inputs also poses some UI challenges, as the RGBA components must be entered numerically, rather than through a color picker:


To solve this problem, new options are available in FxCore 8.0.14 when you right-click on the corresponding input port:


Any 4-element vector arguments can be upgraded into an equivalent Color or Image input. When converting your argument to a color, the RGB component values are implicitly converted to the working color space as your kernel executes, and FxCore will let you assign a value through the system color picker.

Similarly, when upgrading vector arguments to Image inputs, Core Image will implicitly convert RGB sample values to the working color space:


The resulting kernel is otherwise known as a CIColorKernel. It is important to be aware of certain limitations.

If a kernel already contains native sampler arguments, it is not possible to change vector arguments to Image inputs. The corresponding option will therefore be grayed out:

Conversion unavailable

Conversion unavailable

Some optimizations are only possible because a CIColorKernel is only allowed to access the RGB values at the current destination coordinate. When your kernel contains native sampler arguments, it cannot become a CIColorKernel.

This limitation exists for the older Core Image Kernel language too. In that case, the compiler allows a mix of sample_t and sampler arguments but the kernel fails to execute correctly. The node produces no output image.

Further reading

The Shader node shares the same advanced features as the existing Core Image Kernel node:

Core Image Filter Sampler Configuration

Metal Shading Language for Core Image Kernels

Metal Shading Language Specification