banner
IWSR

IWSR

我永远喜欢志喜屋梦子!

Three.js —— テクスチャ

P5r 天下第一!学妹真可爱!

Mesh は Three.js において重要な概念であり、シーン内で三次元オブジェクトをレンダリングするための主要なコンポーネントです。Mesh は Geometry(ジオメトリ)と Material(マテリアル)を組み合わせることで、レンダラー内に表示できる視覚的なオブジェクトを作成します。

Three.js では、Material は複数の Texture(テクスチャ / マッピング)を含むことができ、オブジェクトの表面の詳細を記述します。例えば、オブジェクトの表面の凹凸は法線マップ(normal map)や変位マップ(displacement map)を使用して表現でき、オブジェクトの表面の環境マッピングは環境光マップ(spherical map /cube map)を使用し、オブジェクトの表面の kd(拡散反射係数、マテリアルの一部の属性)やリアルタイム計算を必要としない影(Ambient Occlusion map)なども Texture を使用して実現できます。

一般的な Texture の種類#

Texture は異なる使用シーンに応じてさまざまな種類に分類されます。以下では、その中で一般的なものを紹介します。

Color Map(カラー マップ)#

Color Map は、カラー情報を三次元モデルの表面に適用するために使用されます。これはオブジェクトのマテリアルの一部であり、モデルに特定の色を与えるために使用されます。Color Texture はオブジェクトの基本的な色を含むことができ、オブジェクトのテクスチャ、パターン、詳細をシミュレートするためにも使用されます。

その役割には以下が含まれます:

  • 基本色: 最も一般的な用途は、オブジェクトに基本的な色を提供することです。純色のテクスチャをオブジェクトに適用することで、オブジェクトに特定の外観を持たせることができます。これは金属、プラスチック、木材など、さまざまな種類のマテリアルをシミュレートするために使用できます。
  • テクスチャ: パターン、テクスチャ、または詳細を含むテクスチャをオブジェクトに適用することで、オブジェクト表面の視覚的な詳細をシミュレートする際に、より多くの制御を提供します。これにより、オブジェクトがよりリアルに見えるようになります(木目、石目など)。
  • 色の変化: テクスチャ内で異なる色の領域を使用することで、オブジェクトの色を異なる部分で変化させ、芸術的な効果を実現したり、オブジェクトの特定の部分を強調したりできます。
  • カスタム効果: Color Texture を使用して、車両モデルにブランドロゴを追加したり、キャラクターモデルに独自の外観を追加したりするなど、さまざまな視覚効果を実現できます。

Alpha Map#

Alpha Map は、三次元モデルの表面上の各ピクセルの透明度値(アルファチャネル)を指定するために使用されます。透明度マップを使用すると、レンダリング時にオブジェクトの透明度を制御でき、透明、半透明、不透明の効果を実現できます。

image

左側の葉のテクスチャは、白黒部分(白い領域が可視、黒い領域が不可視)の Alpha Texture 処理を経て、黒い部分の領域が切り取られ、右側のきれいな葉が得られます。

その役割には以下が含まれます:

  • 透明効果: 透明度マップは、オブジェクトの一部の領域を透明にすることができ、ガラス、水、煙などの透明効果を実現できます。
  • 半透明効果: 透明度マップを使用することで、オブジェクトの一部の領域を半透明にし、視覚的にマテリアルの半透明特性をシミュレートできます(薄霧、雲など)。
  • 不透明オブジェクトの透明部分: 不透明なオブジェクトでも、ガラスの窓など、透明である必要がある部分がある場合があります。
  • 複雑なパターンとテクスチャ: 透明度マップは、カラー マップと組み合わせて、透明な領域を持つ複雑なパターンとテクスチャを実現できます。

Normal Map(法線マップ)#

Normal Map は、レンダリング中に表面の詳細をシミュレートし、オブジェクトの視覚効果を強化するために使用されます。法線マップはオブジェクトの実際のジオメトリ構造を変更することはなく、各ピクセルに法線情報を保存することで光の計算を変更し、レンダリング時にオブジェクトがより多くの詳細と深さを持って見えるようにします。ジオメトリ構造を実際に変更しないため、リアルタイムのライティング下で生成される影も元のジオメトリ構造の状態に留まります。

その役割には以下が含まれます:

  • 詳細の追加: 法線マップは、多角形の数を増やすことなく、オブジェクトの表面に詳細を追加できます。これにより、法線の変化によって光の効果が変化し、凹凸の効果を生み出すため、オブジェクトがよりリアルに見えます。
  • 凹凸効果のシミュレーション: 法線マップは、オブジェクトの表面の凹凸効果(凹み、突起、しわなど)をシミュレートするために使用できます。これらの詳細は、光の計算で影やハイライトを生成し、オブジェクトに質感を与えます。
  • 多角形数の節約: 法線マップを使用することで、オブジェクトの詳細を表現するために大量の多角形を使用する必要がなくなり、計算負担を軽減し、パフォーマンスを向上させることができます。

Ambient Occlusion Map(環境遮蔽マップ)#

環境遮蔽マップ(Ambient Occlusion Map)は、レンダリング中に環境遮蔽効果をシミュレートするために使用されます。これはグレースケール画像であり、各ピクセルはオブジェクト表面の凹みや相対的な遮蔽の程度を示し、レンダリング時のオブジェクトのライティング効果を調整し、詳細感と深さ感を増加させることができます。

その役割には以下が含まれます:

  • 遮蔽効果のシミュレーション: 環境遮蔽マップは、環境内の遮蔽をシミュレートし、暗い角や凹みの領域をより暗く見せることができます。これにより、オブジェクトの深さ感と視覚的な詳細が増します。
  • 表面の質感の強化: 環境遮蔽マップに凹凸情報を保存することで、オブジェクトの表面がよりテクスチャと質感を持って見えるようになります。
  • リアリズムの向上: 環境遮蔽マップを使用することで、レンダリングの現実感が増し、オブジェクトが現実世界のライティングと遮蔽効果に近づいて見えるようになります。

Metalness Map(金属度マップ)#

Metalness Map は、レンダリング中にオブジェクト表面の金属度属性を制御するために使用されます。金属度は、オブジェクトが金属であるか非金属(絶縁体)であるかを決定する属性です。金属度マップは PBR(Physically Based Rendering、物理ベースのレンダリング)で非常に一般的であり、よりリアルなレンダリング効果を実現するために使用されます。

  • 金属度の制御: 金属度マップの各ピクセルは、対応する領域の金属度属性を示すことができます。金属オブジェクトの場合、金属度値は高く、非金属オブジェクトの場合、金属度値は低くなります。
  • 反射に影響を与える: 金属度は、オブジェクトの光の反射の挙動に影響を与えます。金属オブジェクトは高い反射率を持ち、非金属オブジェクトは相対的に低い反射率を持ちます。
  • リアリズムの向上: 金属度マップを使用することで、オブジェクトの異なる部分が異なる金属性質を示すようになり、レンダリングのリアリズムが増します。

Roughness Map(粗さマップ)#

Roughness Map は、レンダリング中にオブジェクト表面の粗さ属性を制御するために使用されます。粗さは、オブジェクト表面の滑らかさを決定する属性であり、粗い表面は光を散乱させ、オブジェクトの反射をぼやけさせ、滑らかな表面はより鋭い反射を生じさせます。

その役割には以下が含まれます:

  • 滑らかさの制御: 粗さマップの各ピクセルは、対応する領域の粗さ属性を示すことができます。高い粗さ値は表面がより粗いことを意味し、低い粗さ値は表面がより滑らかであることを示します。
  • 反射に影響を与える: オブジェクト表面の粗さは、光の散乱の程度に影響を与え、オブジェクトの反射の挙動に影響を与えます。滑らかな表面は明確な反射を生じさせ、粗い表面はぼやけた反射を生じさせます。
  • リアリズムの向上: 粗さマップを使用することで、オブジェクトの異なる部分に異なる粗さを設定でき、レンダリングのリアリズムと視覚的な詳細が増します。

コード#

ここに私は demo を作成しました。これにより、対応するテクスチャの表現をさらに理解できます。次に、私が学習中に遭遇したいくつかの重要なポイントについて話しましょう。

Texture Magnification & Texture Minification (テクスチャの拡大と縮小)#

テクスチャの拡大 / 縮小について話す前に、前提を明確にする必要があります。テクスチャの最小単位である texels(テクスチャピクセル)と pixels(ピクセル)は異なり、前者はテクスチャ自体の精度によってサイズが決まり、後者は物理デバイスによってサイズが決まります。そのため、1 つの texel に複数の pixel が含まれる場合や、1 つの pixel に複数の texel が含まれる場合があることがあります。つまり、texel と pixel は必ずしも完全に重なるわけではなく、テクスチャがモデル表面に適用される際に異常が発生することがあります(例えば、モアレパターンなど)。

image

Texture Magnification(テクスチャの拡大)#

例えば、200 * 200 のテクスチャ画像を 500 * 500 の平面に適用する場合、必然的にぼやけが発生します。テクスチャの各 texel がモデルに適用される際には (u, v) の変換を経る必要があることを理解する必要があります。この例では、テクスチャが引き伸ばされ、1 つのテクスチャピクセルの内容が 6.25 ピクセルに適用されます(つまり、これらの 6.25 ピクセルは色や法線方向など、同じ特性を持ちます)。これは明らかにテクスチャをぼやけさせます(下の図の左側のように)。

image

上の図は私が挙げた例ではありませんが、左側の効果は複数の pixel が同じ texel の値を使用した結果です。Three.js には対応する属性(Three.NearestFilter)も存在します。

NearestFilter は、指定されたテクスチャ座標に最も近いテクスチャ要素の値を返します(マンハッタン距離に基づく)。

NearestFilter の効果は肉眼で見えるほど悪いですが、追加の計算が必要ないため、重要でない内容には選択できます。

さらに、Three.js ではテクスチャの拡大のシーンで LinearFilter のオプションも提供しています。説明から判断すると、このオプションは双線形補間(Bilinear Interpolation)に基づいていることがわかります。

LinearFilter はデフォルトで、指定されたテクスチャ座標に最も近い 4 つのテクスチャ要素の加重平均を返します。これには、wrapSwrapT の値に応じて、他のテクスチャの部分からラップまたは繰り返されたアイテムが含まれる場合があります。

前述のように、対応するピクセルの値はその近くの 4 つのテクスチャピクセルの加重平均であり、この考え方は双線形補間の表れです(Games101 p9 0:28 で詳細に説明されていますが、ここでは展開しません)。この方法により、画像はより柔らかなグラデーションを持つようになります(上の図の中央部分を参照)。

Texture Minification と mipmap(テクスチャの縮小と mipmap)#

拡大の場合とは逆に、単一の pixel 内に複数の texel をレンダリングする場合(下の図のように)。

image

図から、1 つのピクセル内に複数のテクスチャが存在することがわかります。以前の Nearest の方法でピクセル中心に最も近いテクスチャの値を適用すると、明らかに大部分の情報が失われ、ぼやけが発生します(Three.NearestFilter)。では、上で述べた双線形補間(Three.LinearFilter)を使用すれば問題が解決するのでしょうか?もしそのピクセル内に 4 つのテクスチャしか存在しない場合は、ぼやけの問題は解決できますが、1 つのピクセル内に 4 つを超えるテクスチャが存在する場合、ぼやけは依然として発生します。線形補間に参加するテクスチャの数を増やし続ける必要があります。例えば、バイキュービック補間は周囲の 16 点を加重平均して精度を高め、ぼやけを防ぐ方法ですが、計算量を増やすことでぼやけを防ぐ方法は、パフォーマンスに大きな要求を課すことは明らかです。したがって、クライアントの性能負担を軽減するために、グラフィックスでは mipmap と呼ばれる技術が導入されました。これは、他のマシンで計算された結果をテクスチャに埋め込み、縮小時に mipmap 上の既存の計算結果を直接使用することで、クライアントの計算要求を減らすものです(時間を空間で交換することになります。詳細は Games101 p9 0:43 または参考資料の Real-Time Rendering 4th を参照してください)。

image

Three.js における mipmap に関連するオプションは以下の通りです:

  • THREE.NearestMipmapNearestFilter:着色するピクセルサイズに最も一致する mipmap を選択し、NearestFilter 条件(ピクセル中心に最も近いテクスチャ)を使用してテクスチャ値を生成します。

  • THREE.NearestMipmapLinearFilter:テクスチャするピクセルサイズに最も一致する 2 つの mipmap を選択し、NearestFilter 基準から各 mipmap でテクスチャ値を生成します。最終的なテクスチャ値はこれら 2 つの値の加重平均です。

  • THREE.LinearMipmapNearestFilter:テクスチャするピクセルサイズに最も一致する mipmap を選択し、LinearFilter 基準(ピクセル中心に最も近い 4 つのテクスチャの加重平均)を使用してテクスチャ値を生成します。

  • THREE.LinearMipmapLinearFilter:(デフォルト)テクスチャするピクセルサイズに最も一致する 2 つの mipmap を選択し、LinearFilter 基準から各 mipmap でテクスチャ値を生成します。最終的なテクスチャ値はこれら 2 つの値の加重平均です。

Three.js におけるテクスチャの拡大 / 縮小に関連する公式の例はこちらを参照してください。

参考資料#

GAMES101 - 現代コンピュータグラフィックス入門 - 闫令琪

見落とされがちなテクセル密度(Texel Density)について

《Real-Time Rendering 4th》ノート —— 第六章 テクスチャマッピング

Direct3D グラフィックス学習ガイド

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。