このセクションでは、面の変形を学びます。
面を変形させることで、波打つような表現などが可能になります。
面の変形は、頂点の座標を変更することで行います。
3Dでの形は、たくさんの面が集まってできていますが、 それぞれの面は頂点で構成されています。
そのため、頂点の座標を変更することで、面の形状を変えることができます。
頂点の座標を扱うには、オブジェクトのgeometry属性のattributes.positionを使います。
const position = オブジェクト.geometry.attributes.position
こうして得られたpositionは、各頂点の座標を保持しています。i
番目の頂点のx座標を取得するには、
const x = position.getX(i)
とします。
また、i
番目の頂点のx座標を変更するには、
position.setX(i, 値)
とします。
頂点の座標を変更したら、position.needsUpdate = true
を記述することで変更を反映させます。
環境マップなどの反射を使う場合は、さらに オブジェクト.geometry.computeVertexNormals()
で法線を再計算する必要があります。
position.needsUpdate = true
オブジェクト.geometry.computeVertexNormals()
また、position.count
で頂点の数を取得できます。
これを使うと、例えばx座標の値に応じてz座標を変えることができます。segments
を指定することを忘れないようにしましょう。plane
はデフォルトではsegments: 1
になっているので、波打つことができません。
また、フラットシェーディングを有効にすることで、 面の位置の変化をよりわかりやすくしています。
const { camera, create, animate, controls } = init()
controls.connect()
camera.position.set(-6, 6, 6)
create.ambientLight()
create.directionalLight()
const plane = create.plane({
size: 10,
segments: 30,
option: {
flatShading: true,
},
})
const position = plane.geometry.attributes.position
animate(({ time }) => {
for (let i = 0; i < position.count; i++) {
const x = position.getX(i)
position.setZ(i, Math.sin(x + time))
}
position.needsUpdate = true
})
const { camera, create, animate, controls } = init()
controls.connect()
camera.position.set(--6, 6, 6)
create.ambientLight()
create.directionalLight()
const plane = create.plane({
size: 10,
segments: 30,
option: {
flatShading: true,
}
})
const position = plane.geometry.attributes.position
animate(({ time }) => {
for (let i = 0; i < position.count; i++) {
const x = position.getX(i)
const y = position.getY(i)
position.setZ(i, Math.sin(x + time) * Math.cos(y + time))
}
position.needsUpdate = true
})
背景を入れると、よりリアルな感じになります。