夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

TriplanarMappingに関して学ぶ

本日はShaderおよびgraphicの勉強枠です。

先日、本ブログとは別に英語の記事で[SpatialAwareness]に関し紹介しました。

seirios48.medium.com

一昨年HoloLensのふるさとアメリカ合衆国Seattleでの旅で出会ったMicrosoftのMRTKを作っておられる方からメッセージがあり、『いいね!TriplanaerMappingと言えば最近こんな記事読んでるんだよね! HoloLensではまだだけど従来よりも軽くなる可能性があるよ!』と次の記事を公開してくださいました!

redhologerbera.hatenablog.com

redhologerbera.hatenablog.com

redhologerbera.hatenablog.com

今回は改めて[TriplanerMapping]に関してと紹介していただいた記事を訳しながらHoloLensに取り組めないかチャレンジしていきます。

www.iquilezles.org

〇TriplanerMappingとは?

[TriplanarMapping]とは一般的にテクスチャ座標であるUVを持たない3Dモデルに対しテクスチャを貼る手法として知られています。

redhologerbera.hatenablog.com

redhologerbera.hatenablog.com

redhologerbera.hatenablog.com

これはTerrainなどの地形に対してテクスチャを貼る方法として非常に優れています。

HoloLensの場合SpatialAwarenessによって生成されるSpatialMeshがまさしくそれに該当し、メッシュが整列することがないためきれいなUVを持っていません。

f:id:Holomoto-Sumire:20200802113341j:plain

このような場合TriplanarMappignが用いられます。

HoloLensの開発ツールであるMRTKに同梱されているMixedReality StanderdShaderではTriplanarMappingのチェックボックスがあり、有効化することでTriplanerMappingを使用できます。

TriplanerMappigの処理として複数の軸からの並行投影などのマルチプロジェクション投影を行っています。

f:id:Holomoto-Sumire:20200802115008g:plain

 これはモデル全体に対して1つの投影を持つのではなく、並行投影、八面体投影、などの複数の投影を共存させて、お互いを補完し合うように投影します。

 テクスチャの引き延ばしが多すぎるために1つの投影によるゆがみが起こり始めた場合、別の投影が補間できることを意味します。

 モデルに複数の投影を割り当てる古典的な、手動で投影を行うことです。アニメ映画を作成しているピクサーには[Picasso]というツールがあり、これは非常に強力なものですが、一般的なアーティストにとっては手間がかかるもののようでした。しかし、それほど強力ではない代わりに、自動的に複数の投影を行うことができる技法が考えられました。

 これが1990年代に開発された[TriplanerMapping]になります。

 TriplanerMappingの考え方として、3 つの投影方向を固定し、それらを空間の正則方向である X, Y, Z にするだけです。そして、3 つの投影マッピングの結果を、それぞれの投影に対するサーフェスの平行度に基づいてカラーブレンドします。

 f:id:Holomoto-Sumire:20200802114144j:plain

これは面の法線とX, Y, Z軸ベクトルのドット積を使用することで実現しています。

redhologerbera.hatenablog.com

この処理をコードにすると以下のようになるようです。

// "p" point being textured
// "n" surface normal at "p"
// "k" controls the sharpness of the blending in the transitions areas
// "s" texture sampler
vec4 boxmap( in sampler2D s, in vec3 p, in vec3 n, in float k )
{
    // project+fetch
    vec4 x = texture( s, p.yz );
    vec4 y = texture( s, p.zx );
    vec4 z = texture( s, p.xy );
    
    // blend factors
    vec3 w = pow( abs(n), vec3(k) );
    // blend and return
    return (x*w.x + y*w.y + z*w.z) / (w.x + w.y + w.z);
}

ここからがオリジナルの記事を執筆されたInigo Quilezさんの考えたTriplanerMappingに変わる軽量の計算方法になるようです。

次回英語と意味を自分なりに訳しながらまとめていきます。