パースペクティブ・マッピング Houdini vs XSI!
アニメでよく利用されるパースペクティブ・マッピングをレイアウトとの連携で紹介します。

パースペクティブ・マッピングは、遠近感のある普通に描かれた絵や撮影された写真をそのままテクスチャマップとして利用する手法です。
その利点は質感を基になる絵や写真に任せることができることです。マテリアルの設定は簡易で、細部のモデリングの必要もありません。
きわめて簡易に3次元のセットをお膳立てできる手法ですが、ポイントはその簡易さよりも最終イメージに近いところから素材を用意して絵作りをする発想の仕方にあります。

この考え方はアニメの現場で取られているレイアウトシステム(※注1)にきわめてなじみが良い考え方です。2D素材を3D空間内に、または逆に2Dレイアウト内に3D素材を違和感なく配置することを容易にします。また手書きの質感を有効に表現することができるのも重要な利点です。

(※注1)絵コンテの後のレイアウトという工程で、絵の構図、カメラワーク、演技プラン、カットの要素の担当分け等(セル作画か美術背景かまたはCGか等)、カットを分業で作るための設計図をここで作成する。
1.レイアウトの検討とBackground画像の準備…Houdini,XSI共通です

【image_2_1.tif レイアウト】
カットのイメージは路地の奥を猫が通り抜けていくのを、カメラが右から左に移動しながらとらえます。
カットの尺は3秒12コマ(24fps)、キャラはセル素材、他は美術素材を想定します。

【image_2_2.tif レイアウト】
決まりごととしてレイアウトのスタンダードフレームは赤枠の範囲(960*720pix)
Houdini&XSI上では少々大きめの緑枠の範囲(1000*750)を素材のスタンダードフレームとします。
(※注2)レイアウト全体はカメラワークを考慮してスタンダードフレームより幅1.75倍の

青枠の範囲(1750*900)としてお膳立てします。
(※注2)実際の仕事においては3D Rendering画像はあくまで映像の1素材でそのままFinishになることはないでしょう。
余計に書き出している部分は次工程のCompositeで切り落とし、他の素材とあわせて納品形態のサイズにリサイズします。

【image_2_3.tif レイアウト】
レイアウトをレイヤー別に分解して保存します。これはマップ画像になります。
Houdiniではパースマップ指定に自由度があるので多種のマップ範囲を混ぜる事が可。XSIもカメラを複数用意できるようになり設定も各カメラごとに変えられるので多種のマップ範囲を混ぜる事が可。softimage|3Dの場合はダミーのヌルに座標値を持たせ
コンストレインそれをドープシートを使って切り替える仕込みが必要で不可能ではないのですがHoudiniと比較すると大変でした…

今回は2種類の範囲で画像を用意しています。
【image_2_4.tif レイアウト】
レイアウトに消失点のマークを入れた画像を保存します。これはモデリングのBackground画像になります。

■ Houdini
2.マッピング用カメラとレンダリング用カメラの作成

【image_3_1.tif Obj+Xform Tab】
レイアウト全体を捉えるマッピング用カメラcam_map1を始めに作成します。

Xform TabでRotation OrderをZXYに設定します。
カメラの回転がY(Hedding) > X(Pitch) > Z(Roll)の順で優先され自然なコントロールができます。
















【image_3_2.tif View Tab】
Resolutionをレイアウトにあわせて(1750,900)に設定。Apertureはフレーム幅がスタンダードの1.75倍なのでAperture=36*1.75に設定します。Focalはまずは50にしておきます。(※注3)
Near,Far ClipはFar Clipがデフォルトでは1000と近すぎるのでもっと大きな値を入れておきます。

(※注3)Houdiniの長さの単位(Unit)は現実の寸法とはリンクしていませんが実寸法との関係を持たせたほうがイメージを掴み易くなります。ここでは便宜的にObjectWorldでの単位を1Unit=1m,ApertureとFocalに関しては1Unit=1mmと捉えて設定をします。
スタンダードのカメラ枠をAperture=36に仮定すると35mmカメラの遠近感に近くなり、焦点距離をイメージしやすくなります。(Focal=50で標準レンズの画角になります。)





【image_3_3.tif Roto Tab】
Roto TabではFileをチェック。Fileの左端の+アイコンをクリックしてBackground画像を選択。Apply Zoom Backgroundはチェックをはずします。

【image_3_5.tif View Tab】
cam_map1をCopy & Pasteしてcam_map2,cam_rendを作成。cam_map1の子供にします。
View TabではResolutionはcam_map2=(1000,900),cam_map2=(1000,750)
Aperture,Focalは両方ともFocal=50(cam_map1と同じ値),Aperture=36とします。

【image_3_6.tif Clop Tab】
レイアウト上でcam_map2,cam_rendの見据える範囲はcam_map1のセンターより左にずれています。カメラをRotateで振って見据える範囲をずらすとパースが変化してしまい不都合ですが、Clop TabのWindow X/Yの設定では範囲を2次元的にシフトことができます。ここでは次の式を設定します。

cam_map2,cam_rend共通:winx=(750-875)/1000+ch("/obj/cam_map1/winx")*1750/1000
cam_map2:winy=ch("/obj/cam_map1/winy")*900/900
cam_rend:winy=ch("/obj/cam_map1/winy")*900/750               (※注4)

(※注4)
cam_map1(Layout1)の左端よりcam_map1の中央までの長さ=C1
cam_map1の左端よりcam_map2(Layout2)の中央までの長さ=C2
cam_map1の幅=W1
cam_map2の幅=W2

cam_map1に対するcam_map2のオフセット値=(C2-C1)/W2
cam_map1のオフセット値のLayout2でのスケール変換値=("cam_map1/winx")*(W2/W1)

cam_map2/winx=(C2-C1)/W2+("cam_map1/winx")*(W2/W1)

【image_3_7.tif Roto Tab】
Roto TabではFileをチェック。画像はcam_map2は$JOB/map/layout_cam2.tif、cam_rendは$JOB/map/layout_rend.tifと指定。Apply Zoom Backgroundはチェックをはずします。



3.ガイド用オブジェクトを利用してカメラを調節

【image_4_1.tif】
Objectの画面でガイドオブジェクトとしてNullオブジェクトを作成、EnterKeyでGeometry(SOP)画面に切り替え、Grid SOPとMerge SOPで消失点合わせガイドを作成します。














































































【image_4_2.tif  Viewer(rotoあり) + DisplayOptions.tif】
Object(OBJ)に戻り、ViewerのCamera選択でcam_map1を選択、Viewer画面上でdを押してDisplayOptionsを出します。DisplayOptions > Background TabでDisplay Background ImagesをチェックしBackground画像を表示します。

【image_4_3.tif Layout + Trans】
cam_map1の高さを設定。レイアウトの中の水平線の位置と人物、建物の対比より1.5mと推測できるのでcam_map1/tyを1.5と入力します。

【image_4_4.tif Layout + CropTab】
カメラのRotateとWindow X/Yを操作してガイドオブジェクトの消失点とレイアウトの消失点を合わせます。一般的な3D SoftではRotateのみで消失点あわせをすることになりますが、HoudiniではCropTabのWindow X/Yを併用して消失点を合わせることができます。
Window X/Yでのシフトを使うとパースを強調せず被写体を見上げたり横から見据えることができます。描きの絵では意識的にパース感をなくしたり、ずらしたりすることが多くありますが、この機能によって意図的にずらしたパースをあわせることができます。今回は横方向のみにこの機能を利用しています。

【image_4_5 Viewer + Grid.tif】
消失点をあわせたところで遠近感のチェックをします。カメラで撮影した素材なら撮影時に焦点距離を残すことができますが、絵ではそれはかないません。描かれている絵より遠近感を読み取るしかないのですが、ダミーのオブジェクトを並べることで読み取りを助けることができます。
このレイアウトでは等間隔の寸法と推定される壁や扉があるので、
それに推定される大きさのダミーオブジェクトを重ねることで遠近感が正しいかどうか評価できます。



















4.パースに添ったモデリング

【image_5_1.tif】
Geometryオブジェクトを新規で配置しGeometry(SOP)に移動。Background画像に合わせて立て看板のようなモデリングをします。
建物が中心なのでGrid SOP,Box SOPを利用します。部分的な頂点編集はVeiwerでEdit SOPを利用します。Textureのレイヤーごとに分けてモデリングをし、グループ付けをしておきます。


【image_5_2.tif】
DeleteでBackfaceを削除してカメラ側を向くSerfaceのみにします。これをUV情報がのり易いようにDivideで細かく分割しておきます。

【image_5_3.tif】
一旦Shader(SHOP)画面に移動してShaderを作成をします。Vex Layered Surfaceを使いLighting Model=Constant、Texture Map=指定ファイル、Texture Tint=Diff + Alphaとします。

【image_5_4.tif】
Geometry(SOP)に戻り、
1.UVTexture SOPでカメラからの視野でUV情報付けをします。Texture TypeをPerspective From Cameraとし、Camera Nameを指定してカメラから投影するようにUV座標を設定します。
2.ShaderSOPでGroupごとにShaderの指定をします。
3.本来キャラクターの部分は作画によって動かしますが、参考テストとしてレイアウト画像をTransform SOPで動かしています。UV情報を付けた後に動かせばObjectはマップごと動き、UV情報を付ける前に動かすとObjectだけ動きマップは取り残されることになります。

6.カメラワーク設定

【image_6_1.tif】
Object(OBJ)でcam_rend/txにアニメーションを付けます。

あとはOutput driverを設定してレンダリングするだけです。設定はProjectを参考にしてみてください。
■ Softimage|XSI
2.マッピング用カメラとレンダリング用カメラの作成


カメラワークを付けて実際にレンダリングするカメラcam_rendとレイアウト全体を捉えるマッピング用カメラcam_map1を作成します。デフォルトで用意されているカメラセットはサイトウ的に使いにくいのでレンダリングするカメラ(以下cam_rend)は次のように構成します
1>各名称を変更
Camera_Root→Cam_rendSET
Camera_Interest→Cam_look
Camera→Cam_rend
2>Cam_rendとCam_lookのParentをcutします。(Ctrl+/)
3>Cam_rendのCam_lookへのDirectionConsが生きている状態なので以下の順番で各値を設定
Cam_look(rx,ry,rz)=(0,0,0),(tx,ty,tz)=(0,0,-20)
Cam_rend(rx,ry,rz)=(0,0,0),(tx,ty,tz)=(0,0,0)
Cam_rendSET(rx,ry,rz)=(0,0,0),(tx,ty,tz)=(0,0,0)
4>Explorerを開きCam_rendのDirectionConsをダブルクリックしてupVectorをoffにします。
*この設定でカメラをオブジェクトのように回転、移動させる事が簡単になりなおかつ注視点を動かしてアニメーションも可能になります。
マッピング用のカメラ(以下cam_map1)はCam_rendSETの
treeセットをコピーしてCam_rendSET(Camera_Root)と
Cam_look(Camera_Interest)を消してカメラ単体にしてしまいます


まずはcam_map1の画角を設定します
Pict,Ratioをレイアウト比率(1750,900)に合わせるので1750/900と入力=結果1.9444に設定されます。
PicelRatio=1
(XSIデフォルトではビデオD1サイズを想定して0.9とされています)

Ver3.0から増えた設定ページProjectionPlaneを開き
Enable on
FocalLength=50(※注3)
Apertureをフレーム幅がスタンダードの1.75倍なので

Aperture X=36/25.4*1.75
結果=X:2.4803,Y:1.2756に設定されます
*この時LockAspectRatioをonにしておいて下さい
PrimitiveページにあるAngleが結果=64.422になっているはずです
(※注3)XSIの長さの単位(Unit)は現実の寸法とはリンクして
いませんが実寸法との関係を持たせたほうがイメージを掴み易くなります。ここでは便宜的にObjectWorldでの単位を
1Unit=1m,ApertureとFocalに関しては
1Unit=1mmと捉えて設定をします。
スタンダードのカメラ枠をAperture=36に仮定すると
35mmカメラの遠近感に近くなり焦点距離をイメージしやすくなります。
(Focal=50で標準レンズの画角になります。)

XSIのAperture単位は何故かinchなのでFocalの単位mmに
合わせてあげるために25.4を掛けてあげます(1inch=25.4mm)
マニュアルを参照するとデフォルトカメラは一応35mmカメラを
想定しているらしいのですがピンとこない数値が設定されているので現実の寸法と馴染みのある数値を入れてしまいます。


cam_map1をCopy & Pasteしてcam_map2を作成。
cam_map1の子供にします
同様にCam_rendSETも子供にします
Pict,Ratioはcam_map2=(1000/900=1.111)

cam_rend=(1000/750=1.333)
Aperture,Focalは両方ともFocal=50(cam_map1と同じ値),
Aperture=X=36/25.4とします。



レイアウト上でcam_map2,cam_rendの見据える範囲はcam_map1のセンターより左にずれています。カメラをRotateで振って見据える範囲をずらすとパースが変化してしまい不都合ですが、ProjectionPlaneページのOpticalCenterShift X/Yの設定では範囲を2次元的にシフトことができます。ここではExpressionEditerを使用して次の式を設定します。

cam_map2,cam_rend共通:
x( ( 750 - 875 ) / 1000 + cam_map1.camera.projplaneoffx
* 1750 / 1000 ) * 0.254
cam_map2:
y=(cam_map1.camera.projplaneoffy * 900 / 900)* 0.254
cam_rend:
y=(cam_map1.camera.projplaneoffy * 900 / 750)* 0.254
(※注4)
cam_map1(Layout1)の左端よりcam_map1の中央までの長さ=C1
cam_map1の左端よりcam_map2(Layout2)の中央までの長さ=C2
cam_map1の幅=W1
cam_map2の幅=W2
cam_map1に対するcam_map2のオフセット値=(C2-C1)/W2
cam_map1のオフセット値のLayout2でのスケール変換値
=([cam_map1のShift x]*(W2/W1)) *0.254
cam_map2のShift x
=((C2-C1)/W2+[cam_map1のShift x]*(W2/W1))*0.254

3.ガイド用オブジェクトを利用してカメラを調節



ガイドオブジェクトとしてNull+Grid,Cube とで消失点合わせガイド
を作成します。消失点を見つける為にZ方向に巨大なGridを作成
Cubeは1Unit=1mのガイドとして1,1,1サイズを用意


ガイドのCubeのセンターは角に移動させておくと便利です。
Ver3.0から付いたObjectViewを使うと選択したオブジェクトだけの画面表示が出せます。移動させたいPointをタグ選択してTransform>MoveCenter to Verticesを実行するとセンターの移動ができます。
個人的にこの機能はよく使うのですが、そういったよく使うモノをボタンにしておくことも便利です。ScriptEditorを開くと実行された履歴が残っていますので…



ボタンにしたいコマンドを選んでCustomToolbar(新しく自分用に作成するのもオススメです)にドラッグ&ドロップするだけで簡単にショートカットボタンが作成できます(Photoshopのアクションみたいに一連の手続きもまとめてボタンにできます)

画面にlayoutを表示させます。
右上の画面表示メニュー内にあるRotoscopeをon
作成しておいたBackground画像を表示します。


cam_map1の高さを設定。
レイアウトの中の水平線の位置と人物、建物の対比より
1.5mと推測できるのでcam_map1/tyを1.5と入力します。

カメラのRotateとOpticalCenterShift X/Yを操作してガイドオブ
ジェクトの消失点とレイアウトの消失点を合わせます。一般的な3DSoftではRotateのみで消失点あわせをすることになりますが、Ver.3.0からはOpticalCenterShiftX/Yを併用して消失点を合わせることができます。

OpticalCenterShift X/Yでのシフトを使うとパースを強調せず被写
体を見上げたり横から見据えることができます。描きの絵では意識的にパース感をなくしたり、ずらしたりすることが多くありますがこの機能によって意図的にずらしたパースをあわせることができます。
今回は横方向のみにこの機能を利用しています。

消失点をあわせたところで遠近感のチェックをします。カメラで撮
影した素材なら撮影時に焦点距離を残すことができますが絵ではそれはかないません。描かれている絵より遠近感を読み取るしかないのですが、ダミーのオブジェクトを並べることで読み取りを助けることができます。このレイアウトでは等間隔の寸法と推定される壁や扉があるので、それに推定される大きさのダミーオブジェクトを重ねることで遠近感が正しいかどうか評価できます。用意した1mガイドのCubeや、同様に約180cmに相当するGridなどで評価して下さい。
こういう場合身近なものの寸法を参考にするとわかりやすく判断できます。例えばだいたい普通の家のドアや窓ガラスのサッシ、畳などは高さが180cmぐらいです。今回の絵の世界にキャラクターが体を出している扉に対して185cm相当のグリッドを合わせるとピッタリきますね。これでこの空間の距離感やオブジェクトのサイズなどが測りだせます。「プロジェクションマップ空間で定規代わりになりそうな身近なモノ」のサイズを知っていると役立ちます。

4.パースに添ったモデリング


Background画像に合わせて舞台セットのように見えるところだ
けの立て看板のようなモデリングをします。Textureのレイヤーごとに分けてモデリングをしグループわけをして、layer分けをしておきます。カメラ側を向くPolygon以外は消してしまいます。

*今回サイトウは手抜きをしましてモデリング済みのオブジェ
クトDATAをHoudiniからもらってきました…
Houdiniの場合頂点数を増やしてUV情報がのりやすいように
していますがXSIの場合その必要はありません。
もっと少ないポリゴン数でモデリングしましょ〜う♪

cam_map1からのモデリング(layer分けをしておくとよい)


cam_map2からのモデリング(layer分けをしておくとよい)


モデルができたらテクスチャーを貼っていきます
マテリアルはConstantを指定。今回はシーンマテリアルを
Constantにしてしまいました。もちろん各オブジェクトの
ローカルに指定してOKです


分けたテクスチャー画像に対応するオブジェクトセットを選んで

Texture>Image、Newより画像を指定。TextureProjectionを
CameraProjectionに設定


そのオブジェクトに投影するべきカメラ(モデリングしたカメラ)
を選択して指定します

Editを押して詳細を設定します


ExplicitからImplicitへ変更。これにより頂点に対してではなく
面に対して貼れるので頂点数が少なくてもキレイにマッピングが
可能です

ここで簡易プレビューするとこのような状態。このままでは
アルファが透明にぬけないので、以下の手順でテクスチャーが
持っているαチャンネルを透明に指定してあげます






PickChannelを使用してαを反転、マテリアルのトランスペアレ
ンスにインプットして透明部分が正しくレンダリングされます。
同様の手順で他のオブジェクトも作業をして出来上がり。
最後にレンダリング用のカメラにてカメラワークをつけて出力