Jump to content
  • Advertisement
Sign in to follow this  
masterbubu

SSE vector normalization

This topic is 2150 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi,

this is the function I use for normalize vec3


inline const CVector3SSE& CVector3SSE::Normalize()
{
m_fValsSSE = _mm_mul_ps(m_fValsSSE, _mm_rsqrt_ps(_mm_dp_ps(m_fValsSSE, m_fValsSSE, 0x7F)));
return *this;
}


the problem is that the sqrt can be zero.

I want to first check if all the coords of the vector are none zero, and only then calculate the sqrt.

if ( *this != ZERO_VEC)
normalize

I have thought about sum all the components in the register and check the res... but I'm not sure how to do that smile.png

Any solution will be welcome.

tnx Edited by masterbubu

Share this post


Link to post
Share on other sites
Advertisement
Why do you want to check for zero vector here? Isn't that a bug in your algorithm if you want to normalize zero vector? Because If you want to normalize vector, then it means you want to get vector with same direction, but with length equal to 1. There is no way you can do that with zero vector - it has no direction. Edited by Martins Mozeiko

Share this post


Link to post
Share on other sites
What do you want the result to be when someone tries to normalize a zero-length vector?

Share this post


Link to post
Share on other sites
HI,

Martins Mozeiko:
I do some mathematics operations on the vector, and then I'm normalizing it.
It is possible that this vector turns to be Zero vector. I just want to check it b4 I normalize it.


Hodgman:
if the vector is the Zero vector, than don't normalize it. I just need away to determine if it is a Zero vector ( fast ).

Share this post


Link to post
Share on other sites
N.B. I'm not very experienced with SSE, so this might not be the best solution.

You could use _mm_cmpneq_ps to compare the vector against (0,0,0,0), which sets each component of the result to either 0xffffffff or 0x0.
You could then use _mm_movemask_ps to OR those 4 result values into a single integer. This integer will be non-zero if any of the original inputs were non-zero, and will be zero if all of the original inputs were zero.

Share this post


Link to post
Share on other sites
Tnx, I'll try that.

All the vector normalization examples I saw online, did not take care for the Zero vector case.

Why is that?

Anyone knows the effect on the performances?

Share this post


Link to post
Share on other sites

All the vector normalization examples I saw online, did not take care for the Zero vector case.

Why is that?

Most likely laziness or ignorance.

I don't know about performance here. I don't know anything about SSE stuff.

Share this post


Link to post
Share on other sites
I don't know if it's laziness/ignorance. A zero vector means your code logic has failed somewhere (or your program inputs are invalid), and is not be a normal occurrence that should be checked against beyond an assert in debug mode. I would just let it be, it will cause an exception in due time. Doing a conditional check for each normalization defeats the performance advantages of using SIMD instructions, imho. Edited by Bacterius

Share this post


Link to post
Share on other sites

I don't know if it's laziness/ignorance. A zero vector means your code logic has failed somewhere (or your program inputs are invalid), and is not be a normal occurrence that should be checked against beyond an assert in debug mode.

That's probably what I'd do, is use a debug assert. Anything less than that and I'd most likely (personally) call it laziness or ignorance. Anything more than that and I'd most likely call it pedantic (which may or may not be what your project needs). Edited by Cornstalks

Share this post


Link to post
Share on other sites

inline const CVector3SSE& CVector3SSE::Normalize()
{
static const __m128 almostZero = _mm_set1_ps(1e-5f);
__m128 dp = _mm_dp_ps(m_fValsSSE, m_fValsSSE, 0x7F);
const __m128 cmp = _mm_gt_ps(dp, almostZero);
dp = _mm_rsqrt_ps(dp);
m_fValsSSE = _mm_mul_ps(m_fValsSSE, _mm_and_ps(dp, cmp));
return *this;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!