SSブログ

ポリゴンレンダラ - その7 [プログラミング]

とりあえず前回で照明の数学はできたことにする。

今日は輪郭線の描画について。

5  輪郭線の描画

輪郭線というのは物理的には存在しない。しかし人間は物体を認識するときにあたかもそれが存在するように感じている。いわゆる漫画やアニメーションでは輪郭線が描かれることが多い。西洋の絵画では大まかに言ってリアリズムが追求されるに従って輪郭線が消失したが、日本画では輪郭線は重要な要素として残った。西洋絵画は印象派の時代になって輪郭線が復活する。それは日本画の影響もあるように言われているが、僕には印象派の輪郭線は二次的な新しい装飾要素として取り込まれたに過ぎない、と思える。

装飾性ではなく、形状把握の助けとしての輪郭線の重要性は、スーラミュシャの絵を較べてみればいい。
0413muchaseurat.jpg

ミュシャの絵はそもそも装飾的で、装飾要素としての輪郭線の重要性が相対的に増しているとは言えるんだけど、それ以上にミュシャの輪郭線は絵に意味を与えているように思える。もともとミュシャの絵はいわゆるポスターだったので、意識していない視線の一瞥で主題が認識されなければいけない。輪郭線はそのために非常に重要な役割を果たしている。ミュシャはそれでは終わらずそのあとに人の視線を引きつける。その要素のひとつは輪郭線による意味の明確化である。それは言葉と結びついている。

逆にスーラは色と光を表現することにしか興味を持っていないことは明らかで、ものの形は違う色が接したことで現れるだけである。したがってスーラの形は角のとれた円筒や円錐などの組み合わせといった単純なものしかない。スーラの絵はまず見る人が注目しないと主題がわからない。

スーラは純粋に絵画的で言葉が存在する余地はまったくないのに較べて、ミュシャには画面に配置された文字だけでなく、画面全体に饒舌な言葉やシンボルがまとわりついている。その違いのせいでスーラの絵は絵を見るしか理解する手段はないんだけど、ミュシャの絵の多くの部分は言葉で語れてしまう。いや、今回はそんなことはどうでもいい。

今回の目的はフォトリアリスティックなレンダリングをしたい訳ではなく、なるべく物体の形状がわかりやすく素早い理解ができるようなものを目指している。そのために輪郭線を引く、というのは形状理解の助けになるのではないか、と思って実装することにした。ようするに、今回はスーラのようではなく、ミュシャのようにレンダリングしたい、ということである。したがって夏の強烈な日差しやモルフォ蝶の羽根の色彩を表現するのは諦める。もともとそんなの難しいけど。

今回ビットマップではなくPDFベースにこだわったのは、光線追跡など他のアプリに使い回ししたかったのもあるけど、面の描画と矛盾しないくっきりとした輪郭線を引きたかった、というのが動機として大きい。

輪郭線は
  • 隣りのポリゴンがないポリゴンの稜線
  • 視点から見て隣りのポリゴンが隠される場合の稜線
のふたつに引くことになる。一つ目は要するに形状そのものの端っこで、ポリゴンが揃った時点で決めることができる。ふたつ目は連続な面が視点から見たときに隣りのポリゴンが見えなくなる場合に引く必要があり、視点からの関係によって決まることになる。

どちらの場合も、あるポリゴンが「隣りのポリゴン」を知っている必要が出てくる。これは結構煩わしい。

例えば図-5のポリゴンAはみっつの稜線を持っている。稜線2と稜線3は接する別のポリゴンがあるが、稜線1にはない。輪郭線はこの稜線1に引くことになる。
0413fig5.png
また、図-6のように視点からみたときにポリゴンBはポリゴンAの後ろになってみえなくなっている。
0413fig6.png
このときポリゴンBとポリゴンAが共有する稜線は輪郭線となる必要がある。

これを判断するには視点からポリゴンへのベクトルと法線ベクトルの内積をとり、隣り合のポリゴンの内積の値と符号が反対であればその稜線を輪郭線にする、という基準で可能である。つまり
0413eq36.png
の符号が負なら共有する稜線を輪郭線にすればいい。

この場合も、隣りのポリゴンを知っている必要がある。

5.0.8  となりのポリゴン

隣りのポリゴンをどうやって知るかというと、他のポリゴンと共有する頂点が2点ある場合、そのポリゴンは接している、つまり隣りのポリゴンである、と言える。そして輪郭線を引く場合はその2頂点を結ぶ直線を輪郭線とすることになる。

共有する頂点が1点だけの場合も隠れる/隠すの関係が発生することがあるが、この場合には引くべき輪郭線はない。また、3点以上共有することは、今回のポリゴンの構成上ありえない。3頂点以上持っているポリゴンはすべての頂点が平面上にあるとしているので、3頂点を共有するふたつのポリゴンはふたつとも同一平面上にあるか、3頂点が直線に並んでいるか、の二通りである。同一平面上にあるならそのポリゴンは合体することができるし、3頂点が直線上にあるならその中の一つは頂点として機能していない(なくても同じポリゴンが表現できる)ということになる。

また、周りが他のポリゴンに囲まれたポリゴンの場合、頂点の数と同じだけの隣りのポリゴンが見つかるはずで、足りない場合、そのポリゴンは端っこにある、と判断できる。

ポリゴンの相対的な位置関係はレンダリング中では変化しない、としているので、ポリゴンが定義されるときに隣りのポリゴンを探して覚えておけばいい。とはいっても、これは総当たりの計算(N個のポリゴンがあるとき、N2/2回探索が必要)になって、実行効率上はかなり厳しい。実装上は効率的な探索が必要になる。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

献立04/14献立04/15 ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。