Elevated で用いられているレイ生成の処理を読んで行きましょう。レイの始点はカメラの位置ですが、レイの向きをどのように求めるか?が主題となります。
Elevated より抜粋
mat3 setCamera( in vec3 ro, in vec3 ta, in float cr )
{
vec3 cw = normalize(ta-ro);
vec3 cp = vec3(sin(cr), cos(cr),0.0);
vec3 cu = normalize( cross(cw,cp) );
vec3 cv = normalize( cross(cu,cw) );
return mat3( cu, cv, cw );
}
...
// camera2world transform
mat3 cam = setCamera( ro, ta, cr );
// pixel
vec2 p = (-iResolution.xy + 2.0*fragCoord)/iResolution.y;
// camera ray
vec3 rd = cam * normalize(vec3(p,fl));
...
カメラ座標系でのレイの向き( normalize(vec3(p,fl))
)をワールド座標系に変換しています。setCamera関数はカメラの回転行列を求めます。
vec3(p,fl)
@kaneta1992 さんの
https://qiita.com/kaneta1992/items/21149c78159bd27e0860#%E3%82%AB%E3%83%A1%E3%83%A9%E3%82%92%E5%AE%9A%E7%BE%A9 を読めばわかります。
setCamera()
setCamera()
は、以下のように分解するとわかりやすくなります。
mat3 lookAt(vec3 eye, vec3 center, vec3 up)
{
vec3 zAxis = normalize(center - eye);
vec3 xAxis = normalize(cross(up, zAxis));
vec3 yAxis = normalize(cross(zAxis, xAxis));
return mat3(xAxis, yAxis, zAxis);
}
mat3 setCamera( in vec3 ro, in vec3 ta, in float cr )
{
return lookAt(ro, ta, vec3(sin(cr), cos(cr), 0.0));
}
lookAt 関数は glm::lookAt などとは異なり、ビュー行列ではなくカメラの姿勢の回転行列を求めているので注意です(ビュー行列はカメラの姿勢の逆行列)。カメラをロールする気がないなら、こちらの lookAt
関数で良いでしょう。