Thread: Angle between two vectors issue

1. Angle between two vectors issue

I'm basically trying to get the angle between two vectors and factor that into a smoothstep which i then use elsewhere:

Code :
```void main()
{
float sampleDepth = texture2D(spec, v_vTexcoord ).r;
vec3 normalPos = vec3(v_vTexcoord.xy,sampleDepth);
vec3 normalVector = texture2D(norm, v_vTexcoord ).rgb;

float brightnessMod = 0.0;
for (float i = 0.0; i < lightNum; i++)
{
vec3 lightPos = texture2D(light,vec2(i,0.0)).rgb;
vec3 lightVector = vec3(normalPos-lightPos);
float angle = acos(clamp(dot(normalize(lightVector),normalize(normalVector)),-1.0,1.0);    // <<< This is the problem line as far as i can tell
brightnessMod += 1.0-smoothstep(0.0,PI/2.0,angle);
}
gl_FragColor = vec4((v_vColour * texture2D( gm_BaseTexture, v_vTexcoord ) * min(brightnessMod,1.0)).rgb,1.0);
}```

From context it seems to me that the "smoothstep()" is allways returning 1, even though the angle should be in [0, pi] but even when i change the "smoothstep()" to "smoothstep(0.0,100000.0,angle)" it still returns 1.

Now am i an idiot and there is a problem with ang = v1 dot v2 (since normalized)? or is there something else going on.

lightVector and NormalVector are both vec3s and i can provide additional context if needed. I'm somewhat fresh on the opengl scene but i cannot for the life of me figure out what is going on.

2. Originally Posted by Kealor1458
Now am i an idiot and there is a problem with ang = v1 dot v2 (since normalized)? or is there something else going on.
If the two vectors are almost colinear, It's possible for dot() returns a value greater than 1 (or less than -1) due to rounding error. In that case, the result of acos() will be undefined.

Other than that, I can't see any issue with the code posted.

3. Originally Posted by GClements
If the two vectors are almost colinear, It's possible for dot() returns a value greater than 1 (or less than -1) due to rounding error. In that case, the result of acos() will be undefined.
What would be the most efficient method to account for this? just a clamp function?

4. I edited the original post to have the entire void main() of the fragment shader, just for context.

5. Originally Posted by Kealor1458
What would be the most efficient method to account for this? just a clamp function?
Or multiply by 0.9999.

Originally Posted by Kealor1458
I edited the original post to have the entire void main() of the fragment shader, just for context.
The brightnessMod variable isn't used, so the variable (and the calculation of its value) will be eliminated. In fact, everything but the last line will be eliminated.

6. My bad, i was attempting to debug by testing other variables and i forgot to change it back to its default, its actually:

gl_FragColor = vec4((v_vColour * texture2D( gm_BaseTexture, v_vTexcoord ) * min(brightnessMod,1.0)).rgb,1.0);
gl_FragColor = vec4((v_vColour * texture2D( gm_BaseTexture, v_vTexcoord )).rgb,1.0);

I fixed the original post to reflect this

7. Originally Posted by Kealor1458
Code :
```	float brightnessMod = 0.0;
for (float i = 0.0; i < lightNum; i++)
{
vec3 lightPos = texture2D(light,vec2(i,0.0)).rgb;```
You should probably be using texelFetch() here. Bear in mind that texture2D() expects normalised texture coordinates.

But even with that mistake, it should work for i==0.

Other than that, the only thing I can suggest is to copy specific variables to gl_FragColor() so that you can check that they have the expected values.

Another potential issue is that applying normalize() to a zero vector is undefined (and may result in NaNs).

8. Originally Posted by GClements
You should probably be using texelFetch() here. Bear in mind that texture2D() expects normalised texture coordinates.

But even with that mistake, it should work for i==0.

Other than that, the only thing I can suggest is to copy specific variables to gl_FragColor() so that you can check that they have the expected values.

Another potential issue is that applying normalize() to a zero vector is undefined (and may result in NaNs).
Ah thanks for catching that out, ive been testing with one light but that would be a problem later, Though it apears that the texelFetch function either doesnt work in my system or im doing something else wrong, this code throws an error (im using openGL ES btw):
Code :
```for (int i = 0; i < int(lightNum); i++)
{
vec3 lightPos = texelFetch(light,ivec2(i,0)).rgb;
//Rest of for loop
}```

Also i have made some progress, im no longer having the issue above, as it turns out i was loading some data incorrectly and the end result was normalizing a zero vector, fixing this had made (almost) everything run smoothly.

Though currently the output is scaled oddly, and the light is emitted in a more elliptical manner for some reason: https://imgur.com/a/7f0yd . Anybody have any ideas? (ill update original post)

9. Originally Posted by Kealor1458
Though it apears that the texelFetch function either doesnt work in my system or im doing something else wrong, this code throws an error (im using openGL ES btw):
OpenGL ES 2 doesn't have texelFetch(). So you need to use (i+0.5)/texture_width (the texture filters should be set to GL_NEAREST).

10. Originally Posted by GClements
OpenGL ES 2 doesn't have texelFetch(). So you need to use (i+0.5)/texture_width (the texture filters should be set to GL_NEAREST).
How come the "+0.5"? Also im having some issues using the texture filter functions as well:

Code :
```	glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);```

throws an error

edit: adding the 0.5 is needed for it to work, also it seems everything is working perfectly on my end now! even without the glTexParameterf setting. Though i am still curious about the two. Thanks alot!

Posting Permissions

• You may not post new threads
• You may not post replies
• You may not post attachments
• You may not edit your posts
•