Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Vector4 Usage For Particle Positon and Velocity
#1
Hello again!

I was wondering if someone could shed some light on what the purpose/function of the 'w' value in the vector4 used for both position and velocity for particles?

For example:
Code:
// Calculate and apply spring force:
                    Vector4 position = solver.positions[pickArgs.particleIndex];
                    Vector4 velocity = solver.velocities[pickArgs.particleIndex];

Is it used like a quaternion? I didn't just want to assume/guess so I figured I'd ask. I checked out the definition ObiNativeVector4List but it's not really immediately obvious to me. I might just be developmentally challenged. Gran sonrisa

Thanks in advance.
Reply
#2
(06-02-2020, 11:33 PM)GrimCaplan Wrote: Hello again!

I was wondering if someone could shed some light on what the purpose/function of the 'w' value in the vector4 used for both position and velocity for particles?

For example:
Code:
// Calculate and apply spring force:
Vector4 position = solver.positions[pickArgs.particleIndex];
Vector4 velocity = solver.velocities[pickArgs.particleIndex];

Is it used like a quaternion? I didn't just want to assume/guess so I figured I'd ask. I checked out the definition ObiNativeVector4List but it's not really immediately obvious to me. I might just be developmentally challenged. Gran sonrisa

Thanks in advance.

Hi there! Sonrisa

The reason for this is performance. Internally, we use SIMD instrinsics for nearly all math (particle simulation, constraint projection). SIMD stands for Single Instruction-Multiple Data. It's a special kind of assembly instruction that takes 2 double precision or 4 single precision arguments, and operates on all at once. We use SSE4 and NEON instruction sets. More modern SIMD instruction sets exist that allow to operate on even more data (AVX).

So for instance, you can add two 4-component vectors in the same time you'd add two floats. The theoretical best-case speedup you get by using them vs plain two-operand operators is x4. The catch is that these instructions need the data to be 16-byte aligned in memory, and they can't work on 3 operands only.

So we needed to store our data as tightly as possible (for good cache utilization), have it be 16-byte aligned (a float is 4 bytes), and avoid casting back a forth between Vector3 and Vector4 was much as possible because it's slow as hell. There you have the reasons why we use ObiNativeVector4List: it is backed up by unmanaged memory so no managed/unmanaged data juggling, 16 byte aligned, and allows you to access the underlying data as Vector4 managed type directly. The extra component (w) is basically padding, and should be zero.

Fun fact, this is the exact same thing Burst and NativeList do. NativeList is pretty much identical to ObiNativeVector4List, and Burst compiles your job code into SIMD instructions as long as you're using Unity.Mathematics.

Here you have some interesting experiments of another user, testing float3 vs float4 for speed in Burst. Turns out, that using float4 is fastest, because you can skip conversions between float3 and float4:
https://forum.unity.com/threads/burst-si...es.527504/
Reply
#3
Always good to hear it's for performance purposes.

Solid code.

Thanks for the help, as always.
Reply