FxCore is a node-based compositing engine inspired by Quartz Composer, a graphics framework and development tool Apple distributed for many years with macOS.
FxCore is a visual graphics tool. It is designed to process images to produce an output, allowing you to combine multiple graphics technologies: Metal, Core Image, Core Graphics, Vision, CoreML and more.
When you launch the FxCore app and accept its license agreement, you are greeted by an empty window:
The empty window is meant to host a graph: a series of nodes, connected together to produce the final output:
Collectively, a graph that combines the work of multiple nodes to produce an output is called a composition.
The output of your composition is visible in the preview window. A composition may be animated, producing a different output as time goes by.
A node may have zero or more inputs, and zero or more outputs. The output of one node may be connected to the input of another node, thus allowing the flow of information:
Some nodes have no outputs. They are called consumers, because they consume their inputs to produce a side effect.
All nodes that render an output are consumers. A graph can have multiple consumers:
The order in which consumers are executed matters. The number in the top-right corner of each consumer shows its current priority. Lower-numbered consumers are evaluated first. You can change the execution order by clicking on the number and assigning a new priority:
Consumers therefore define what gets rendered to the output, and in what order.
Consumers are also responsible for one of the major efficiencies of a node-based composition: your graph is evaluated lazily.
When looking at a composition, it is logical to think of information as flowing downstream, i.e. from nodes that produce and/or process information down to the consumers. In reality, when a new frame is being rendered, the graph is evaluated backwards: each consumer is executed, and when one of its inputs is needed, the graph looks to the node upstream that provides such input. The evaluation proceeds until all inputs to the consumer have been computed. The efficiency comes from ignoring any nodes whose outputs are not needed by any consumers.
Graphs can therefore grow in complexity without necessarily causing a performance penalty. FxCore only evaluates portions of the graph that are needed to produce the output.
To help manage this complexity, some nodes act as containers, allowing you to place nodes inside them and expose only a limited set of inputs and outputs.
A container is similar in concept to a folder in your file system. Just as folders allows you to group files and other folders that logically belong together under a single entity, so do containers allow you to group nodes that together perform a specific task in your composition.
When creating a container, you can hide away its complexity and expose only the inputs and outputs that are needed by other portions of your composition.
Your graph produces an output image by manipulating information with a number of graphics technologies accessible through its nodes. Some nodes are designed to process or render images (2D) while others are designed to process or render geometry (3D). FxCore provides different rendering environments to support one type of work vs the other: