作ったもの
アイディアを考え中 🤔💡#webgl #threejs pic.twitter.com/o3sWjJXNkj
— yukidoke (@snowdoke) March 7, 2018
初めに
Three.js Advent Calendar 2019の10日目の記事です。
今回、ご紹介するのはSVGをJSONに変換して、一筆書きのlineを作ろうというものです。
少し古くなってしまうのですが、
three.js r92
blender 2.79
を使用しています。
まず、blenderでSVGをインポートします。
ファイル > インポート > .svg
その際、インポートしたSVGはカーブになっていますので、SVGを選択した状態でAlt + Cを押して、メッシュに変換してください。
次は、インポートしたSVGをJSONにエクスポートします。
ファイル > エクスポート > .json
デフォルトでは、JSONのエクスポートはないため、アドオンを追加する必要があり、こちらの記事が参考になります。
3Dデータ(Blender)をThree.jsで表示するまでの方法
JSONをエクスポートする際のオプションですが今回は頂点情報のみを使用するので、
Geometry
タイプ: geometry
index Buffer: なし
エクスポートするもの 頂点にのみチェックを入れる、でやっています。
コード
頂点座標を配列に追加する関数を書きます。
function addVertexBuffer(geometry, index, x, y, z){
var index = index*3;
var array = geometry.attributes.position.array;
array[index] = x;
array[index+1] = y;
array[index+2] = z;
};
描くlineの設定を書きます。
function drawDynamicLine(){
var geometry = new THREE.BufferGeometry();
// JSONの読み込み
var request = new XMLHttpRequest();
request.open("GET", "think.json", false);
request.send(null);
var json_l = JSON.parse(request.responseText);
var positions = new Float32Array(maxpoints * 3);
geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));
var material = new THREE.LineBasicMaterial({color: 0xffd700});
var line = new THREE.Line(geometry, material);
var points = new Float32Array(json_l["vertices"]);
for(var i=0; i<maxpoints; i++){
var x = points[i*3+0];
var y = points[i*3+1];
var z = points[i*3+2];
addVertexBuffer(line.geometry, i, x, y, z);
}
line.position.z = 0.3;
scene.add(line);
}
繰り返す関数を書きます。
function animate() {
line.geometry.setDrawRange( 0, drawCount );
if(drawCount > maxpoints) drawCount = maxpoints;
drawCount += 2;
line.geometry.attributes.position.needsUpdate = true;
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
Sceneなどを設定します。
function setup() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 100);
var ambientLight = new THREE.AmbientLight(0xffffff);
scene.add(ambientLight);
var directionalLight = new THREE.DirectionalLight(0xffffff);
directionalLight.position.set(1, 1, 1).normalize();
scene.add(directionalLight);
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
drawDynamicLine();
}
setup();
animate();
最後に
個人の感想ですが、lineが時間の経過とともに描かれていくのは、とても面白いです。
僕が作ったものでは、lineがZ軸上は移動していないので、Z軸も移動させるとまた違うものができてくると思います。