教育機関向け活用例

2. テクスチャの利用

このセクションでは、テクスチャを使った3Dオブジェクトの作成方法を学びます。

テクスチャ画像の用意

テクスチャとは、3Dオブジェクトに貼り付ける画像のことです。
背景画像と同じく、無料で入手するには、 Poly Haven のようなサイトを利用すると便利です。
テクスチャ画像は、Poly Haven では Textures として配布されています。

ここでは、Poly Haven のCoast Sand Rocks 02を利用してみましょう。
ページ右上のところで、「1K」の解像度を選択し、 その右の形式の選択では「ZIP」を選んでおきます。
ダウンロードボタンの右のメニューから 「Diffuse」と「Normal(GL)」のJPG形式を選択してダウンロードします。

ダウンロードした画像は、 プログラムのファイルと同じ場所に配置してください。

Diffuse は、色の情報を持つ画像で、 いわゆる通常の画像です。
Normal は、法線マップと呼ばれる情報を持つ画像で、 3Dオブジェクトの凹凸を表現するのに使います。

テクスチャの設定

テクスチャを読み込むには、load.texture を使います。

load.texture(画像のパス)

今の場合、次のようにするとキューブにテクスチャが設定されます。

index.html
const { camera, create, animate, controls } = init()

controls.connect()
camera.position.set(0, 1, 2)
controls.autoRotate = true
create.ambientLight()
create.directionalLight()

create.cube({
  option: {
    map: load.texture("./coast_sand_rocks_02_diff_1k.jpg"),
  }
})

animate()

実行すると、キューブにテクスチャが貼り付けられます。
ただ画像を貼り付けただけなので、表面のデコボコ感はありません。

法線マップを使うことで、3Dオブジェクトの凹凸を表現することができます。
その場合は、次のようにします。

index.html
const { camera, create, animate, controls } = init()

controls.connect()
camera.position.set(0, 1, 2)
controls.autoRotate = true
create.ambientLight()
create.directionalLight()

create.cube({
  option: {
    map: load.texture("./coast_sand_rocks_02_diff_1k.jpg"),
    normalMap: load.texture("./coast_sand_rocks_02_nor_gl_1k.jpg"),
  }
})

animate()

法線マップがあるものとないものを並べてみると、 次のようになります。
左が法線マップなし、右が法線マップありです。

表面の質感のリアルさが全く違うことがわかります。

このように、法線マップを使うことでよりリアルな3Dオブジェクトを作成することができますが、マップ画像の用意は場合によっては難しいことがあります。
そのような場合は、通常のテクスチャ画像をバンプマップとして使うことで、似たような効果を得ることができます。

バンプマップとは、法線マップと同じように凹凸を表現する画像ですが、 ピクセルの明るさを使って凹凸を表現します。
普通、白い部分が凸、黒い部分が凹となることが多いため、通常のテクスチャ画像を使うことができます。

バンプマップを使う場合は、bumpMap を設定します。
また、凹凸の強さを設定するために、bumpScale を使います。

同じ画像を2回読み込むのは効率が悪いので、load.texture で読み込んだテクスチャを変数に保存して使いましょう。

index.html
const { camera, create, animate, controls } = init()

controls.connect()
camera.position.set(0, 1, 2)
controls.autoRotate = true
create.ambientLight()
create.directionalLight()

const texture = load.texture("./coast_sand_rocks_02_diff_1k.jpg")
create.cube({
  option: {
    map: texture,
    bumpMap: texture,
    bumpScale: 3,
  }
})

animate()

法線マップの場合とバンプマップの場合を比較すると、 次のようになります。
左が法線マップ、右がバンプマップです。

バンプマップは法線マップよりも簡単に使える反面、 凹凸の表現が荒いことがあります。
また、凹凸の強さを調整するために、bumpScale を設定する必要があります。

1つのオブジェクトに対して、1つのテクスチャを繰り返し貼ることもできます。

create.cube({
  option: {
    map: load.texture("./coast_sand_rocks_02_diff_1k.jpg", {
      repeat: [2, 3],
    }),
  }
})

このようにすると、テクスチャが横に2回、縦に3回繰り返し貼られます。

テクスチャを使うことで、3Dオブジェクトの表面の質感をリアルに表現することができます。
基本的には法線マップを使うことが望ましいですが、 難しい場合はバンプマップを使うと良いでしょう。