Skip to content
jonahfriedman edited this page Apr 3, 2014 · 4 revisions

Sort Controller is a pass sorting system written by Andy Jones and maintained by Jonah Friedman. It allows you to write rules to sort objects into partitions based on groups.

Table of Contents

Use

Select your pass and choose:

Render: Pass: Edit: SortController.

This adds the SortController to your render pass. You'll be able to start writing the rules for sorting your pass. Passes are written as a number of = statements.

Buttons

  • Sort: Sorts whichever SortController is currently open.
  • Sort All: Sorts all SortControllers in the scene.
  • Check: Checks the pass and logs whether the sorting is up to date.
  • Check All: Checks all SortControllers in the scene and logs whether they're sorted.

Sort Code

The simple version of sort code:

  • Partition = Group
    • To the left of the "=" are partition names. If the partition does not exist, it will be created.
    • To the right of the = are group names. If the group doesn't exist, nothing will be added to the partition.
  • l: means lights partitions
  • * (Asterisk) can be used in place of a group and means all objects.
  • // or /* lines are comments and are ignored.
  • White space and blank lines are ignored

Simple Example Code

 Background_Objects_Partition = *
 myPartition = myGroup  
 l: Background_Lights_Partition = *
 l: myLightsPartition = myLightsGroup

The above code explained line by line:

  • Background_Objects_Partition = *
    • * (asterisk) means all objects in a scene. This line puts all objects into Background_Objects_Partition. This ensures that sorting starts out with a clean slate- a pass where all partitions are empty except Background_Objects_Partition.
  • myPartition = myGroup
    • This is where some actual work takes place. All objects from group "myGroup" will be added to "myPartition".
  • l:Background_Lights_Partition = *
    • l:" denotes a lights Partition. Otherwise this is the same as the first line, but for lights.
  • l:myLightsPartition = myLightsGroup
    • This is the same as the second line, except only lights will be efffected, and the partition will be a lights partition.

Real World Workflow

The Sort Controller allows a lot of different workflows. They are all based on renderable assets having "sort groups" embedded, usually named sg_something.

Frequently changing geometry while doing lighting

Let's say Alice is creating an animated element for a shot, a complicated growing metallic plant, and Bob is lighting it the shot. Alice needs to continually change the geometry, and gives Bob new animated assets as a model.

If Alice maintains two sort groups in her model, sg_metalPlant and sg_general, Bob can set up all his passes such that when the model is changed, the metal plant has the correct behavior in all passes. If Bob just wants all renderable geometry in the scene in a partition, he can call use sg_general.

In this example workflow, the rules are that each asset must contain:

  • sg_assetname (contains all renderable objects in the asset)
  • sg_general (same as sg_assetname)
Assets may have a lot of objects that shouldn't be rendered, like meshes or point clouds used to generate other meshes or pointClouds. Your scene may have objects that shouldn't be renderable by default, like lighting aid spheres, proxy geometry, placement guides, etc. Your passes need to be sorted even if you have everything renderable in one partition:

Sort Code

 Background_Objects_Partition = *
 visibleGeometryPartition = sg_general 

Lets say you want to sort it into midground, background, and fg partitions, and you have a curb, hydrant and dog in the foreground, a sidewalk with a character in the midground, and a building in the background, and you want it sorted that way in all your passes.

 Background_Objects_Partition = *
 fg_partition = sg_curb|sg_hydrant|sg_dog
 mg_partition = sg_character|sg_sidewalk
 bg_partition = sg_building

Complicated Character Setups

If you have a complicated pass setup that is reusable for more than one asset, such as a number of different characters who need the same pass setup from shot to shot, but need to be sorted into those passes in a very specific way.

A set of rules might be: Each character lighting asset as to contain, for this example a fury animal:

  • sg_assetName
  • sg_general (all renderable elements)
  • sg_displaced
  • sg_fur
I could make a pass with rules that sets up a shadow/light interaction pass, and hides the character's fur and uses the body geometry instead. This pass would work in every shot as long as there's a consistent sort group for ground objects, and a sort group for characters. It would look something like this:
 background_objects_partition = *
 characterGeoPartition = sg_general
 furPartition = sg_fur
 groundPlane = sg_groundPlane

This pass will work for any shot, with any character that's set up properly.

Complete Rules

Here are the complete rules of sort code:

 syntax: [o|l:]<setName>=<groupName1>&<groupName2>|<groupName3>
  • Partition=Group
    • To the left of the "=" are partition names. If the partition does not exist, it will be created.
    • To the right of the = are group names. If the group doesn't exist, nothing will be added to the partition.
  • o:/l: prefixes:
    • o: means renderable objects (and not lights), is the default, objects with no o/l prefix default to o:
    • l: means lights
    • if groups contain both lights and objects, only whatever the prefix is for that line will be sorted
  • * (Asterisk) can be used in place of a group and means all objects.
    • This works for both lights and objects
  • // or /* lines are comments and are ignored.
    • Blank lines are also ignored
    • These must be at the start of lines, comments in a line with a line of code will not work
  • Logical operators: & and | are supported
    • & = AND, | = OR
You may notice that log output suggests the script sorts in reverse order. This is true. However, it first analyzes the sort groups in order to determine what needs to be moved where, in order to avoid actually moving objects to partitions and then moving them again. This is for speed.

Order Matters

Note that these rules are executed in order they are written. In the following example the first line will do nothing.

 //This is broken, because Background_Objects_Partition comes second and will undo everything.
 characters = sg_character
 Background_Objects_Partition = *

Intersecting and Combining Sets: And and OR (& and |)

| (pipe symbol) is an OR statement. OR combines two sets.

 //myPartition will contain all objects from groupA as well as all objects from groupB.
 myPartition = groupA | groupB

is the same as:

 //myPartition will contain all objects from groupA as well as all objects from groupB.
 myPartition = groupA
 myPartition = groupB

& (ampersand) is the symbol for AND. AND intersects two sets.

 //myPartition will contain only objects found in both groupA and groupB.
 myPartition = groupA & groupB