Help us understand the problem. What is going on with this article?

three.jsでレインボーロードを走ってみた

作ったもの

See the Pen rainbowroad run by cahid (@cahid0814) on CodePen.

事の発端

three.jsを触っている時に「道路を走っている描写作れそう!レインボーロード作れるじゃん!」
と思いついたので勉強がてら作ってみることに。

簡単な解説

それらしく見えれば良いなーくらいで作ってますので作りは雑です。

道路

createRainbowRoad(15.5);
createRainbowRoad(-15.5);
createRainbowRoad(46.5);
createRainbowRoad(-46.5);
function createRainbowRoad(xPosition) {
    let panelGeo = new THREE.PlaneGeometry(30,30,0);
    let panelDistance = 800;
    let group = new THREE.Group();
    let k = 0;
    let colorArray = [
        0xf80000,0xb878f8,0x3058f8,0x00e0a8,0x00f800,0xf8f800,0xf87800
    ];
    for (let i = 0; i < 150; i++, k++) {
      let panelMate = new THREE.MeshBasicMaterial( { color: colorArray[k],specular: 0xffffff, side: THREE.BackSide } );
      let panelMesh = new THREE.Mesh( panelGeo, panelMate );
      let radian = (i / 150) * Math.PI * 2;
      panelMesh.position.set(0, panelDistance * Math.cos(radian), panelDistance * Math.sin(radian));
      panelMesh.lookAt(new THREE.Vector3(0, 0, 0));
      if(k === 6) { k = 0; }
      group.add( panelMesh );
    }
    group.position.x = xPosition;
    scene.add(group);
}

パネルを虹色順に色を指定し、面を原点に向けて円状に量産。
マテリアルの設定をbacksideにして、片面だけ見せる事で地平線に向けて走っているように。

その後円状になったパネルを左右にずらして4つ作成。

星空

createStarField();
function createStarField() {
    let starGeo = new THREE.Geometry();
    for (let i = 0; i < 50000; i++) {
        starGeo.vertices.push(
            new THREE.Vector3(
                3000 * (Math.random() - 0.5),
                3000 * (Math.random() - 0.5),
                3000 * (Math.random() - 0.5)
            )
        );
    }
    let starMate = new THREE.PointsMaterial({
        size: 2,
        color: 0xddddbb
    });
    let starMesh = new THREE.Points(starGeo, starMate);
    scene.add(starMesh);
}

星空っぽく見えるようにポイントを量産して、ランダムに配置。

カメラの動き

run();
function run() {
    runSpeed += 0.2;
    let radian = (runSpeed * Math.PI) / 180;
    camera.position.y = 830 * Math.sin(radian);
    camera.position.z = 830 * Math.cos(radian);
    camera.position.x = 30 * Math.sin(radian * 8);
    camera.rotation.x = 1.2 - (runSpeed * 0.017453286);
    requestAnimationFrame(run);
    renderer.render(scene, camera);
}

カメラを道路から少し離れた箇所から円状に動かし、円の形に沿わせるようにカメラの向きを調整。
走ってる感を出すためにカメラの位置を左右に揺らす。

作った感想

three.jsは単純なものなら簡単に作れて楽しい反面、
ちゃんとやろうとすると数学的な知識や計算、空間把握が求められて難しい・・・

普段はhtmlとcssばかり書いているので、少しずつ出来ること増やしていこうと思います。

:christmas_tree: FORK Advent Calendar 2019
:arrow_left: 12日目 サーバレスの時代だけどハードウェアの話 @momoken
:arrow_right: 14日目 @dashimakitamago さんお願いします。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした