LoginSignup
24
4

More than 3 years have passed since last update.

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

Last updated at Posted at 2019-12-12

作ったもの

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 さんお願いします。

24
4
1

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
24
4