【Three.js】3D空間内の単位

コレ大事ヨ
はじめに
前回の続きです。前回はポストプロセッシングについて説明しました。
それ以外にも色々と気づいたことがあったので、今回はそれの説明をしてみようと思います。
前回でも紹介したものがコレです↓。

デモサイトはこちら。
カメラの位置を動かすとこうなります↓。

こんな感じでテレビの枠と画像は分かれていたんですねぇ。以降はテレビの枠を「テレビ」、画像を「ネコ」と呼びます。
単位の話をします
今回はこの3D空間内の単位について説明します。ネコを作成しているコードがこちら↓。
var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load("../assets/textures/animals/cat.jpg");
var geo = new THREE.PlaneGeometry(5, 3.75, 1, 1);
var mat = new THREE.MeshBasicMaterial();
mat.map = texture;
var panel = new THREE.Mesh(geo, mat);
scene.add(panel);
板状のジオメトリと猫の画像を貼り付けたマテリアルをもとにメッシュを作っています。で、ネコの大きさを決めているのが3行目です。横幅が5で高さが3.75。これ単位書いてませんよね。CSSなんかだとpxとかremとかemとか指定するのに…。ずっと「なんでなんだろ」って思いながらほったらかしにしてたんですけど、今回のコレを作ったときに分かりました。
相対距離でした
pxでもremでもemでもありません。「横幅を5としたら高さは3.75ね」って指定しているんです。
ちなみにカメラはz方向に15の位置にあり、ネコは原点にいます。絵にするとこう↓。

この3つの数字は相対的な距離を表しているだけなので、比率さえ同じであればなんでもいいワケです。ネコが500×375でカメラの位置が1500とかでも同じように表示されます。「ほぇ~」と僕。
次はテレビを作るコードを見てみましょう。
var tvElem = document.createElement("img");
tvElem.setAttribute("src","../assets/textures/tv.png");
var tvObj = new THREE.CSS3DObject(tvElem);
scene.add(tvObj);
ネコとだいぶ違いますね。ネコは"THREE.Mesh"クラスを使った3Dオブジェクトですが、テレビはHTMLの<img>タグをもとにした"THREE.CSS3DObject"クラスの3Dオブジェクトです。
1行目で<img>タグを作って、2行目で<img>タグのsrc属性の設定をしています。3行目で"THREE.CSS3DObject"クラスのコンストラクタに<img>タグを渡して3Dオブジェクトを作っています。言ってしまえば<img>タグでできた画像を3D空間で使えますよーってことです。
で、テレビのサイズを決めているのがコレです↓。
tvElem.style.width = "5px";
tvElem.style.height = "5px";
単位ついてますね。ピクセル。しかも5て。めちゃくちゃ小さい。でもコレで大丈夫だぁ。
1px = 1
1pxは相対距離での1になります。何言ってんのかよく分からないので実際に確かめてみましょう。
テレビとネコの位置を合わせる
テレビを原点に移動させました。ネコと同じ位置です。

大きさを合わせる
分かりやすくするためにテレビとネコのサイズを同じにしてみましょう。両方とも5×5。
var geo = new THREE.PlaneGeometry(5, 5, 1, 1);
tvElem.style.width = "5px";
tvElem.style.height = "5px";

見やすくする
ネコの方が大きく見えるのは、テレビの背景が透過されているからです。テレビの背景を塗りつぶしてみましょう。
tvElem.style.backgroundColor = "tomato";

はいピッタリ。テレビとネコがピッタリ重なっています。これで「1px=相対距離の1」ということが分かって頂けたと思います。分かって。
余談
テレビのサイズを"5px"って指定しましたけど、ホントに5pxってワケではありません。そんなに小さかったら見えないですから。


上が初期表示の状態。実際のテレビのサイズは416pxですね。下がカメラを少し遠ざけた状態。207pxになります。
CSSで設定するときはpxとかremとかで実際のサイズを指定すると思うんですけど、Three.jsでサイズ決めるときは考え方が全く違うという事を頭に入れておかないといけませんね。じゃないと混乱します。僕はしました。
あとがき
はい。というワケでThree.jsを使う上での単位についてお話ししました。なかなか良い情報ではないでしょうか。自分で言うのもナンですけど。
「なんかよく分からんけど動いたからヨシ!」ってよくやっちゃうんですけど、今回のコレ作ったおかげで色々と知ることができました。ありがとうございました。
おしゃれ度
★★★☆☆
ディスカッション
コメント一覧
まだ、コメントがありません