4 ms·
> For some reason I can't quite put my finger on, some experienced game programmers are reluctant to use atan2() and prefer the dot product. It's because atan2
by pcwalton 9y ago
> For some reason I can't quite put my finger on, some experienced game programmers are reluctant to use atan2() and prefer the dot product.
It's because atan2, along with all the other inverse trigonometric functions, is incredibly slow. On a GPU, sin and cos may be a couple of cycles, but asin/acos/atan/atan2 may be upwards of 30 or 40.
Often times, angles are best avoided when possible for this reason. Normalized vectors end up faster and simpler in many cases.
Relevant anecdote: I recently wrote some code to compute normals in 2D and thought I would be clever by encoding the normal as an angle to save space. It turned out that the atan2 call at the end was so slow that it outweighed the cost of everything else I was doing several times over. Lesson learned…
- agjacobson 9y agoExactly. And if you understand what you’re doing, you can avoid referencing the angle explicitly. Because macro arc length is rarely needed.
- nerfhammer 9y agorelevant, in case anyone needs it: https://geekshavefeelings.com/posts/fixed-point-atan2 https://geekshavefeelings.com/posts/fixed-point-atan2
- tgb 9y agoI also think the dot product and other vector operations are more naturally the thing you're actually trying to do in the end. We generally start with a vector (say a movement command to take our unit to a certain location) and want to end up with a vector (acceleration to apply) so going through angles as the intermediate step makes little sense logically. This is true even in 2D and without speed constraints. Moreover, angles often leave you with a tricky case to handle where you are going "over 360 degrees"and there is an unnatural discontinue discontinuity.
- 60654 9y agoYeah, there are multiple reasons. Perf is important: inverse trig functions are generally much slower both on the CPU and on the GPU [1] But also - most of the time gamedev happens in 3D space not in 2D space (even if it gets rendered down to 2D). So it's more natural to do a dot product of two 3d vectors, than try to mess around with trig functions that work on scalar angles. Same with rotations: it's easier and better to use quaternions in 3D space than try to rotate along each axis separately. [1] GPU intrinsic estimated costs: http://www.fractalforums.com/programming/shader-function-or-instruction-cost-(performance)/msg84618/#msg84618 http://www.fractalforums.com/programming/shader-function-or-...
- dahart 9y ago> 1/x, sin(x), cos(x), log2(x), exp2(x), 1/sqrt(x) - 0 or close to 0, as long as they are limited to 1/9 of all total ops (can go up to 1/5 for Maxwell). This is what surprised me to learn recently, that some transcendentals are free, as long as you don't use too many of them.
- vvanders 9y agoQuaternions have a bunch of properties that make them awesome: * Compact storage compared to matrices * No gimbal-lock * Multiplication is cheap (mult + add, very similar to vector operations) * Interpolation is cheap You really only pay the sin/cos costs when translating out to a Mat3x3 at the end.
- Const-me 9y ago> You really only pay the sin/cos costs when translating out to a Mat3x3 at the end. You don’t need sin/cos for that either. Here’s a code that does that: https://github.com/Microsoft/DirectXMath/blob/master/Inc/DirectXMathMatrix.inl#L1654-L1736 https://github.com/Microsoft/DirectXMath/blob/master/Inc/Dir...
- vvanders 9y agoYou're right, I was mixing that up with the initial conversion from axis+angle to quaternion.
- 0xfaded 9y agoUntil you need to differentiate a quaternion ... Also, you don't pay the sin/cos costs when converting to a rotation matrix. For angle axis R = I + (sin x) * S + (1 - cos(x)) * S^2 Where S is the 3x3 skew symmetric matrix. A unit quaternion representing a 3D rotation is sort of like angle axis q = cos(x/2), sin(x/2) <axis> But sin(x) = 2*cos(x/2)*sin(x/2) (1-cos(x) = 2*sin(x/2)*sin(x/2) Where you pay the cost is in the construction of the quaternion.
- 9y ago