LoginSignup
31
23

More than 5 years have passed since last update.

threejsで座標変換行列の使い方を理解する

Last updated at Posted at 2017-09-28

threejsのshaderMaterialで、自分で用意した行列を使い、MVP変換をやってみる。

3つの変換行列

matrix 説明
modelMatrix ワールド変換行列とも呼ばれる。モデルの位置、モデルの回転、モデルの拡大縮小の情報を持たせる。
viewMatrix カメラを定義するためのもの。カメラの位置、カメラの注視点、カメラの上方向から作られる。
projectionMatrix スクリーンの縦横比や、クリッピング領域の定義、遠近法のような効果を加える。fov,aspect,near,farから作られる。

座標系

上記の各行列をpositionに掛け算することによって以下のように座標系が変換されていく。

座標系 説明
オブジェクト座標系  モデルが原点の座標系
ワールド座標系  ワールドな原点の座標系。オブジェクト座標にmodelMatrixを掛けると得られる。
ビュー座標系 カメラを原点とするような座標系。ワールド座標系にviewMatrix( カメラのworldMatrixの逆行列 ) を掛けると得られる。
クリップ座標系 遠近法的な処理が加えられ -1<x,y,z<1となるような座標系

projectionMatrixによってクリップ座標系に変換される図

赤はカメラから見える領域(四角すいだい)

image

projectionMatrixをかけると、こうなる↓

image

引用元:
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を渡せばよい。

uniform
    uniforms: {
        modelMat: { type: 'm4',     value: modelMat },
        viewMat: { type: 'm4',      value: viewMatrix },
        projMat: { type: 'm4',      value: projectionMatrix }
    }
vertexShader
        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

31
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
23