10.10.4.8. Harmonizer
If the key-value pair in the description has a key harmonizer_type
, it defines a harmonizer. A harmonizer constrains how a mutable attribute randomizes.
Mutable attribute harmonizer
If harmonizer_type
is mutable_attribute
, it is a mutable attribute harmonizer. When the harmonizers harmonize, a value is resolved for it just as in any other mutable attributes.
We often want to randomize a value that is shared across different mutable attributes, but is different across different frames. Consider a scene where there are 2 penguins standing side by side.
penguin:
count: 2
type: geometry
subtype: mesh
usd_path: [PATH_TO_PENGUIN]
transform_operators:
- translate:
- ($[index] % 2 - 0.5) * 600
- 0
- 0
We rotateY
them by 30 degrees each, which looks fine:
transform_operators:
- translate:
- ($[index] % 2 - 0.5) * 600
- 0
- 0
- rotateY: 30
But once we want to specify rotateY
as a mutable attribute, they rotate differently within the same frame:
transform_operators:
- translate:
- ($[index] % 2 - 0.5) * 600
- 0
- 0
- rotateY:
distribution_type: range
start: -180
end: 180
Now we want them to rotate the same angle the same frame, but different angles accross different frames. This is where the harmonizer comes to the rescue. Define a harmonizer
rotate_H:
harmonizer_type: mutable_attribute
mutable_attribute:
distribution_type: range
start: -180
end: 180
This will be evaluated only once per frame in the harmonize stage. Then the penguin mutables will retrieve this value per frame, from the harmonizer:
- rotateY:
distribution_type: harmonized
harmonizer_name: rotate_H
Now we have them rotating the same amount.
This can be used in all other transform operators as well, and all other distribution types.
Permutation harmonizer
If harmonizer_type
is permutate
, it is a permutation harmonizer. When we free randomize a harmonized
mutable attribute, we can specify a pitch
as the input to the permutation harmonizer. Then the permutation harmonizer shuffles these input, and sends back the value to the harmonized attribute, which in turn can be used in a transform operator in the harmonized randomize stage
Let’s see an example. We define 3 penguins, facing 3 directions:
penguin:
count: 3
type: geometry
subtype: mesh
usd_path: [PATH_TO_PENGUIN]
transform_operators:
- translate:
- ($[index] % $[count] - 1) * 600
- 0
- 0
- rotateY: ($[index] - 1) * 60
These 3 penguins have X-axis position -600, 0, 600; and they are rotated around Y-axis by -60, 0, 60 degrees.
Now we want to shuffle the positions of these penguins. So that penguin that rotate -60 degrees can appear to the right, for example.
First we define a mutable attribute permutated_index
as harmonized
. At free randomize stage, it submits its index as its pitch
to the harmonizer permutate_H
, which is a permutation harmonizer.
penguin:
...
permutated_index:
distribution_type: harmonized
harmonizer_name: permutate_H
pitch: $[index]
permutate_H:
harmonizer_type: permutate
At harmonize stage, permutate_H
shuffles the received pitches from all relevant harmonized mutable attributes, and resonate them back to each of them.
At harmonized randomize stage, permutated_index
gets the shuffled value back. Now, we can use it in transform operators just as using an index.
penguin:
...
transform_operators:
- translate:
- ($[permutated_index] % $[count] - 1) * 600
- 0
- 0
- rotateY: ($[index] - 1) * 60
This feature can be used with any values within scope.