Jump to content

  • Log In with Google      Sign In   
  • Create Account

We're offering banner ads on our site from just $5!

1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


normalize() producing different results


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
6 replies to this topic

#1 george7378   Members   -  Reputation: 1251

Like
1Likes
Like

Posted 28 January 2014 - 03:27 PM

I've come across something weird in HLSL. Well, maybe it's not that weird, but it was unexpected for me. There's probably a simple explanation. Anyway...

 

when I do this in my normal mapping shader:

 

float3 normal = normalize(2.0f*tex2D(TextureSamplerN, PSIn.TexCoords) - 1.0f);

 

...I get a different result to if I do this:

 

float3 normal = 2.0f*tex2D(TextureSamplerN, PSIn.TexCoords) - 1.0f;
normal = normalize(normal);

 

It seems like the latter one produces the correct result when I run my program, but I have no idea why they're different. Any ideas?

 

Thanks!
 



Sponsor:

#2 Mona2000   Members   -  Reputation: 617

Like
10Likes
Like

Posted 28 January 2014 - 03:44 PM

In the first snippet you normalize a float4 and then throw away the fourth component, while in the second snippet you throw away the fourth component and then normalize.

The result of the first snippet is not unit length (unless the sampled fourth component is exactly 0.5).



#3 MJP   Moderators   -  Reputation: 11589

Like
8Likes
Like

Posted 28 January 2014 - 03:47 PM

Like Mona mentioned, in both cases you're implicitly truncating a float4 to a float3. This is generally considered bad practice, since it can lead to non-obvious bugs due to dropping data. In fact the compiler will actually warn you when it happens. If your intention is to truncate, I would recommend using a swizzle like this:

 

float3 normal = normalize(2.0f * tex2D(TextureSamplerN, PSIn.TexCoords).xyz - 1.0f);

This makes the truncation explicit, and in your particular case also prevents the bug that you're encountering.

#4 george7378   Members   -  Reputation: 1251

Like
0Likes
Like

Posted 28 January 2014 - 04:55 PM

Ahh, so simple :) Thanks!



#5 Bacterius   Crossbones+   -  Reputation: 9068

Like
1Likes
Like

Posted 28 January 2014 - 09:51 PM

Is it ever meaningful to normalize a float4 anyway? Apart from the perspective division I can't think of a situation where you'd want to do that rather than normalize the underlying float3.


The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

 

- Pessimal Algorithms and Simplexity Analysis


#6 Hodgman   Moderators   -  Reputation: 31122

Like
2Likes
Like

Posted 28 January 2014 - 10:03 PM

Is it ever meaningful to normalize a float4 anyway? Apart from the perspective division I can't think of a situation where you'd want to do that rather than normalize the underlying float3.

For normalizing a vector (or turning a position into a vector), you'd use a float3, for normalizing a quaternion you'd use a float4.

 

Often in graphics you want to normalize a bunch of weights -- if you've got 4 and your weighting system is based on Euclidean distance, you might find normalizing a float4 handy too biggrin.png

Though usually normalizing weights looks more like weights /= dot(weights, (float4)1)...



#7 Bacterius   Crossbones+   -  Reputation: 9068

Like
1Likes
Like

Posted 28 January 2014 - 10:05 PM


For normalizing a vector (or turning a position into a vector), you'd use a float3, for normalizing a quaternion you'd use a float4.
 
Often in graphics you want to normalize a bunch of weights -- if you've got 4 and your weighting system is based on Euclidean distance, you might find normalizing a float4 handy too 
Though usually normalizing weights looks more like weights /= dot(weights, (float4)1)...

 

I hadn't thought of quaternions, good point!


The slowsort algorithm is a perfect illustration of the multiply and surrender paradigm, which is perhaps the single most important paradigm in the development of reluctant algorithms. The basic multiply and surrender strategy consists in replacing the problem at hand by two or more subproblems, each slightly simpler than the original, and continue multiplying subproblems and subsubproblems recursively in this fashion as long as possible. At some point the subproblems will all become so simple that their solution can no longer be postponed, and we will have to surrender. Experience shows that, in most cases, by the time this point is reached the total work will be substantially higher than what could have been wasted by a more direct approach.

 

- Pessimal Algorithms and Simplexity Analysis





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS