Ptex のメモ

## Ptex とは

http://ptex.us/

基本的には face(面)に [0, 1]^2 の座標(u, v)を生成し, (faceid, u, v)でテクスチャマッピングを行います.

明示的なテクスチャ座標を割り当てる必要がないので(たとえばメッシュから texture atlas を作るとか), テクスチャ座標を割り当てる作業や, テクスチャのゆがみに悩まされたりという問題が低減します.

Ptex では, 隣接 face 情報も求めておくため, face 間でフィルタリングすることで, face の境界をまたいでのシームレスなテクスチャマッピングがやりやすくなります.

形状としては, 基本的には quad(四角形)になります. 論文では四角形だけでしたが, その後ライブラリとての ptex では三角形や多角形(最低限五角形対応は確認)もサポートするようになっています.

Ptex の主な利用用途はキャラクターメッシュ(人/動物の顔/体など)向け, でしょうか.
(今回も, ptex(xgen)データ付きのキャラクターをコンバートする必要が出てきて ptex を調べました)

Ptex の欠点としては, モデリング/テクスチャリングツールでの対応が必要, GPU 化(HW 化)が面倒, というのがあります. 

VFX 業界では ptex は使われているようですが, リアルタイムグラフィックス方面では普及している感が無いのも欠点です.
(iOS ARKit/SceneKit では USD/OpenSubdiv 対応しているので, iOS では Ptex 対応ももしかしたらしているのかも?)


## Ptex を使う.

http://ptex.us/PtexFile.html

で, ある程度仕様が公開されているので, 自前で ptex ファイルのパーサーとかを書くのが理想ですが, 面倒なのとフィルタリング処理も必要なので, とりあえずは WDAS(Walt Disney Animation Studio)が公開している Ptex ライブラリを使います.

https://github.com/wdas/ptex

CMake のビルドを改善したり(CPU だけバージョンを作る), AARCH64/Android 対応(メモリから ptex ファイルを読み込む)したのを作りましたので, `ptex-aarch64` のほうがビルドがやりやすいです. nanort のサンプルでもこちらを使っています.

https://github.com/syoyo/ptex-aarch64

## API

wdas の ptex ライブラリのドキュメントはあんまり充実してません. doxygen ページがありますが, doxygen で生成したそのものなのでこれだとソースコードのコメントを見たほうが早いでしょう.

また, OpenSubdiv には OpenGL での Ptex(+ subdiv 処理)のサンプルがあります. こちらも参考になります.

https://graphics.pixar.com/opensubdiv/docs/glptexviewer.html

NanoRT で ptex サンプルを作りました.

https://github.com/lighttransport/nanort/tree/master/examples/ptex

### 使い方

基本的には, 

* ptex ファイルを読み込む: open API
* (face_id, u, v) を与えて, フィルタリングする: eval()

だけでいけます. 

## barycentric coordinate

日本語では重心座標と訳されています.
(u, v) で三角形, 四角形を sweep できるようにする媒介変数ですね.

三角形の場合は, NanoRT や embree とかの API で帰ってくる, 交点の (u, v) がそれになります(テクスチャ座標とは異なることに注意).

四角形の場合は注意が必要です. 単純に四角形を三角形二つにして, その三角形の (u, v)から四角形の (u, v)は求まりません.
(平行四辺形の場合はうまく求まります)


今回は, 形状は .ptx ではなく .obj から読み込み, レイトレーシングと相性のよい以下の手法で四角形の (u, v) を求めます.

An Efficient Ray-Quadrilateral Intersection Test
Ares Lage and Philip Dutre
http://graphics.cs.kuleuven.be/publications/LD04ERQIT/LD04ERQIT_paper.pdf

Author が Ares Lagae と Philip Dutre(Advanced Global Illumination のひと)で強い.
ベルギーのルーベンに行きたくなりますね!

### 四角形で重心座標を求める前提条件

convex planar な四角形とする.

優秀な若人さまにおかれましては, 中学数学の幾何で当然のごとく習得済みかと思われますが,
私のような旧教育過程世代では習わなかった気がしますので, 老婆心ではありますが追記しておきます.

三角形では, ３点が必ず同一平面にあり, また凸でありますが, 四角形の場合はそうではありません.

convex = 四角形が凸であること.
planar = 4 点が同一平面上にあること.

それ以外のケースでは, OpenSubdiv で処理したほうがよさそうです(ptex 用 uv 座標を求める関数がある)

## 任意多角形

Ptex では, meta 情報として, 形状データを格納できます. 

http://ptex.us/metakeys.html

形状データでは, pentagon(五角形)などのサンプルもありますが, ptex 自体は quad face までの対応になります.

ptex で保持するための, 多角形から三角形 or 4 角形への分割ルールは特にないようですが, pentagon サンプルを見る限りでは分割については OpenSubdiv のルールあたりを使っているようです.

OpenSubdiv では, pentagon サンプルを見る限りでは, 五角形については, 中心点を求めて, 5 個の四角形に分割するようです.

OpenSubdiv のソースコードを漁れば, もう少し詳しい分割ルールの論文などの文献が見つかるかも...?

## メッシュデータ

optional で, 形状(メッシュ)データ(vertex, face)は上記にあるようにメタデータとして .ptx に保存することができます.
.obj などで形状データとの関連づけをとるのが難しいケースでは, メタデータに形状データを書き込んで .ptx で扱えるようにするのがよさそうです.

## 発展

Cem Yuksel 先生のところでは, Ptex に似たようなものであるが, より扱いやすい mesh color(patch textures)が提案されています.

http://www.cemyuksel.com/research/meshcolors/

http://www.cemyuksel.com/research/meshcolors/patchtextures_hpg2019.pdf

GPU 化もしやすいのが特徴ですが, 実装が無いようです. 
普及するにはまず実装公開などが必要そうですね.


## おまけ

mean value を算出して, mean value ベースで ptex したい.

Mean Value Coordinates for Arbitrary Planar Polygons
https://www.mn.uio.no/math/english/people/aca/michaelf/papers/barycentric.pdf