Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
[go: Go Back, main page]

Progressive landscape [II]
12/2 プログレッシブな地面[II]/プロトタイプと反省





Proto-type

 考えたら即実行(希望)の俺なので、昨日考えたプログレッシブ・ランドスケープをとりあえず実際にやったらどうなるか試してみた。


 右の図は今回作ったアルゴリズムで分割したランドスケープのワイヤーフレームを上空から見下ろしたものだ。

 この図を見ると、きちんと指数関数的に中心(視点を置く位置)が密、外周が疎となっているのがお解りいただけるであろう。

 分割のアルゴリズムは単純で、4×4のマトリクスの、中央2×2の部分を取り除いたものをまず描画し、次にその中央部を4x4分割して同じ操作を繰り返すという再帰的な方法を使っている(無論、プロトタイプとはいえ速度の低下を嫌って再帰関数を使ってはいない)。

 このような再帰ループを繰り返すと、最終的に中央部に穴が空いてしまうが、その部分に関してはごく普通のランドスケープアルゴリズムを適用している。
 どのみち、当初から視点付近は普通に描画する予定だったので、これについては問題ない。
 速度だが、当然のことながらごく普通にランドスケープを描画するよりも圧倒的に高速だ。
 とりあえず256x256のランドスケープを4段の再帰を使って描画させても(ろくな最適化をしていないにも関わらず)30fps近い速度が出る。

 ちなみにこの再帰ループは、実際に使用するときには、あらかじめ視点から各ポリゴンへのオフセット値を計算しておき、使用する時には単純加算するだけでなんの工夫も必要なくポリゴン化できるので実装時のオーバーヘッドはゼロだ(なぜなら、同面積を普通に描画する場合はより多くの加算が必要だからだ)。

 また、一見気がつきにくいが、重要なのは各再帰図形の外周の辺の処理である。

 これは、スムースシェーディングでエッヂを一致させるために、外周に面するポリゴンの外周の辺だけは一段大きい再帰図形の内周と一致しなくてはいけない。しかし、内周はかならず2x2ポリゴンぶんの辺があり、外周はかならず4x4ポリゴンぶんである。

 この差を埋めるためには、とりあえずここでは単純に線形補完している(といっても、足して2で割っているだけだ。オーバーヘッドは推して知るべしだろう)。


 
 肝心の実行結果だが、こちらは少々(かなり)残念な結果になってしまった。

 図の、上がノーマルの状態、下が今回のアルゴリズムを使った場合である。

上の図で、比較的視点に遠い起伏が、簡略化されて再現されているのがわかるだろう。
しかし、視点の遠方にあるコブは、見る影もなくなってしまっている。

 処理速度レベルでは、既にノーマル状態とは比較にならないので、近傍の起伏もきちんと再現できることだし、ここでやめてしまってもいいのだが、もうひとひねり欲しい。

 だいいち、かなり不自然である。残念ながら、上の図と下の図を比べて、ほとんどかわらないでしょう?とは言えない悔しさがある。

 この原因はハッキリしている。それは、指数間数的な収束があまりにも早く収束しすぎることである。

 視点と物体との距離、そして物体の視体積は指数関数的な関係になっている。しかし、この場合は、再帰ループ一段につき、ひとつのポリゴンの大きさは面積比にして4倍だ。たったの4段再帰するとしても、面積比は256倍にも膨れ上がる。
 要するに、この速度でポリゴンを簡略化していくのは、あまりにも早すぎるのだ。結果、ポリゴンは省略されすぎてしまうのである。

 これを解決しない限り、プログレッシブ・ランドスケープは単なる机上の理論で終わってしまうだろう。
 

   無論、おれは失望などしていない。

 既にいくつかの解決策を考えている。

 まず、地表が自然物であることを利用して、地表の隆起をエネルギーに見立て、遠方の描画を碁盤目ではなく、フラクタル的に簡略化する方法。これは相手が地形であるだけにうまくやれれば効果は絶大だろう。

 しかし、この方法は簡単に(数時間以内には)理論化できない。

 そこで、今回の方法の応用としてより簡単に実装でき、なおかつ実用性がありそうなのは、右図のように一次元フラクタルパターンで簡略化する方法である。

 二次元フラクタルでうまくいかないのに、どうして一次元だと上手くいくのか?

 それは、二次元フラクタルと違い、一次元の時間軸方向をZ軸プラス方向とし、時間軸の幅を二次元的に設定することによって、正方形のフラクタル図形を作るよりはずっと合理的に簡略化処理が行えるからである。

 この場合は、収束速度は二次元フラクタルと変わらないのだが、劇的に変化するのはその適用範囲である。
 一次元フラクタルだからといって、時間軸を一定の割合で進めなくてはいけないという法はない。むしろこの時間軸はこちらに都合の良いステップで(それこそ指数関数的に)はばをもたせてとれば良い。そうすると、二次元フラクタルの時は無謀にも思えた、「ちょうど良い」ディティールをコントロールすることができるのである。
 我ながら良いアイディアではないだろうか。

 ということで、日付が変わってしまったのでまた次回。