Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: Angle between two vectors issue

  1. #1
    Junior Member Newbie
    Join Date
    Dec 2017
    Posts
    6

    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.
    Last edited by Kealor1458; 12-09-2017 at 10:59 PM.

  2. #2
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,522
    Quote Originally Posted by Kealor1458 View Post
    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. #3
    Junior Member Newbie
    Join Date
    Dec 2017
    Posts
    6
    Quote Originally Posted by GClements View Post
    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. #4
    Junior Member Newbie
    Join Date
    Dec 2017
    Posts
    6
    I edited the original post to have the entire void main() of the fragment shader, just for context.

  5. #5
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,522
    Quote Originally Posted by Kealor1458 View Post
    What would be the most efficient method to account for this? just a clamp function?
    Or multiply by 0.9999.

    Quote Originally Posted by Kealor1458 View Post
    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. #6
    Junior Member Newbie
    Join Date
    Dec 2017
    Posts
    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);
    instead of
    gl_FragColor = vec4((v_vColour * texture2D( gm_BaseTexture, v_vTexcoord )).rgb,1.0);

    I fixed the original post to reflect this

  7. #7
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,522
    Quote Originally Posted by Kealor1458 View Post
    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. #8
    Junior Member Newbie
    Join Date
    Dec 2017
    Posts
    6
    Quote Originally Posted by GClements View Post
    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)
    Last edited by Kealor1458; 12-10-2017 at 03:27 AM.

  9. #9
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,522
    Quote Originally Posted by Kealor1458 View Post
    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. #10
    Junior Member Newbie
    Join Date
    Dec 2017
    Posts
    6
    Quote Originally Posted by GClements View Post
    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!
    Last edited by Kealor1458; 12-10-2017 at 07:19 AM.

Posting Permissions

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