There are a couple of common transforms-related pitfalls you can encounter:
1- Only transforming positions
Not transforming other 3d coordinates used for the simulation to worldspace often leads to undesired behaviors if part of the simulation already runs in worldspace.
Transforming only position and changing the effect instance orientation ignores the effect orientation entirely. In the example below, the physics node will see the {1, 2, 0} vector as an absolute, worldspace velocity:
![]() | ![]() |
Using the “local direction to world” to transform the initial velocity before wiring it into the physics node solves the problem:
![]() | ![]() |
2- Converting to worldspace twice
Doing a local->world conversion at spawn, running the simulation at evolve, and inserting a local to world conversion before rendering in hopes of making the particles follow the effect, will lead to totally incorrect behavior.
![]() | ![]() |
This can also happen with trails and child particles, when you want localspace trails. Here you want the spawn xform node to spawn at the parent particle position, but also want the child particles to follow the effect instance. The solution here is to use a localspace node.
3- Localspace scene collisions
Using the “local position to world” node before rendering to transform the effect to worldspace will not work properly when using a collision node. This is because the collision node expects worldspace coordinates.
The effect will always collide as if it was located at the world origin:
![]() | ![]() |
Having the entire simulation run in worldspace produces correct collisions:
![]() | ![]() |
4- Incorrect positioning of local to world evolve conversion
Trying to solve #3 by converting from local to world at evolve before the physics node will not work, and produce incorrect results.
Trying to solve #3 by converting from local to world between the physics and collision nodes will not work either.
The physics and collision nodes re-use the simulation’s previous frame results to compute the new particle state.
This is done through a load/store path (also called discretization path). For position, the load happens along the position wire at the first spawn->evolve transition, and the last store performed is at the end of the collision node.
Load/store paths are displayed in yellow in the “Exec rate” view mode of the nodegraph.
Any operation touching that yellow region is on the load-store path and will affect the results of the next frame.
Inserting an evolve “local position to world” node before the physics or between the physics and collision will cause it to transform the previous frame position at the start of every new frame. This is equivalent to adding the emitter position to the previous position, every frame.
It is effectively re-transforming from local to world a coordinate which was already in worldspace. This is like pitfall #2, except it does it every frame and accumulates the results.
This obviously causes totally wrong results whenever the effect is not at the origin, causing the entire simulation to “expode”.
There are various ways to solve this. The easiest one by far which does not need to worry about or even understand load/store paths is to use a localspace node.