Three.jsでTextGeometryのシンプルなサンプル


このエントリーをはてなブックマークに追加

Three.jsをやってて

Textを三次元で描画したかったがシンプルなサンプルが無かったので

なるべく削ったのをコーディングしてみた

こんな感じになる


  • three.jsはリビジョン r85 を使用
  • ローカルサーバーで動かさない場合、chromeだとcross originエラーが起きるのでfirefoxで動作確認すること

コード


まずコードだけ書くと、下記のようになる。ソースコードはgithubにもおいてます

動いてるデモ

Githubにおいたソースコード

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>TextGeometry three.js</title>
<style>
html, body
{
margin: 0;
padding: 0;
overflow: hidden;
font-family: Monospace;
}
</style>
</head>
<body>
<script src="three.min.js"></script>
<script src="OrbitControls.js"></script>
<script>
var scene = new THREE.Scene();
var aspect = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
var controls = new THREE.OrbitControls(camera);
var axis = new THREE.AxisHelper(1000);
var light = new THREE.DirectionalLight(0xb4e7f2, 1.5);
light.position.set(1,1,1);
light.target.position.set(0,0,0);
scene.add(axis);
scene.add(light);
scene.add(light.target);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.set(50, 50, 200);
var loader = new THREE.FontLoader();
loader.load('helvetiker_regular.typeface.json', function(font){
var textGeometry = new THREE.TextGeometry("Hello Three.js!", {
font: font,
size: 20,
height: 5,
curveSegments: 12
});
var materials = [
new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, overdraw: 0.5 } ),
new THREE.MeshBasicMaterial( { color: 0x000000, overdraw: 0.5 } )
];
var textMesh = new THREE.Mesh(textGeometry, materials);
scene.add(textMesh);
});
var render = function () {
requestAnimationFrame(render);
controls.update();
renderer.setClearColor(0xaabbcc, 1.0);
renderer.render(scene, camera);
};
render();
</script>
</body>
</html>


マウスコントロールするために、OrbitControls.jsも使用しています


参考にしたリンク

three.js/canvas_geometry_text.html at master · mrdoob/three.js

three.js docs - TextGeometry

Three.js TextGeometry (3Dテキスト表示) - Three.jsを使って、作ってみた



THREE.FontLoader()を使用しないといけない?


BoxとかSphereを追加するみたいに単純にnew THREE.TextGeometryしてからMeshに追加していけばいいのかと思ったけど

どうにもうまくいかなかった

まずは、three.js/canvas_geometry_text.html at master · mrdoob/three.js

を参考にしてやってみたところ

動くのは動くが、mouseアクションが追加されていてあまりシンプルでなかった


最低限で動きそうなところ知っておきたかったので公式のドキュメントを参考にして

以下をどうにか動くようにした

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var loader = new THREE.FontLoader();
loader.load( 'fonts/helvetiker_regular.typeface.json', function ( font ) {
var geometry = new THREE.TextGeometry( 'Hello three.js!', {
font: font,
size: 80,
height: 5,
curveSegments: 12,
bevelEnabled: true,
bevelThickness: 10,
bevelSize: 8,
bevelSegments: 5
} );
} );


どうやら、THREE.FontLoader()が必要で

それに対して load メソッドでフォントを指定してあげないと行けないみたい(直接fontを指定してみたけどなんか失敗した)

fontで指定しているhelvetica(helvetiker_regular.typeface.json) は下記からファイルをダウンロードしてhtmlとかと同じディレクトリに入れておく(ディレクトリパスを間違えると読み込めないので注意)

three.js/examples/fonts at master · mrdoob/three.js


  • loader.load内でgeometryが定義されているので同じくこの中でmaterialも定義してあげればよいと考えた
  • 最低限 font, size, height, curveSegments(テキストカーブの分割数、大きいほどなめらかになる)を指定してやれば良さそう

ということで下記のようにした

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var loader = new THREE.FontLoader();
loader.load('helvetiker_regular.typeface.json', function(font){
var textGeometry = new THREE.TextGeometry("Hello Three.js!", {
font: font,
size: 20,
height: 5,
curveSegments: 12
});
var materials = [
new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, overdraw: 0.5 } ),
new THREE.MeshBasicMaterial( { color: 0x000000, overdraw: 0.5 } )
];
var textMesh = new THREE.Mesh(textGeometry, materials);
scene.add(textMesh);
});

これで単純には描画することが可能


materialにはMeshを2つ指定

loader.load内のvar materialsでは配列で引数2つで指定している

これは、第一引数(new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, overdraw: 0.5 } ))は文字の色で

第二引数(new THREE.MeshBasicMaterial( { color: 0x000000, overdraw: 0.5 } )) は側面の色みたい

Three.js TextGeometry (3Dテキスト表示) - Three.jsを使って、作ってみた

いろいろ変えて確かめてみるとよさそう



meshをグローバル変数にしてやるとアニメーションも可能


あまり綺麗なコードではないが、textのmesh変数をグローバル変数に指定してやることでanimationさせてやることも可能

例えば文字をY軸周りに回転させてやる場合は下記になる(js部分のみ記述)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
var scene = new THREE.Scene();
var aspect = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspect, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
var controls = new THREE.OrbitControls(camera);
var axis = new THREE.AxisHelper(1000);
var light = new THREE.DirectionalLight(0xb4e7f2, 1.5);
light.position.set(1,1,1);
light.target.position.set(0,0,0);
scene.add(axis);
scene.add(light);
scene.add(light.target);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
camera.position.set(50, 50, 200);
// textMeshをグローバル変数で指定
var textMesh;
var loader = new THREE.FontLoader();
loader.load('helvetiker_regular.typeface.json', function(font){
var textGeometry = new THREE.TextGeometry("Hello Three.js!", {
font: font,
size: 20,
height: 5,
curveSegments: 12
});
var materials = [
new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, overdraw: 0.5 } ),
new THREE.MeshBasicMaterial( { color: 0x000000, overdraw: 0.5 } )
];
textMesh = new THREE.Mesh(textGeometry, materials);
scene.add(textMesh);
});
var render = function () {
requestAnimationFrame(render);
controls.update();
renderer.setClearColor(0xaabbcc, 1.0);
// textをY軸周りに回転させる
textMesh.rotation.y += 0.01;
renderer.render(scene, camera);
};
render();

なんかもうちょっと良い書き方ありそうだけどひとまず

シンプルな書き方でキレイにloadさせたい場合はfunctionにすればよいのかも

下記が参考になりそう(loadでTextureを貼り付けてるサンプルコード)

three.jsで地球を作ってみよう!〜基礎の基礎編2〜 | それいけ!フロントエンド


このエントリーをはてなブックマークに追加