Floating point precision inside VOPs

   3437   2   3
User Avatar
Member
2 posts
Joined: April 2015
Offline
Hi!

I'm running into what looks like a floating point precision issue, and I wanted to see if anyone else has seen this. I have a point that's at { 1234.56, 0, 0 } (6 non-zero digits is as much as the spreadsheet will display). As part of a larger algorithm inside an Attribute VOP, I'm adding a vector of pscale magnitude to the point's X. However, since the pscale is very small (e.g. 0.00005), adding the two still leaves the x value at 1234.56, and when I subtract the original point from the point with the added radius, I get a 0.0 value which then goes on to wreak havoc in the rest of my setup. I have tried casting both the position and the pscale as a 32- or a 64-bit float before diving into the VOP, but that hasn't made a difference.

Has anyone seen this behavior before? Seems like 6 digits of precision is really small. Due to the nature of the larger algorithm, zeroing out the point prior to the operation is not feasible (it needs to be transformed into camera space later).

Any suggestions are appreciated!
User Avatar
Member
1743 posts
Joined: March 2012
Offline
32-bit floats are only precise to between 1 part in 16,777,216 and 1 part in 33,554,431, so about 7.2 to 7.5 decimal digits. VOPs currently only supports 32-bit floats, so it's converting pscale to 32-bit before computing, if it was 64-bit in the attribute. In 32-bit floating-point, 1234.56 is (I assume) exactly equal to 1234.56005, (i.e. they get rounded to the same value).

This is why it's important to operate on geometry reasonably close to the origin. If you want to make changes that are extremely small compared to the distance to the origin, they're going to hit catastrophic roundoff error. If you must use geometry that's very far from the origin compared to the tiny changes being made, you can also try to mitigate precision problems by changing the way the computation is done. For example, it sounds like you're adding a vector to P, then later subtracting the original P from the new P to find the vector it was moved by, but you can instead use the vector that was originally added directly, if you need it, instead of incurring the factor of 24.7 million in precision loss. There are also more complicated approaches that use multiple floats to get higher precision, but usually, the best solution is just to operate on geometry centred near the origin, instead of offset so far away relative to the small changes.
Writing code for fun and profit since... 2005? Wow, I'm getting old.
https://www.youtube.com/channel/UC_HFmdvpe9U2G3OMNViKMEQ [www.youtube.com]
User Avatar
Member
2 posts
Joined: April 2015
Offline
I see… I was computing the points in order to feed them into the toNDC() function. Basically, I'm computing the diameter of a point in screen space, by constructing two points in world space that are on opposite poles of the particle “sphere” and converting them both to NDC space (since, to my understanding, NDC is only well-defined for positions, not vectors, and only within the camera frustum). Since the NDC functions treat the camera as a closed entity, I can't think of a way to offset both the point and the camera an equal distance towards the origin from within the VOP…

I don't suppose there are equivalent toNDC/fromNDC functions that operate on distance vectors rather than position vectors? So far, the only ones I found are in CVEX land.
  • Quick Links