Website Pages:

Welcome to Pipeline Design Patterns
Vocabulary
A Theory of Pipeline
General Thoughts on Pipeline
The Map Metaphor
Patterns as Shapes
Pipeline Design Patterns
Case Studies

Sections in this Page:

Patterns as Shapes
The Simplest Pipeline
The L-Shape
The U-Shape
U-Shapes in Serial Stages
U-Shapes in Parallel
The Server U-Shape
The C-Shape
The E-Shape
The H-Shape
Summary: Patterns as-Shapes
Extra: More on Stage Handoffs

Definitions:

A Vocabulary for Diagrams
Glossary

Patterns as Shapes

Our diagrams are in an underlying space:

  • Horizontal axis — fixed Revision, and varying Representation.

  • Vertical axis — fixed Representation, and varying Revision.

Within this space, many design patterns take on shapes that snap together. Often they look like letters, such as L, U, C, etc.

To see this, let's design a highly simplified pipeline and see the shapes emerge.

The Simplest Pipeline

The Representation Problem

We start with the end in mind. We are creating a deliverable film or game, which is a dense binary file.

Pipelines solve some fundamental problems. The first is Representation: we cannot write the deliverable directly; we need to do it via an application of some sort.

In this diagram, our artist opens an application in her workspace, creates the scene and related objects, and exports the deliverable.

shapes_app
Click on diagram to Zoom/Unzoom.

Our artist needs to be able save intermediate work and come back to it, so she will save and load a Source File.

shapes_app_source
Click on diagram to Zoom/Unzoom.

The Revision Problem

The next fundamental problem is keeping track of Revisions.

Our artist continually creates revisions to her source, and exports corresponding revisions of the deliverables.

shapes_app_source_mult
Click on diagram to Zoom/Unzoom.

She can keep track of source revisions by locally renaming them, i.e.

> mv source.file source.file.backup_12

but this is a fragile workflow, as she would need to manually keep track of revision numbers.

Far better to introduce some sort of storage on the server.

The L-Shape

This is the first of our shapes, and it results from introducing source control to our simple pipeline.

shapes_ell
Click on diagram to Zoom/Unzoom.

The server has a source code management system like Perforce or Git. The artist checks out or syncs the source file into her workspace, makes her edits, then exports the finished game or animation.

Note she is still managing her downstream deliverables manually. Let's take care of that:

The U-Shape

This is the most common and most important of our shapes, and it results from introducing both source control and asset control to our simple pipeline.

shapes_u
Click on diagram to Zoom/Unzoom.

On the left side, on the server, is a source code management system. On the right side is an asset management system.

Note: some pipelines use a source code system for both. In this case Perforce is common, Git less so. I'll have more to say on this soon in Asset Management.

I have found the U-Shape with Perforce to be very common in the game industry. If your artists manage the build of downstream data, and check it in manually (say, to Perforce), then you are running a U-Shape.

Also, as we'll see, depending on the details of source/asset management, we'll often find a U-Shape hiding inside other shapes.

U-Shapes in Serial Stages

The next fundamental problem that pipelines solve is Collaboration, which can be either parallel or serial. Let's start with serial:

Many projects can be broken into Stages, where output from each stage is input to the next stage. For example, imagine that our project has an Asset Stage, where re-usable objects are created, and an Aggregation Stage, where the objects are instanced and specialized.

shapes_serial
Click on diagram to Zoom/Unzoom.

This simple graph hides a lot of complexity, especially in how the workspaces interact. See the discussion on stage handoffs below.

But for now, please note that in each stage the overall flow of information is from lower left, where the artist makes her edits, to the upper right, where they become available for downstream consumption.

U-Shapes in Parallel

A second form of collaboration is working in parallel. Many stages can be decomposed into parallel operations.

Typically this means the source files for the stage can be decomposed into orthogonal components. (Orthogonal means one component does not affect another.)

For example, imagine the project's Assets can be decomposed into Geo and Tex components, which can be developed in parallel, by separate artists, each in their own workspace.

shapes_parallel
Click on diagram to Zoom/Unzoom.

Note: This diagram overloads the meaning of the vertical axis. The Geo workspace is not more global in scope than the Tex workspace. Rather, this is just a best attempt to show both workspaces' relationship to the server.

Developing components in separate workspaces creates some workflow difficulties.

  • Versionitis. Our artists can easily check in incompatible components. The asset will be internally inconsistent. They will need to carefully synchronize their checkins, of both the source and run-time data.

  • Testing. As currently diagrammed, each checkin becomes the default revision of the asset, and will be part of any exported delivery. The asset may be internally consistent, but may be bad artistically or bad technically in some other way.


We need a way to protect the next stage from a bad checkin.

Workspace Local Assets

One common way to achieve internal consistency is for each artist to fully export the Local Asset, just to make sure their latest revisions are in sync with each other.

Then they can test the local asset in the aggregation workflow via an override.

shapes_parallel_no_tooling
Click on diagram to Zoom/Unzoom.

In this scheme, (without additional tooling) each artist exercises both component workflows. In other words:

  • the Geo Artist checks out, modifies, and exports the Geo, but in addition, checks out (read-only) and exports the Tex.

  • the Tex Artist does just the opposite.

Headless Exports

With a bit of tooling we can give each artist a Headless Export for the other components in their workspace. That way they can focus on their own work.

Here is the asset side of the graph, showing that workflow.

shapes_parallel_headless
Click on diagram to Zoom/Unzoom.

Note the Geo artist has an automatic Tex convert, and vice versa.

The Local Build

Once we have headless exports, it's a short step to unifying the workflow for all components, i.e. change it from export to save and convert.

shapes_parallel_local_build
Click on diagram to Zoom/Unzoom.

The concept of executing all the source conversions at once is called Building.

The Server U-Shape

Once we have a Build it's a natural step to put it on the server.

This demands some sort of sync operation on the server. Whatever the source control system —Perforce, Git, RCS, etc.— the files are not available directly. They need to be checked out or synced into location.

It's common to maintain the Head Revision (i.e. latest) on the server.

I've indicated a similar structure for the asset side as well, including the Head Revision.

shapes_parallel_two_level_build
Click on diagram to Zoom/Unzoom.

This is a complex but common shape: the E-Shape with Server U-Shape.

  • the E-Shape (or more accurately, the Multiple-C-Shape) means that tooling on the server is managing the conversion, and

  • the Server U-Shape is the mechanism by which the server tooling does its job.


There are many options for this mechanism. I'll have more on this in an upcoming Asset Management page, but for now, here is one way:

shapes_indir_layer
Click on diagram to Zoom/Unzoom.

In this diagram, the asset management does not rely on a source control system. Rather, the asset is built on the server, then synced (i.e. copied, possibly renamed, etc.) up to the Asset Control level, where it is accumulated into a list of some sort. These are the Installed Assets. In addition, there is an indirection mechanism to select one of the assets as the currently Published Asset.

And in the next stage's workspace, Subscription is via Reference with Override.

I've indicated the list and indirections with a different content badge colors. Again, the idea here is to evoke what is going on — i.e. to provide a simplified visual reminder of the complexity.

The C-Shape

Simplified Server Structure

I often elide the explicit source control level (i.e. Server U-Shape) and merge the drawings of the source control and head revision, unless the pipeline does something non-standard with the server checkout.

This makes it very easy to see the C-Shape and E-Shape.

C-Shape

Recall the U-Shape results from introducing source/asset control. The C-Shape results from formalizing the conversions into a build, and placing that on the server.

These are really the two main organizational shapes for any stage. Everything else is a kind of variation.

shapes_c
Click on diagram to Zoom/Unzoom.

Once again, just as with the U-Shape, this simple diagram hides a lot of details. I'll discuss them more in an upcoming page.

Also note, as in the U-Shape, the overall flow of information is from lower left, where the artist makes her edits, to the upper right, where they become available for downstream consumption.

The E-Shape

We get E-Shapes whenever we have multiple components in parallel.

The E-Shape, is an artifact of overloading the vertical axis and drawing both component workspaces on the same diagram, one above the other. What we really have is two C-Shapes, each sharing the same server.

shapes_parallel_server_build
Click on diagram to Zoom/Unzoom.

Complex assets can have a dozen or more components — geo, rig, UV, texture, hair, clothing, fracture, etc. — each of which has its own workflow. Taken singly, each workflow looks like a C-Shape. Taken all together, the whole thing looks like ... a comb, perhaps?

The H-Shape

In the preceding, we worked to get the conversions on the server, in order to manage synchronization.

Another reason to do this is if the conversions are just too heavy for the workspace machine.

shapes_h
Click on diagram to Zoom/Unzoom.

Summary: Patterns as-Shapes

Let's revisit from a very ligh level perspective.

Here is a highly simplified diagram, —where I've elided the applications and processes— showing the typical server/workspace relationship:

shapes_shorthand_ell
Click on diagram to Zoom/Unzoom.

There are two simple ways to connect in the server level asset. The first and simplest is the U-Shape:

shapes_shorthand_u
Click on diagram to Zoom/Unzoom.

The next simplest —because it requires more tooling on the server and headless exports, etc.— is the C-Shape:

shapes_shorthand_c
Click on diagram to Zoom/Unzoom.

But there are many others. We've seen L, U, C, E, H. In addition I've seen Bent-Plus, Backwards-4, and a few others. I'll cover those in future pages.

These arise naturally out of simple considerations:

  • at what infrastructure level should we do conversions?

  • where do the products need to be synced to?

I won't enumerate every possible shape. The key idea is simply that synchronizations are vertical, conversions are horizontal, and in various combinations they form recognizable shapes. Often the shapes serve as a shorthand.

Example

Imagine the downstream stage is located halfway around the world, and (as is common) the source representation is much lighter weight than the downstream asset representation. In that case, latency is a huge issue, and it's far more efficient to transmit the source, and build the asset on demand in the next stage.

shapes_shorthand_remote
Click on diagram to Zoom/Unzoom.

This is three connected L-Shapes:

  • an L-Shape based at workspace level in San Fransisco (with a vertical leg into the cloud),

  • connected via the cloud to

  • an L-Shape based at server level in London, which feeds (via reference)

  • an L-Shape based at workspace level in London.

A Shape Language

I often get into pipeline discussions. I've found that once I explain the shape concept, my counterpart will pause for a moment, then say:

“OK, in this language, I think I can draw my pipeline. We have a bunch of U's that connect into a C, then it all drops down to crazy shape I can't quite describe, then bounces back up like the right side of a U.”

And then: “Funny, I never really had a mental picture of it before.”

Maps are good things!

Extra: More on Stage Handoffs

Note: The following analysis works for either U-Shapes or C-Shapes. In fact, this section is really more about overrides, and in a subsequent release of the website will likely have its own page.


Recall our simple graph with two U-Shape stages:

shapes_serial
Click on diagram to Zoom/Unzoom.

The Full CoffeeCup Project

The above diagram seems simple, but represents significant complexity. To see this, consider a simple project with only two assets: the CoffeeCup, and the KitchenTable. In addition, there is the overall Deliverable, which could be a short animation using these assets.

Let's assume we have three artists: one for each of the assets, and one doing the overall project aggregation.

The fully expanded diagram for all three artists might look like:

shapes_kitchen
Click on diagram to Zoom/Unzoom.

This needs some explaining, as I've broken a few of the informal diagram rules in the interest of clarity.

  • The badges are color-coded by Asset rather than content.

  • The references are indicated with magenta lines for server references, and red lines for local overrides. Note the arrows point in the direction of reference (to the left) rather than data flow (to the right).

  • Again, the diagram overloads the meaning of the vertical axis. The CoffeeCup workspace is not more global in scope than the KitchenTable workspace. Rather, this is just a best attempt to show both workspaces' relationship to the server.


In detail, here is the workflow for each artist.

The CoffeeCup Artist

The CoffeeCup has been assigned to a modeling/texturing artist. Her workflow is:

  • establish a local workspace,

  • check out the CoffeeCup source as editable/writable,

  • make changes as needed,

  • and export the CoffeeCup in the downstream consumable format.

For testing purposes —to see her new edits in the context of the project— she must

  • establish a testing workspace,

  • check out the aggregation source as writable,

  • adjust the CoffeeCup in the scene,

  • re-export the project for testing.

Whether or not she needs to check-in her changes to the Aggregation Source will depend on the details of her CoffeeCup edits. For example, she may have added new logo_texture_name parameters and needs to adjust how they are specialized in the aggregation.

# Aggregation Source
# as seen in CoffeeCup Workspace

table_1 = KitchenTable()    # note this resolves to server version
cup_1   = CoffeeCup()       # note this resolves to workspace version
cup_2   = CoffeeCup()       # ditto

cup_1.logo_texture_name = 'JoesDiner.tex'
cup_2.logo_texture_name = 'ILoveCoffee.tex'

Once she is happy with the new CoffeeCup she can check in both the source and output versions of the cup. For concreteness, imagine the source is a Maya file, and the deliverable is an Alembic file with new UV assignments on the points.

If needed, she can also check in her changes to the aggregation source.

KitchenTable

Exactly the same, but with the roles of the Assets reversed. CoffeeCup comes from server, and KitchenTable is local.

Project Aggregation

Our third artist is a game level designer. Once both CoffeeCup and KitchenTable assets are built and checked in (on the upper right of their respective U-shapes), the level designer can check out the Game Level Source (i.e. aggregation source) and make the final adjustments to how the new assets are instanced and specialized.

On check out he may be surprised to see the new logo parameters. He immediately realizes that the CoffeeCup artist had not gotten the latest art direction — there are now three cups, and also a new logo texture.

# Aggregation Source

table_1 = KitchenTable()    # all assets resolve to server versions
cup_1   = CoffeeCup()       #
cup_2   = CoffeeCup()       #
cup_3   = CoffeeCup()       #

cup_1.logo_texture_name = 'JoesDiner.tex'
cup_2.logo_texture_name = 'ILoveCoffee.tex'
cup_3.logo_texture_name = 'BestDinerInTown.tex'

He will adjust this file as needed, export and test the deliverable, and if all is good, check it in to Asset Management for the project.

Note the other artists do NOT check in their project deliverables. Those are meant to be local to their workspace.