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

three.js マウスクリックで一部の面の色を変える

概要

three.jsでクリックした面の色が変わるような物を作ります。
バージョンはr93

デモ:https://arihide.github.io/demos/face_pick/
スクリーンショット 2020-06-28 14.42.12.png

ソースコードはこちら
https://github.com/Arihide/demos/tree/master/face_pick

解説

普通にオブジェクト追加するのと異なる部分に絞って説明します。

material作成時のvertexColorsの指定

以下のように、Materialを作成する際にvertexColorsを指定するようにします。
こうすることで、面ごとに色を指定できるようになります。

var loader = new THREE.JSONLoader();
var mesh;
loader.load('./rough_plane.json', function (geo) {
    var material = new THREE.MeshLambertMaterial({ color: 0xffffff, vertexColors: THREE.FaceColors });
    mesh = new THREE.Mesh(geo, material);
    scene.add(mesh);
    renderer.render(scene, camera);
});

クリック時の処理

次に、クリックされた面の取得および、色変更について説明します。
以下がその処理部分です。

window.addEventListener('click', function (e) {
    //クリックした面番号の取得
    var square = getIntersectedIndex(e);
    if (square !== undefined && mesh) {
        mesh.geometry.colorsNeedUpdate = true;
        mesh.geometry.faces[square].color.set(0x00ff00);
    }
    renderer.render(scene, camera);
}, false);

var raycaster = new THREE.Raycaster();
function getIntersectedIndex(e) {
    var raymouse = new THREE.Vector2();

    raymouse.x = (e.offsetX / width) * 2 - 1;
    raymouse.y = -(e.offsetY / height) * 2 + 1;
    raycaster.setFromCamera(raymouse, camera);
    var intersects = raycaster.intersectObjects(scene.children);

    if (intersects.length > 0) {
        var square = intersects[0].faceIndex;
    }

    return square;
}

ここでは大きく
1. getIntersectedIndexによる面番号の取得
2. 面番号から実際に色を変更
の二つで構成されています。

1. getIntersectedIndexによる面番号の取得

そもそも、three.jsのメッシュには、faceIndexと呼ばれる面一つ一つに割り振られている番号があります。
THREE.RayCasterは交差判定処理をまとめたオブジェクトですが、「どの面番号の面と交差したか?」を調べることもできます。
getIntersectedIndexでは、これらを利用して、「クリックした面の面番号を返却する」処理になっています。

2. 面番号から実際に色を変更

色を変更したい面番号がわかったら
mesh.geometry.faces[faceIndex].color.set(color);
で、色を変更することができます。ただし、rendererに色が変更されたことを知らせるために
mesh.geometry.colorsNeedUpdate = true;
も指定する必要があります。

Arihi
ゲームエンジニアです。業務ではUnityを使ってます。趣味は JavaScript/three.js です。 https://twitter.com/arihide_t
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
ユーザーは見つかりませんでした