Taking fixed direction on hemisphere and project to normal (openGL)
- by Maik Xhani
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.