View Full Version : GLSL normalize and length on zero vectors

Schnulla

08-30-2010, 09:13 AM

Hi,

I wonder how zero vectors are handled by normalize

and length (i.e. normalize(vec3(0.0, 0.0, 0.0)))?

I have some calculations that take a position and

substract another position to get a direction

vector and then normalize this vector.

What happens if both positions are nearly or really

equal thus the direction vector is zero vector?

Somehow I found nothing about this in the spec =/

Thanks!

lobbel

08-30-2010, 09:34 AM

Hello,

you may have a look at NVIDIA's GPU programming guide.

They suggest not to normalize zero-vectors. You can check the

length before normalizing the vector to avoid normalizing

zero vectors or almost zero vectors.

Here is the linkt to the programming guide

http://developer.download.nvidia.com/GPU_Programming_Guide/GPU_Programming_Guide_G80.pdf

regards,

lobbel

Schnulla

08-30-2010, 11:47 AM

Hi!

Thanks for the link. But even if I check the length

like I would do in a software normalize function

I wonder how I should handle length == 0 in the

shader... I mean for example I calculate some

direction vector for a light source or for eye

position and do some lighting calculation based

on this direction vector.

But if I am not able to calculate this direction

vector because he is just zero how should I proceed?

I guess this would require a lot of extra code

for checking and handling this edge case that

might slow down the whole shader? :(

But on the other side it could happen quite often

if my light source touches an object's triangle

or vertex.

david_f_knight

08-30-2010, 12:37 PM

You are right to be concerned about dividing by zero in shader programs. However, I think there's some subtlety to it. The OpenGL spec requires that the GL pipeline not stop in the case of division by zero, but does not specify what a GL implementation must do in that case.

You have a couple choices:

1) you could ignore the GLSL built-in normalize() function, and code a do-it-yourself normalization function that is something like this:

len = length (vector);

normal = (len == 0.0) ? vec3 (0.0, 1.0, 0.0) : vector / len;

2) assume that the GL implementor (nVidia, AMD, etc.) has done something like what is in choice (1) and live with it. The only thing is that since the spec doesn't state what should be done when the length is zero, it is up to each implementor to choose for themselves, which means inconsistent behavior from different GL implementations. Ultimately, though, that may not be a big deal because it *is* wrong to divide by zero, and the result *is* undefined, so there is *no* correct response. It's just a question of having a *consistent* response or not regardless of brand of GL implementation.

In any case, you don't want errors to compound. If the length of the unnormalized vector is zero, then you still want the normalized vector to have a length of 1.0 so that numerical problems downstream won't occur. The direction of this normalized vector is arbitrary.

Schnulla

08-30-2010, 04:20 PM

Thanks for your suggestions!

I think I'll try to somehow handle zero vectors.

Maybe if a light source sits directly on a vertex

and I get a zero vector I just say the fragment

receives maximum possible illumination from this

light source without any further dot product

calculations.

Powered by vBulletin® Version 4.2.3 Copyright © 2017 vBulletin Solutions, Inc. All rights reserved.