Building imgplex: part 6

imgplextoolinggame-dev

This is a series of posts on building imgplex, best read in order:
Part 1 - The why, what, and how of imgplex
Part 2 - Getting things up and running
Part 3 - The node definition system
Part 4 - Executing the node graph, making it fast
Part 5 - Two graphs in one
Part 6 - Multiple inputs and outputs, processing images as sets
Part 7 - Profiling and Optimization

Supporting multiple inputs and outputs

The first version of the pipeline supported one Input node and one Output node. That was enough to build and test the execution system, but it became limiting once I started trying workflows that combined several image sources or produced more than one result.

A compositing workflow might load source images from one folder and masks from another. The same workflow might also need to save the processed images, write some calculated values to text files, and generate a contact sheet for review.

To support those cases, I changed the graph to allow multiple Input nodes and several typed output nodes.

Multiple inputs

Each Input node owns a separate image list and filmstrip state. Selecting an Input node switches the filmstrip to that node’s files.

This is useful for workflows that combine independent sources. For example, one Input node can provide a base image while another provides an overlay or mask. Keeping the queues separate avoids merging unrelated files before the graph determines how they should be combined.

Supporting multiple inputs also required a change to execution planning. With only one Input node, the engine could assume that every output ultimately came from the same image queue. That assumption no longer worked once several sources were present.

When a run begins, the engine traces each output branch upstream until it reaches an Input node. That tells it which image queue should be processed through that branch.

Multiple typed outputs

imgplex currently has three output-node types:

Text Output can receive values such as an image’s filename or dimensions, as well as results produced by Math, Logic, or other value nodes. This can be used for manifests, sidecar data, or inspecting the values produced by a graph.

The first implementation used one Output node with a mode dropdown. Image, text, and flipbook output were all handled by that node.

That design became difficult to maintain as the output modes diverged. Each one needed different Inspector controls, validation rules, and execution behavior. The shared node accumulated more conditional UI every time a new setting was added.

I eventually replaced it with separate output-node types. Each node now owns the controls and validation appropriate to its output, and the selected behavior is visible directly on the canvas.

During a run, the engine processes each valid output node. A workflow can therefore save processed images, write calculated metadata, and generate a contact sheet without requiring separate graph files.

The skip-or-overwrite setting originally existed only on Image Output. I later moved it into the shared output behavior so that Text and Flipbook outputs follow the same policy when their destination files already exist.

Processing images as sets

The normal Input node treats every file as an independent item. That does not work for operations that need a related group of images, such as the faces of a cubemap, the frames of a sprite sheet, or the maps belonging to one material.

For those cases, I added a Set Input node that derives a group key from filenames using a configurable prefix or suffix rule. Files with the same resulting key are passed through the pipeline as one set.

For example, T_Example_D.png and T_Example_N.png can both be grouped under T_Example. A sequence such as Frame_01.png, Frame_02.png, and Frame_03.png can be grouped under Frame when the configured rule removes the numbered portion of the filename.

The exact grouping rule depends on the filename convention being used. This matches a common game-art workflow in which related texture maps or animation frames are associated through their filenames.

Nodes that accept image sets receive the entire group rather than one file at a time. Flipbook Output, for example, needs every frame before it can build the final tiled image.

The grouping field is exposed as a string input rather than existing only as an Inspector value. It can therefore be supplied by a constant or another compatible operation in the value graph.

Flipbooks

Flipbook Output arranges an image set into a tiled texture.

In real-time VFX, this format is commonly used to store animation frames for a particle shader. The same operation can generate contact sheets for reviewing a large batch of processed images.

The node receives an image set, determines the grid layout, and composites the frames into one output image.

It also accepts a background color used for the areas between and behind the tiles. This is useful when creating ordinary contact sheets and can affect edge filtering when the result is used as a texture, particularly around frames containing transparency.

Validating multiple outputs

With several output nodes in a graph, they may not all be ready when a run begins. One output may be fully configured while another is disconnected or missing a destination path.

I did not want invalid outputs to be omitted without explanation, so imgplex validates every output before execution. A confirmation dialog lists which outputs are ready and explains why any others cannot run, such as a missing source connection or unset destination path.

A confirmation dialog lists the available outputs and reports which ones are ready to run. When an output is invalid, the dialog gives the reason, such as a missing source connection or an unset output path. The user can review the results before starting the batch.

Nodes that do not lead to an output are excluded from both preview and batch execution. This allows unfinished or experimental branches to remain on the canvas without producing errors or adding work to a run. Once the branch is connected to an output, it becomes part of the execution plan.

Saved workflows also include the version of imgplex that created them. If a workflow was written by a newer application version, imgplex displays a warning before loading it because the file may contain fields that the current build does not understand.

During processing, the progress dialog shows the current filename in addition to the overall progress value. This also helps identify files that take substantially longer to process than the rest of the batch.

Together, these changes allowed one workflow to combine several image sources, process related files as sets, and produce multiple independently validated outputs. They also required the execution engine to stop treating the graph as one linear path between a single input and output.

Next post in this series: Part 7 - The small, measured optimizations beneath the big ones