メインコンテンツまでスキップ

視差マッピング

視差マッピング (Parallax Mapping) は、高さマップを使用して平らな表面に深みがあるように見せる手法です。ノーマルマップが表面のライティングのみを変更するのに対し、視差マッピングはカメラの移動に応じて表面上の見え方も変化させます。そのためレンガは単に陰影が付くだけでなく、実際にくぼんで見えます。

これは Standard Material のピクセル単位の効果で、heightMap を割り当てることで有効になります。ノーマルマッピングと同様にタンジェントフレームが必要ですが、UVを持つメッシュでは自動的に用意されます。

ライブサンプル

  • Parallax Mapping - 平らな壁と球体でモードを比較するレンガの部屋
Parallax Mapping
  • Parallax Terrain - 1つの地面マテリアルを広い範囲の距離と角度から見る
Parallax Terrain

2つのモード

StandardMaterial#parallaxMode で高さマップの解釈方法を選択します。

モード説明
PARALLAX_OFFSETデフォルト。高さマップを1回サンプリングしてUVをずらします。非常に低コストで、浅い凹凸の表現には十分です。
PARALLAX_OCCLUSION視線レイを高さフィールドに沿って進め、表面より下に出る位置を求めます。深い凹凸が実際の深さとして見えますが、その分サンプル数が増えます。
material.parallaxMode = pc.PARALLAX_OCCLUSION;
material.heightMapFactor = 0.5;
material.update();
警告

2つのモードは高さマップの解釈が異なります。既存のマテリアルのモードを切り替えたときに、最も驚きやすい点です。

  • offset は中間グレーを元のジオメトリの高さとして扱い、その位置を基準に表面を傾けます。明るい部分はその上に、暗い部分はその下になります。
  • occlusion はマップをジオメトリよりの深さとして扱います。白が表面の位置で、黒が heightMapFactor の深さになります。

そのため offset から occlusion への切り替えでは、凹凸の鋭さが変わるだけでなく、見た目の基準の高さそのものが変化します。

heightMapFactor は両方のモードで深さをスケールします。実用的な範囲はおおよそ 0 から 2 です。それを超えると、この手法で自然に見せられる範囲より深くなり、表面に沿った視線ではテクスチャの伸びが目に見えるようになります。

サンプル数

occlusion モードでは、StandardMaterial#parallaxSamples が視線レイに沿って行う高さマップのサンプリング回数の上限になります。デフォルトは 16 です。

これは固定の回数ではなく上限です。レイがテクスチャ上を進む距離が短いほどサンプル数は減ります。視線が表面に対して正面に近いとき、凹凸が浅いとき、そして表面が遠ざかるときです。レイの移動が1テクセル未満になるとずらすべき情報が残らないため効果は完全にフェードアウトし、遠方の表面のコストはゼロになります。

サンプリングはフォワードパスでのみ行われるため、シャドウパスや深度パスには影響しません。

セルフシャドウイング

StandardMaterial#parallaxShadowSamples は凹凸自身に影を落とします。シェーダーが視線レイの交点からライトの方向へ高さフィールドを進めるため、盛り上がったレンガがその横の目地を暗くします。デフォルトは 0 で、この場合は無効です。

material.parallaxMode = pc.PARALLAX_OCCLUSION;
material.parallaxShadowSamples = 8;
material.update();

影はソフトになります。最初の遮蔽物で打ち切るのではなく、光路がどの程度遮られているかを測り距離で重み付けするため、影を落とす対象に接する部分では鋭く、離れるほど柔らかくなります。サンプル数を増やすと早期に打ち切られるのではなく結果が滑らかになるので、指定した数に対してコストは一定です。8 前後が出発点として適切で、4 を下回るとバンディングが出ます。

注記

セルフシャドウイングはディレクショナルライトのみに適用され、PARALLAX_OCCLUSION が必要です。ライト側ではなく表面側の性質なので、ライトがシャドウをキャストしている必要はありません。

この効果は、ライトが高さマップの起伏を横切るように当たっている場所にのみ現れます。そのためライトがどれだけ低いかと同じくらい、どの方向から当たっているかが重要で、起伏に沿った方向から当たる場合はほとんど現れません。またライトを低くすれば増えるとも限りません。ライトが低くなるほど直接光がまったく当たらない面が増え、直接光を受けていない面には暗くする余地が残らないためです。

制限事項

視差マッピングはテクスチャの参照位置をずらすことで深さを擬似的に表現します。ピクセル自体は移動しないため、そこにこの手法の限界があります。

  • シルエットは変化しません。 凹凸はメッシュの輪郭の内側にのみ見えるため、凹凸のある表面でも縁は直線のままです。
  • 深度バッファは平らな面を見ています。 表面に落ちるシャドウ、スクリーンスペースアンビエントオクルージョン、深度プリパスはいずれも表面を平らなものとして扱うため、凹凸には追従しません。セルフシャドウイングは、ディレクショナルライトについてこれを回避する仕組みです。
  • 浅い角度でテクスチャが滑ります。 参照位置のずれは凹凸の深さと視線角度のタンジェントの積になるため、浅い角度ではカメラのわずかな移動でテクスチャが大きくずれ、表面が泳いでいるように見えることがあります。最も直接的な対処は heightMapFactor を下げることです。

シルエットを変える必要がある凹凸や、シャドウや深度を使う効果に反映させる必要がある凹凸には、ジオメトリ自体を変位させてください。