2008年02月

2008年02月29日

ベイク時のUV境界サイズについて modo 301

ここのところ集中してmodoのベイクとディスプレイスメントマップ関連の詳細を調べている。おかげで少しいろんな事が垣間見えてきた。誰からも突っ込みが入らないので、調子に乗ってもうちょっと調べてみたよ。あくまで自分の環境1台でしか試していない事と、何らかの大きな勘違いがあるかも知れないって事だけはあらかじめ断っておくよ。

でもその前に、マニュアルを今更ながら読んでいたら次の記述が見つかったのでちょっと触れておくね。これはユーザーガイド319ページ、スムースポジションについての記述からの抜粋だ。

スムースポジションを無効にできるということは、マイクロポリゴンのポイントの最初の位置を、平坦な元のポリゴンの上に置けるということです。先ほどの例のサブディビジョンしていない球体で、スムースポジションを無効にすると、平面ポリゴンで細分化された球体が出来上がります。この機能を追加した理由は、ベイクデータからディスプレースメントマップを作るときにスムースポジションの機能が邪魔になるからです。つまり、ディスプレースメントマップのポイントの移動距離は、元になった低ポリゴンオブジェクトの元々のポリゴンの位置から割り出されたものなので、スムースポジションを無効にしなければならないのです。

ディスプレイスメントマップを使う時にはどうやらスムースポジションの設定も考えなくちゃならないみたいだ。この事については改めて検証してみようと思う。

さて、今回のテーマはベイク時のUV境界サイズだ。前回の溝問題を解決する切り札として設定されるこのパラメータなんだけど、どうも様子がおかしい。203と301では挙動に差がある。そして203の方がいいような感じなんだよね。

fig02まずその203のベイク境界だ。左の画像をクリックするとUV境界サイズを徐々に大きくした場合にベイクのはみ出し具合がどう変わるかをGIFアニメで見ることが出来る。左上隅だけ他の角と若干形状が違う事を除けば、UVマップの境界から等しく外側にはみ出し部分が広がっていく様子が確認できると思う。

fig01そしてこっちが301の場合。どう見ても左上方向にしかはみ出し部分が拡大して行ってないよね。

fig03不思議な事にアルファレイヤも含んだ画像で同じ事をしてみると、アルファレイヤの部分だけはちゃんとUV境界に対して等距離にはみ出し部分が広がっている。左のGIFアニメのはみ出し部分をよーく見るとグレーの部分と真っ黒い部分があるのが分かるはずだ。グレーになっているのは、はみ出し部分として塗られた部分で上のGIFアニメと同じだ。違うのはその外側で、上のGIFアニメではUVマップの外側が真っ黒なのに対してこのGIFアニメでは外側が薄いグレーだ。実はこの部分こそアルファレイヤで塗りが無効になっている部分で、理想としてはベイク時にはみ出して塗られた画像の外側をぴたりと塗っていて欲しいのだけど、黒い部分ははみ出して塗っている部分とアルファで無効になっている領域の間に隙間が出来て、地の黒い部分が見えちゃっているわけだ。そして、このアルファのマスク画像は203で作ったベイクの塗りと同じ形の穴になっている。要するにアルファレイヤのマスクは理想どおりの形になり、ベイクの塗りは左上に偏っちゃってるって感じだ。

さらにマニュアルを読むと次の記述がある。

この値は3Dペインティングエンジンでも利用されます。Projection Painting(プロジェクションペイント)で、UVの境界線を跨いでペイントを行うとき、UV境界サイズが0だと、同じような黒い境界線が現れてしまうからです。

UVのはみ出しサイズがペイントブラシの塗りのはみ出し量にも影響を与えると書いてあるように見える。しかし実際に試してみたところ、203でも301でもペイントした時のはみ出し量は一定で、初期設定パネルではみ出し量の設定を変えてもペイントではみ出す量に変化は無かった。とにかく不連続UVの境界は外側の部分もディスプレイスメントマップなどに影響を与えるので、UVマップを作成する時には1×1の範囲ギリギリまで作っちゃまずいね。必ず余白を取っておかないとトラブルの原因になるよ。UVマップを自動生成した時なんかは余白が作られないので注意が必要だ(どっかに設定ないのかな?UVの自動生成の際の余白の指定があると便利だよね)。

それではまた次回。

スクリプトまとめページ( Down Load はこちらから)  

カテゴリー別ページ 



take_z_ultima at 11:51|この記事のURLComments(0)TrackBack(0)modo | CG

2008年02月28日

ベイク後の画像について modo 301

自分の環境ではベイクした画像がどうにも上書き保存出来ない。「別名で保存」で保存するぶんには出来るんだけど、何がどうなっちゃったんだろう?

クエリにテクスチャークリップの情報を取得する

query layerservice clip.info ?

っていうクエリがあったので、これを使って調べてみた。そこで分かったんだけど、どうもベイクを使うと画像のアスペクト比が0になっちゃうようだ。これを無理やり保存するとアスペクト比が保存できるフォーマットでは0のまま入っちゃうみたいなんだよね。でもそのアスペクト比を使ってるソフトがあんまり無いみたいで特に問題が無いのが笑っちゃうとこなんだけど、でもやっぱりマズイよな。

コマンド履歴これがその履歴。colorという名前で1024×1024RGBAでPNGファイルを作って、まずはclip.nameをクエリしてIndexがそのクリップであることを調べてから、clip.infoを取った。その結果が

RGBA w:1024 h:1024 bpp:8 pa:1

これは画像がRGBとアルファレイヤの4レイヤ構成で、幅・高さともに1024ピクセルで各レイヤの1ピクセルは8ビット構成で、アスペクト比が1である事を表わしていると思われる。

ベイクそしてこの状態でシェーダーリストからアイテムを右クリックしてベイクした。

その後で再びclip.infoをクエリしたのが上の画像の5〜6行目で、

RGBA w:1024 h:1024 bpp:8 pa:0

ここでアスペクト比が0になっているのが確認できる。

上書き保存この時点で画像タブから「上書き保存」しようとしても保存出来なくなった。そこで「別名で保存」を選んで元の画像と同じPNG形式で保存した後で再びclip.infoをクエリしたのが上の画像の7〜8行目だ。



RGBA w:1024 h:1024 bpp:8 pa:1.11259e-306

アスペクト比は1.11259×10^(-306)というほぼ0に近い小さな値に置き換えられた。でも結局だーれもアスペクト比を使ってないのでphotoshopでもフツーに読めて、保存して戻すとpaは再び0になったwww。

フォーマットのミスマッチそれから、ブランク画像の生成は画像フォーマットに関係なく出来てしまうので、保存の時は注意が必要だ。例えば左の画像はJPEGフォーマットの画像なのにアルファレイヤ付きで各色ともに浮動小数点が扱えるハイダイナミックレンジな画像になっている。こういう場合も上書き保存は出来なくなるんだけど、ファイルフォーマットについての警告ダイアログは出して欲しいところだね。ちなみに「別名で保存」なら保存可能で、その時点で適切なフォーマットを選べばいいわけなんだけど、そこでさらにJPEG形式で保存しちゃっても、表面上は特に問題が出ない。相変わらずアルファレイヤが存在して消しゴムが使えたりする。でも、実際に保存された画像を見ると消しゴムの効果はアルファレイヤに出るので、消したはずのものが残っていたりする。これを「再読み込み」するとアルファレイヤが消えるようで、消しゴムが使えなくなるんだけど、画像の情報自体は相変わらずRGBAのままになっている。

以上の事から、画像保存の時にはフォーマットに注意してね。うっかりすると次に開いた時にびっくり映像になってるなんて事になるからね。たぶんもうすぐ出る302では修正されるんじゃないかな?(あくまで自分予想)。

それではまた次回。

スクリプトまとめページ( Down Load はこちらから)  

カテゴリー別ページ 



take_z_ultima at 12:03|この記事のURLComments(0)TrackBack(0)modo | CG

2008年02月27日

UV境界の謎についていろいろたやってみた modo 301

オブジェクトからベイクした時にUV境界に出た溝みたいなものについてイロイロと試してみた。

まずは現象の再現から。

fig01四角形の板のアイテムを2つY軸方向に50mm離して配置した。下の板にはUVマップが仕込んであり、中央にエッジが1本入っている。この下側の板に画像ファイルを貼り付けて、エフェクトをディスプレースメントにして距離100mmでオブジェクトからベイクした。

べイク結果これがベイク結果をUVマップと重ねてみたもの。ベイク結果はUVマップが明るいグレーで塗りつぶされ、縁より外側が境界を拡張する形で少し広めに塗りつぶされた。

ベイク結果拡大これがUVマップの角の部分を拡大したものだ。ベイクの外側は真っ黒でUVマップのエッジの白い線より外側までベイクのカラーがはみ出して塗られている。このはみ出し部分は初期設定パネルのレンダリングのところの「ベイク時のUV境界サイズ」で調整出来る。

レンダリング結果01これがレンダリング結果。一応ディスプレイスメントマップによって板が50mm浮き上がっていて、ここまでは特に問題ない。

UVを分割してベイクした例次にUVマップだけ真ん中から2つに分けて両者を離してからベイクしてみた。ベイク結果は分断したポリゴンそれぞれに50mmの高さの色が塗られている。これは予想通りだな。左の画像はさらに黄色い丸で囲んだ部分を拡大した画像も重ねて表示してある。

溝が出来たこれがレンダリング結果。そしてこの板の中央を走っている溝が今回のテーマだ。この例ではUVマップのみ分離しただけで現物のメッシュは一切編集していない。上のUVマップを見ても溝が出たUV境界はそれより外まで内側と同じ色で塗られているから、本来ならこんな事が起きるはずが無い。

ここでひとつ気が付くことがあった。それは板の外周のUV境界もUVの不連続境界も、ベイクではみ出して塗られている幅に差が無いのに、UVマップの不連続境界だけが窪んでいるという事である。

メッシュ自体を分離した場合のベイク結果この事実を確認するために、今度は3Dの方で繋がっているポリゴンの片方だけ選択してCTRL+XキーでカットしてCTRL+Vキーで貼り付けて2つのポリゴンを分離してみた。そして同じようにベイクしたのが左の画像だ。見た感じはポリゴンが繋がっていて、UVマップだけが不連続になっていた先の場合と全く変わらない。

メッシュ自体を分離した場合のレンダリング結果これがそのレンダリング結果。思った通りUV境界で発生する溝が消えている。これが意味する事は何だろう?自分が思うに不連続UV境界でのディスプレイスメントマッピングの画像のサンプル点が単純にマップの外側にずれているんじゃないだろうか?

縁を細く塗ってみたさらに、単純なポリゴン境界となったUVマップの境界線付近のディスプレイスメントマップの画像をペイントブラシで塗って、より境界からのはみ出し部分をタイトにしてみた。

縁を細く塗ってみたレンダリング結果これがレンダリング結果。このように溝なんか出来ずに綺麗に繋がっている。UVマップの不連続境界の場合はかなりはみ出させないと繋がらないのに、単なるポリゴン境界になった途端にこれだけタイトにしてもビクともしない。となれば、UVの不連続エッジがディスプレイスメントマップの画像の値をサンプリングする位置が怪しいという結論に達するのは自然な気がする。だがしかし、この予想はちょっと違っていた。

 

UV不連続境界の拡大図さて、これはUVの不連続境界の左端の拡大画像だ。

境界を拡大してレンダリングこれに対応する部分を拡大してレンダリングしたのがこれ。よーく見ると筋は太いものと細いものの2本あることに気が付いた。

UVの縁を塗ってみたまず、不連続UVとポリゴンの縁の2本のエッジから構成された角の部分をペイントブラシで塗ってみた。こうすれば、実際のUV上の境界がレンダリングした時にどこに現れるかわかるだろうと思ったからだ。

縁を塗ってみたそしてこれがレンダリング結果。これにはびっくりした。予想に反して、塗って作った線は溝を越えて向こう側に描かれている。

UV相手側の境界線も塗ってみたさらに相手側の境界も塗ってみた。方向が分かるように右側に縦の線も入れてみた。

相手側の境界線も塗ってみたこれがそのレンダリング結果。2つの境界線を塗ったものはちゃんと1つに重なっている。そしてその両側に例の筋が生じている。要するにこの部分は2つの不連続UVマップの外側の部分が重なって使われていて、出てきている筋のようなものは、不連続UVの相手側の縁より外側にある影が描かれてしまっているもののようだ。ブレンドのためなんだろうか?

ディフューズでレンダリングした場合同じマップをディフューズに変えて下限値を0%に戻してからレンダリングしたのが左の画像だ。このように他のマップの場合はこの外側の余白を重ねるような事はしていない。ディスプレースメントマップだけ特別なようだ。

不連続UV境界に現れる溝の原因?以上、今回の結論はUVマップの不連続境界のディスプレイスメントマップは、UVマップの外側の部分を相手側に重ねてブレンドしていて、その外側の部分が溝として現れているみたいだ。

もちろんベイクの時に余白を広げればこの溝は消えるけど、どこかでこの重ねしろの方の幅を調整できる設定とかあるのかな?

素人考えでは重ねないでもいいような気がするんだけど、どうなんだろう?折れ曲がった時の問題なんだろうなぁ。

それではまた次回。

スクリプトまとめページ( Down Load はこちらから)  

カテゴリー別ページ 



take_z_ultima at 13:12|この記事のURLComments(0)TrackBack(0)modo | CG

2008年02月26日

多階調フォーマットの効果 modo 301

さて、前回はディスプレイスメントマップについてあーでもないこーでもないとやってみたけど、今回もその続きだ。前回まではマップ用の画像として日頃馴染んだJPEGとかBMPとかを使っていた。だけどRGB各8bitで階調が0〜255の256段階しか無いって言うのは滑らかな曲面とかを表わすのにはちょっとキツイ。例えば平らな面に勾配をマップする時に勾配の高低差が128mmだったとすると、BMPやJPEGのマップの諧調では、高さ1mmの階段が128段あるような絵しか作れないわけだな。

そこで登場するのが16bitTIFFとかOpenEXR、HDRなどで、これらはRGBの各色について16bitとか、32bitとか、浮動小数点とかで物凄い数の階調を扱うことが出来る。これを使えばベイクの時に現れたモアレのような凹凸をかなり改善することが出来るようになるはずだ。

シーン例えばこんな感じに2枚のポリゴンを1辺だけ128mm離して斜面にしてオブジェクトからベイクを使って斜面のディスプレイスメントマップを作成してみると、その効果が確認できるはずだ。

手順GIFアニメで作業を撮ってみた。この作業でテクスチャを作成する時に浮動小数点を指定する事で滑らかなディスプレイスメントマップが得られる事が確認できた。ただし、それを記録できないフォーマットで保存して読み込みなおすと、とんでも無い事になる事も確認できた。そして、さらに驚くべき事に、ベイク時に出てくるレンダーウィンドウから画像を保存すると、保存画像がディザリング処理されちゃう事も判明したよ(後述)。

JPEG形式で保存した場合2左の画像は上のGIFアニメの手順で得られたレンダリング結果だ。何だか意味不明にガサガサになっている。これは保存する際になるべくオリジナルに近くなるように、modoが小数点以下の数値をディザリング処理してくれてるからなんだろうね。

JPEG形式で保存した場合1左の画像は同じようにベイクしたディスプレイスメントマップなんだけど、ベイク時点で保存しないで、シーンファイルと一緒にファイルメニューから「全て保存」を使って保存して、再び開いたもの。こっちは階段状の画像になっている。どうやら画像の保存も2通りあるみたいだね。こっちでは浮動小数点から整数に変換される時に単純に小数点以下の数値が丸められているようだ。いずれにしてもRGB各8bit256階調しか持たない画像フォーマットでは、斜面もこのような階段状になって現れてしまう事が確認できた。

同じ手順で他のフォーマットも試してみた。ここで意外な事がわかった。ベイク後のレンダーフレームから保存した画像は、どれもみなディザリングされてしまって開きなおすとガサガサな表面になってしまった。だからベイクしたものをこの時点で上書き保存しちゃダメなんだな。保存するなら画像タブから行うか、ファイルメニューからやらないと、せっかくの浮動小数点が台無しだ。

画像タグから保存ベイクした画像はこっちから保存ね。ちなみにいくら上書きしても*マークが消えないのは何故なんだろう?保存した後再読み込みすれば消えどね。
注)どうやらオブジェクトからベイクをすると上書きが出来なくなるようだ。保存する時は「別名で保存」かファイルメニューの「全て保存」で保存する必要があるようだ。

HDR形式で保存した場合これでHDRとか16bitTiffとかOpenEXRとかのファイル形式で保存すれば、無事に滑らかなディスプレイスメントマップ画像が得られるってわけだ。

以上の事からディスプレイスメントマップ画像は多階調表現が可能なファイルフォーマットで、画像タブまたはファイルメニューから保存する必要があることがわかった。それから新規にブランク画像を作る時は浮動小数点のチェックを忘れずにね。これを忘れると、どんな形式で保存してもグラデーションがガタガタの階段になっちゃうよ。再読み込みした時にどうなるかまでは検証していないけどね。

まあ自分の早合点かも知れないので各自で確認してみてね。

それではまた次回。

スクリプトまとめページ( Down Load はこちらから)  

カテゴリー別ページ 



take_z_ultima at 12:57|この記事のURLComments(0)TrackBack(0)modo | CG

2008年02月25日

混合栓のハンドルを作ってみた その9 modo 301

さて、溶接跡みたいになっちゃったディスプレイスメントマップの続きだ。

まず最初にチェックしなくちゃならないのは、オブジェクトからベイクする時の計測範囲だ。ご存知のように一部の画像フォーマットを除いて色を表わす数値にマイナスは存在しない。だから現在のレベルより窪んでいる状態をディスプレイスメントマップで表わすためにはテクスチャレイヤのプロパティの上限値と下限値を調節して、色を表わす数値の範囲をマイナス側にも振ってやらなくちゃならない。前回自分は下限値−100%、上限値100%にした。こうすることで、256段階のグレースケールなら0が−100%、255が+100%になり、その間の数値は比例で按分される。ディスプレイスメントマップの場合この値にマテリアルのディスプレースメント距離を掛け合わせたものが実際の変位量になるわけだ。

しかしここにひとつの落とし穴があった。自分は範囲をマイナスに振っておけば、ベイクの時に計測される範囲もマイナス側に振ってもらえて、指定した距離より遠いものはその距離でスライスされて飽和するものと思っていた。でもそれは大きな勘違いだった。

オブジェクトからベイクのためにセットアップしたシーン例えば1m角の立方体とそれを複製して、2枚の面を50mmインセットしてからそれぞれ+100mmと−100mmオフセットした左の画像のような立体を重ねてオブジェクトからベイクでディスプレイスメントマップをベイクしてみた。ベイクしてみて気が付いたんだけど、オブジェクトからベイクをすると画像の上限値と下限値は自動的に−100%と+100%に設定されるようだ。親切機能だけど気をつけないと酷い目に遭いそうな機能だな。まあそれはいいとして、ベイク時の距離は凹凸のオフセット距離である100mmにしてみた。

100mmでベイクこれがその結果。凹凸が無い部分が50%グレーになったって事は上限下限値の設定が効いているって事で、変位距離0が色の中間値になっているわけだ。そして左側に真っ白い領域があるのは100mm出っ張っている部分だ。あれ?−100mmで窪んでいる部分は?ここでようやく重大な事実に気が付いた。範囲外のものはサーチされないんだな。前に試して確認していたつもりが勘違いしていた。オブジェクトでベイクで現れるのは、指定した距離の範囲で、それを超えたものは無いものとしてオフセット距離0になる仕様だったんだね。色の段階が256段階の偶数で、0がある都合、マイナス側はちょっと足りなくなって100mm離れたポリゴンはサーチ範囲外に行ってしまっているわけだ。そしてサーチ出来ないので当然ディスプレイスメントマップは50%グレーで塗りつぶされたって訳だ。

101mmでベイク試しに範囲を101mmにしてベイクしてみたのが左の画像だ。今度は窪みもちゃんと現れている。このことから範囲はちゃんととらないと、範囲を超えた部分で大きく凹凸がブレる事態が起きることが容易に想像できる。
長々と書いてきたけど上記の勘違いは今回のボコボコな縁にはあてはまるのだろうか?残念ながらサーチ範囲10mmはかなり大目にとっていてて、実際には5mm程度で間に合うくらいの切り欠きだ。

ところで冒頭にも書いたけどベイクした時に得られた数値はどのように変位距離に変換されるかと言うと、まず色の数値の範囲である0〜255の値を下限上限の範囲から、パーセンテージに直される。今回は−100%〜100%が下限上限の設定なので、

変位量=(ベイク色×(上限−下限)÷色のレンジ+下限)×ディスプレースメント距離

=(ベイク色×(1−(−1))÷256+(−1))×ディスプレースメント距離

のようになるのだと思う(この式は数値の丸め誤差とかまでは考慮していないので実際にベイクで求めた値とは±1くらい誤差が生じると思う)。この変位量が計測に使ったメッシュと貼り付けるメッシュの間の距離と等しくなれば、ディスプレースメントマップで変形したものと、計測に使ったメッシュの形状が同じになるわけだ。
計測距離範囲を10mmにしてベイクした場合、実際の変位量が5mmだったとすると、ベイク色は0〜255を−10mm〜10mmとして計算して、

((5−(−10))÷(10−(−10))×256=192

この192というベイク色が5mmの変位量に戻るためにはディスプレースメント距離は計測距離範囲と同じ10mmにしないとならないわけだ。

変位量=(192×(1−(−1))÷256+(−1))×10

=5mm

前回のレンダリング結果の切り欠きが妙に浅かったのは、計測距離範囲を10mmにしてベイクしたにも拘らず、ディスプレースメント距離を10mmにしていなかったのが原因のようだ。

距離を調整してレンダリングこれが修正したもの。切り欠きの縁は出て来たようだ。でもUV境界に溝が出来てしまっている。

UVの継ぎ目を拡大このUV境界に出来てしまった溝を解消するために、今度はスカルプトのユーティリティータグにある「UVの継ぎ目を拡大」で境界部分の画像を広げてみた。溝は解消して行くようなんだけど、それはそれでまた新たな問題が発生しているような感じだ。

高解像度のテクスチャかなり煮詰まって来たのでややこしい部分を出来るだけ小さくする事を考えてみた。それにはマップを高解像度にするのが一番。そこで思い切って4096×4096にしてベイクしてからUVの継ぎ目を拡大したのがこの画像。ずいぶんマシになったけど・・・。

膨らませてからベイクしてみたそこで今度はベイクされる側のメッシュをスケーリングして、切り欠きを作ったメッシュから少し離してみる事にした。左の画像はスケールで膨らましてからベイクした結果。おーなんだかいい感じになって来た。

以上いろいろ奮闘してみたんだけど、結論から言えば、マップ境界を変えるのが一番手っ取り早い。ミもフタも無い話だけどね。

変更したUVマップこれは切り欠き部分にUV境界が来ないようにして、なるべくマップを切らないようにUV展開しなおしたものだ。

UVマップの境界位置を変更したレンダリング結果これを使ってベイクしたマップでレンダリングしたのがこれ。今までの苦労が嘘のようにいとも簡単に仕上がっちゃった・・・。しかもこの場合はマップの不連続エッジでの溝も出てきていない感じだ。以上を考えるとディスプレイスメントマップ用のUVマップはあまり急峻な変動位置で分断しないほうがいいみたいだな。逆に言うと、この問題はUVマップの不連続境界での誤差によるノイズなわけだから、マップ境界をアンチエリアシングする代りに境界部分の計算用に分断されている相手側のマップを持ってきて、繋いで計算すれば済む話なんじゃないだろうか?

合成マップによるレンダリング結果そこでマップを複製して2つ作り、それぞれ境界部分をずらしてベイクし、合成してみた。これがそのレンダリング結果。急いで処理したのでこの結果を持って語るのはちょっと怪しいかも知れないけど、予想は外れている感じだ。どうもアンチエリアスだけの問題でも無さそうだな。この境界問題はもう少し研究してみる必要がありそうだ。時間がなくなったので今回はここまで。
今回の結論は、「無理して難しいことしないでUVマップを作り直せ」って事で、ひとつwww。



それではまた次回。

スクリプトまとめページ( Down Load はこちらから)  

カテゴリー別ページ 



take_z_ultima at 14:36|この記事のURLComments(0)TrackBack(0)modo | CG
Archives