Taking fixed direction on hemisphere and project to normal (openGL)

Posted by Maik Xhani on Game Development See other posts from Game Development or by Maik Xhani
Published on 2014-07-23T11:18:27Z Indexed on 2014/08/24 16:30 UTC
Read the original article Hit count: 410

Filed under:
|

I am trying to perform sampling using hemisphere around a surface normal. I want to experiment with fixed directions (and maybe jitter slightly between frames). So I have those directions:

vec3 sampleDirections[6] = {vec3(0.0f, 1.0f, 0.0f), 
                            vec3(0.0f, 0.5f, 0.866025f),
                            vec3(0.823639f, 0.5f, 0.267617f),
                            vec3(0.509037f, 0.5f, -0.700629f),
                            vec3(-0.509037f, 0.5f, -0.700629),
                            vec3(-0.823639f, 0.5f, 0.267617f)};

now I want the first direction to be projected on the normal and the others accordingly.

I tried these 2 codes, both failing. This is what I used for random sampling (it doesn't seem to work well, the samples seem to be biased towards a certain direction) and I just used one of the fixed directions instead of s (here is the code of the random sample, when i used it with the fixed direction i didn't use theta and phi).

vec3 CosWeightedRandomHemisphereDirection( vec3 n, float rand1, float rand2 )
    float  theta = acos(sqrt(1.0f-rand1));
    float  phi = 6.283185f * rand2;

    vec3 s = vec3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));

    vec3 v = normalize(cross(n,vec3(0.0072, 1.0, 0.0034)));
    vec3 u = cross(v, n);
    u = s.x*u;
    v = s.y*v;
    vec3 w = s.z*n;

    vec3 direction = u+v+w;
    return normalize(direction); 
}

** EDIT **

This is the new code

vec3 FixedHemisphereDirection( vec3 n, vec3 sampleDir)
{
    vec3 x;
    vec3 z;

    if(abs(n.x) < abs(n.y)){
        if(abs(n.x) < abs(n.z)){
            x = vec3(1.0f,0.0f,0.0f);
        }else{
            x = vec3(0.0f,0.0f,1.0f);
        }
    }else{
        if(abs(n.y) < abs(n.z)){
            x = vec3(0.0f,1.0f,0.0f);
        }else{
            x = vec3(0.0f,0.0f,1.0f);
        }
    }

    z = normalize(cross(x,n));
    x = cross(n,z);

    mat3 M = mat3(  x.x, n.x, z.x,
                    x.y, n.y, z.y,
                    x.z, n.z, z.z);
    return M*sampleDir;
}

So if my n = (0,0,1); and my sampleDir = (0,1,0); shouldn't the M*sampleDir be (0,0,1)? Cause that is what I was expecting.

© Game Development or respective owner

Related posts about opengl

Related posts about multisampling