やりたいこと
Three.js で座標を変更したい!!
要約するとこのあたりのメソッドを駆使すればよい。
点の数の取得
{mesh}.geometry.attributes.position.count
点のXYZ座標の取得
getX()
とかの引数でインデックスを指定することに要注意。
{mesh}.geometry.attributes.position.getX(index)
{mesh}.geometry.attributes.position.getY(index)
{mesh}.geometry.attributes.position.getZ(index)
点のXYZ座標毛の変更
これも引数でインデックスを指定するのに注意。
{mesh}.geometry.attributes.position.setXYZ(i, x, y, z)
点の色の変更
これも引数でインデックスを指定する、かつ、なぜかメソッド名がXYZ(?)
{mesh}.geometry.attributes.color.setXYZ(i, r, g, b);
色や座標に変化があったことを知らせるフラグ
{mesh}.geometry.attributes.position.needsUpdate = true
{mesh}.geometry.attributes.color.needsUpdate = true
このあたりを知っていればなんとかなりそう。
サンプルまでに全体のコード
まずランダムに白い点をうってみる。
コードはこんな感じ。
<html>
<head>
<meta charset="utf-8" />
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.167.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.167.0/examples/jsm/"
}
}
</script>
</head>
<body>
<canvas id="myCanvas"></canvas>
<script type="module">
import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";
// サイズを指定
const width = window.innerWidth;
const height = window.innerHeight;
// レンダラーを作成
let canvas = document.querySelector("#myCanvas")
const renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(width, height);
// シーンを作成
const scene = new THREE.Scene();
// カメラを作成
const camera = new THREE.PerspectiveCamera(45, width / height);
camera.position.set(0, 0, 50);
const controls = new OrbitControls(camera, canvas);
// 適当なデータ作成
let mesh
const vertices = [];
const colors = [];
for (let i = 1; i < 100; i++) {
let x = Math.random() * 10 - 5;
let y = Math.random() * 10 - 5;
let z = Math.random() * 10 - 5;
vertices.push( x, y, z );
let r = 1;
let g = 1;
let b = 1;
colors.push( r, g, b );
}
// 形状データを作成
const geometry = new THREE.BufferGeometry();
geometry.setAttribute("position", new THREE.Float32BufferAttribute(vertices, 3));
geometry.setAttribute("color", new THREE.Float32BufferAttribute(colors, 3));
// マテリアルを作成
const material = new THREE.PointsMaterial({
size: 1,
vertexColors: true
});
// 物体を作成
mesh = new THREE.Points(geometry, material);
scene.add(mesh);
tick();
function tick() {
renderer.render(scene, camera);
requestAnimationFrame(tick);
}
</script>
</body>
</html>
tick()
の中で点の位置や色をぐりぐり変えてみる!
function tick() {
if(mesh){
for(let i=0;i<mesh.geometry.attributes.position.count;i++){
let x = mesh.geometry.attributes.position.getX(i) + (Math.random() - 0.5)
let y = mesh.geometry.attributes.position.getY(i) + (Math.random() - 0.5)
let z = mesh.geometry.attributes.position.getZ(i) + (Math.random() - 0.5)
mesh.geometry.attributes.position.setXYZ(i, x, y, z)
let r = Math.random();
let g = Math.random();
let b = Math.random();
mesh.geometry.attributes.color.setXYZ(i, r, g, b);
}
mesh.geometry.attributes.position.needsUpdate = true
mesh.geometry.attributes.color.needsUpdate = true
}
renderer.render(scene, camera);
requestAnimationFrame(tick);
}