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 を書きました。これにより、対応するテクスチャの表現をさらに理解できます。以下では、私が学習中に遭遇したいくつかの重要なポイントについて話します。

テクスチャの拡大と縮小#

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

image

テクスチャの拡大#

例えば、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 で詳細に説明されていますが、ここでは展開しません)。この方法は、画像により柔らかいグラデーションをもたらします(上の図の中央部分を参照)。

テクスチャの縮小と 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 グラフィックス学習ガイド

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