wiki:vectoraygen:home

While not necessary to operate VectorayGen, a basic knowledge of vectors, sets, and the physical relationship between position and velocity will help to get the most out of VectorayGen. This documentation assumes familiarity with these concepts. It also assumes that the output of VectorayGen is used as a vector field of velocities, eg. for particle effects in Unreal Engine. While other use cases are possible, the formalization in this document does not reflect those use cases.

The output of VectorayGen is written to .FGA files for import into Unreal Engine. The file generation options are found at the top of the `Vector Field Options`

window. Checking the `Create vector field batches`

box causes VectorayGen to output a collection of files, with `%`

being replaced by the file number. The .FGA file is a 3-dimensional array of 3-component vectors, preceded by 3 additional vectors for file information. Here, an example:

3.000000, 3.000000, 3.000000, -256.000000, -256.000000, -256.000000, 256.000000, 256.000000, 256.000000, 0.269348, 0.814392, -0.514023, -0.264771, -0.838806, -0.475708, 0.639851, -0.694504, -0.329041, 0.996181, -0.056122, -0.066864, 0.523178, 0.136810, 0.841171, 0.679184, 0.723419, 0.124008, -0.605774, 0.047447, -0.794220, -0.062485, 0.217873, -0.973969, -0.642010, -0.180618, 0.745117

Each line defines a single 3-component vector. The first is the resolution of the file. The second two, respectively, are the minimum and maximum bounds. The `resolution`

and `bounding minimum/maximum`

fields, in the `Vector Field Options`

window, control these first 3 lines in the file. The remainder of the file is the contents of the vector field, of which there are resolution_{x}*resolution_{y}*resolution_{z} elements. The resolution and bounds combine to control field density. Large bounds paired with low resolution make for a sparse field, while low bounds and high resolution make for a denser field. Very low densities may yield particle effects of poor quality, while high resolutions require more memory.

To construct a vector field, a pipeline of operators are applied to the world coordinates. In an effort to understand the operator pipeline, it is helpful to begin with an empty one. To visualize what's going on, show the vector field arrows by checking the `Show field`

box. Next, remove all the operators from the pipeline by clicking the `-`

button. A large valued vector field appears, represented as many long, narrow arrows. To ease visual comprehension, set the resolution to 3x3x3. Rotating the preview window, ones sees a handful of vectors pointing strongly away from the center. Note the absence of an arrow at the center of the bounding box preview. The world coordinate at the center of the bounding box is (0, 0, 0). ^{1)} Because the world-coordinate input to the operator pipeline is (0, 0, 0), and there are no operators, the output is (0, 0, 0). The arrow for this vector can't be seen, because it has zero size. In contrast, the other vectors are quite large because the world coordinates at their positions contain combinations of -128, 0, and 128. For example, the arrow closest to the orientation gizmo, where the red, green and blue bounding box lines meet, has a world coordinate of (-128, -128, -128). As such, the arrow at this position represents a large value, and is long and narrow. Change the resolution back to 6x6x6 (or higher) before moving on, as low densities tend to result in degraded simulation quality.

In the operator pipeline, add an element using the `+`

button, and choose `Constant`

from the drop down. Set the constant X,Y,Z values to (1, 1, 1). Now, all the arrows are the same size and point in the same direction. Precisely, they are all (1, 1, 1). Regardless of the world coordinate, the `Constant`

operator always outputs the same value. By combining the available operators in creative ways, an unlimited variety of vector fields can be created.

To describe the operator pipeline concisely and consistently, some formality is useful. The set of all vectors is ℝ³. All operators can abstracted as functions taking a vector as input, and producing a new vector. The set of all operators is O.

O: {x | x: ℝ³ → ℝ³}

This is the “O-model” of operators - all operators take a vector in, and a new vector comes out. The `Negative`

and `Normalize`

operators function at this level precisely. Starting from an empty pipeline, use the `+`

button to add a `Negative`

and a `Normalize`

operator. The field is the result of composing the `Negative`

and `Normalize`

operators together. The O-model hides the details in more complex operators. For example, The `Cross`

operator contains some configuration, which can be seen in the pipeline interface. The `Cross`

operator is described as follows.

Name | Form | Interpretation |
---|---|---|

Cross | ℝ³ * O * O → ℝ³ | p, o₁, o₂ ⇒ o₁(p) ⨯ o₂(p) |

That is, it takes a vector as the first input, an operator as the second input, and another operator as the third input, and produces a vector by computing the cross product of the results of the two configured operators. Some operators, such as `Constant`

are configured with non-operator arguments:

Name | Form | Implementation |
---|---|---|

Constant | ℝ³ * ℝ³ → ℝ³ | p, c ⇒ c |

Operators that have configurations are parametric operators. In any case, the form of an operator will always start with an ℝ³ input, and end with an ℝ³ output, which correspond to the input and output of the O-model. Parametric operators have the general form `ℝ³ * Z₁ * Z₂ * … Zₙ → ℝ³`

.

In | Configuration | Out |

ℝ³ | * Z₁ * Z₂ * … Zₙ | → ℝ³ |

One of the available operators is titled `Composition`

and it works by chaining the output of one operator into the input of the next operator, and permits any number of chained operators to be added. For convenience, the pipeline is itself a `Composition`

operator.

Notably, the O-model does not assign any meaning to vectors. However, the goal of VectorayGen is to produce *velocity* fields, representing the rate of change of the *position* of particle effects. By assigning meaning to fields, we can assign meanings to the operators, and understand the pipeline as a whole.

Name | Meaning |
---|---|

ℝ³_{W} | The set of all world coordinates (position) |

ℝ³_{V} | The set of all velocities |

The input to the pipeline is in ℝ³_{W}, and the output is in ℝ³_{V}. Unlike most operators, spatial transformation operators, specifically `Rotation`

, `Scale`

, `Shear`

, and `Translation`

, have algorithms that assume the form `ℝ³`

. Creating a pipeline solely from one of these operators will likely not result in the simulation expected. The _{W} → ℝ³_{W}`Delta`

operator, which takes one operator in its configuration, assumes that operator is of the form `ℝ³`

and produces a new vector in the _{W} → ℝ³_{W}`ℝ³`

form. _{W} → ℝ³_{V}^{2)} So, by creating a pipeline of a `Delta`

, containing a `Translation`

we get a translation *velocity* field. The full list of operators:

Name | Form | Implementation |
---|---|---|

Composition | ℝ³ * Oⁿ → ℝ³ | p, {o₁, o₂, … oₙ} ⇒ oₙ(…(o₂(o₁(p) ) ) |

Constant | ℝ³ * ℝ³ → ℝ³ | p, c ⇒ c |

Cross | ℝ³ * O * O → ℝ³ | p, o₁, o₂ ⇒ o₁(p) ⨯ o₂(p) |

Delta | ℝ³ * O → ℝ³ | p, o ⇒ o(p) - p |

Interpolate | ℝ³ * ℝ³ * ℝ³ → ℝ³ | p, r, s ⇒ (p + (1, 1, 1)) * 0.5 * (s - r) + r |

Linear fade | ℝ³ * ℝ³ * ℝ³ * ℝ * ℝ → ℝ³ | p, r, s, t, u ⇒ (v, v, v) where v = max(0, min(1, (1 - (p - r) ⋅ s / t)^{u})) |

Minus | ℝ³ → ℝ³ | p ⇒ -p |

Modulate | ℝ³ * Oⁿ → ℝ³ | p, {o₁, o₂, … oₙ} ⇒ Πoₖ(p) = o₁(p) * o₂(p) * … oₙ(p) |

Normalize | ℝ³ → ℝ³ | p ⇒ p / ‖p‖ |

Radial fade | ℝ³ * ℝ³ * ℝ * ℝ → ℝ³ | p, r, s, t ⇒ (v, v, v) where v = max(0, min(1, ( (1 - ‖p - r‖) / length)^{t}) ) |

Random | ℝ³ → ℝ³ | p ⇒ rand |

Rotation | ℝ³_{W} * ℝ³_{W} * ℝ → ℝ³_{W} | p, r, s, t ⇒ p + ( ( (p - r) - s * ( (p - r) ⋅ s) ) ⨯ s) * t |

Scale | ℝ³_{W} * ℝ³_{W} * ℝ³ → ℝ³_{W} | p, r, s ⇒ p + (p - r) * s |

Shear | ℝ³_{W} * ℝ³_{W} * ℝ³ * ℝ³ → ℝ³_{W} | p, r, s, t ⇒ p + (p - r) ⋅ s * t |

Sum | ℝ³ * Oⁿ → ℝ³ | p, {o₁, o₂, … oₙ} ⇒ ∑oₖ(p) = o₁(p) + o₂(p) + … oₙ(p) |

Translation | ℝ³_{W} * ℝ³ → ℝ³_{W} | p, r ⇒ p + r |

World origin | ℝ³_{W} → ℝ³_{W} | p ⇒ p |

World rotation | ℝ³_{W} * ℝ³_{W} * ℝ → ℝ³_{W} | p, r, s, t ⇒ |

World scale | ℝ³_{W} * ℝ³_{W} * ℝ³ → ℝ³_{W} | |

World shear | ℝ³_{W} * ℝ³_{W} * ℝ³ * ℝ³ → ℝ³_{W} | |

World translation | ℝ³_{W} * ℝ³ → ℝ³_{W} |

assuming a bounds of (-256, -256, -256) to (256, 256, 256), the defaults

Precisely, it computes a non-instantaneous derivative

wiki/vectoraygen/home.txt · Last modified: 2017/04/25 19:21 by brentlewis