threejsのshaderMaterialで、自分で用意した行列を使い、MVP変換をやってみる。
3つの変換行列
matrix | 説明 |
---|---|
modelMatrix | ワールド変換行列とも呼ばれる。モデルの位置、モデルの回転、モデルの拡大縮小の情報を持たせる。 |
viewMatrix | カメラを定義するためのもの。カメラの位置、カメラの注視点、カメラの上方向から作られる。 |
projectionMatrix | スクリーンの縦横比や、クリッピング領域の定義、遠近法のような効果を加える。fov,aspect,near,farから作られる。 |
座標系
上記の各行列をpositionに掛け算することによって以下のように座標系が変換されていく。
座標系 | 説明 |
---|---|
オブジェクト座標系 | モデルが原点の座標系 |
ワールド座標系 | ワールドな原点の座標系。オブジェクト座標にmodelMatrixを掛けると得られる。 |
ビュー座標系 | カメラを原点とするような座標系。ワールド座標系にviewMatrix( カメラのworldMatrixの逆行列 ) を掛けると得られる。 |
クリップ座標系 | 遠近法的な処理が加えられ -1<x,y,z<1となるような座標系 |
projectionMatrixによってクリップ座標系に変換される図
赤はカメラから見える領域(四角すいだい)
projectionMatrixをかけると、こうなる↓
引用元:
http://www.opengl-tutorial.org/jp/beginners-tutorials/tutorial-3-matrices/
threejsで各行列を作り、計算する
いちから作ろうと思ったんですが、難しかったため、threejsが用意してくれてるものを流用。。
threejsでの、各行列の取得の仕方
var obj = new THREE.Object3D();
var cam = new THREE.PerspectiveCamera(fov,aspect,near,far);
//modelMatrix
var modelMat = obj.worldMatrix;
//カメラのモデルマトリックスの逆行列がviewMatrix
var viewMatrix = cam.worldMatrixInverse;
//カメラにすでに用意されているので、これを使う
var projectionMatrix = cam.projectionMatrix;
本当はmatrix.lookAtとかmatrix.perspectiveとかをつかってやりたかったが、また次回。
あとはshaderMaterialへuniformを渡せばよい。
uniforms: {
modelMat: { type: 'm4', value: modelMat },
viewMat: { type: 'm4', value: viewMatrix },
projMat: { type: 'm4', value: projectionMatrix }
}
uniform mat4 modelMat;
uniform mat4 viewMat;
uniform mat4 projMat;
void main()
{
gl_Position = projMat * viewMat * modelMat * vec4( position, 1.0 );
}
normalMatrixも計算してみよう
normalMatrixとはviewからみたnormalを得るためのもの。そんで、ライティングベクトルとのdotを取り、マテリアルへの影響を計算する。
normalMatrixはmodelViewMatrixの逆行列の転置行列らしい。なぜmodelViewMatrixではだめか、はこの記事が参考になる。
mat4 modelViewMat = viewMat * modelMat;
mat4 normalMat = transpose(inverse(modelViewMat));
transpose 転置行列
inverse 逆行列
https://github.com/glslify/glsl-transpose/blob/master/index.glsl
https://github.com/glslify/glsl-inverse/blob/master/index.glsl
ここではgpuでやっちゃったが、ふつうはcpuで計算しておくとよいらしい。
参考にしたページ
http://www.opengl-tutorial.org/jp/beginners-tutorials/tutorial-3-matrices/
https://wgld.org/d/webgl/w013.html
http://esprog.hatenablog.com/entry/2016/04/14/184423