User Tools

Site Tools



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.

Generating files

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 resolutionx*resolutiony*resolutionz 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 ℝ³W → ℝ³W. Creating a pipeline solely from one of these operators will likely not result in the simulation expected. The Delta operator, which takes one operator in its configuration, assumes that operator is of the form ℝ³W → ℝ³W and produces a new vector in the ℝ³W → ℝ³V form. 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