セカンドライフの描画詳細度について

投稿日: 更新日:

今日はセカンドライフのLoDの動作について、少し解明していきたいともいます。以前もLoDの話はしておりますが改めて説明します。

LoDとは、Level of Detailの略でして、描画詳細度と呼ばれるものです。描画詳細度が大きければ、ディテールを細かくし、詳細度が低ければディテールを荒くします。例えばですが、3Dの世界で全てを描写しようとすると、とてもGPUに負荷がかかります。そのため、カメラが写っている範囲だけを描写したり、いろいろな工夫をしているわけです。その中の1つに、カメラからの距離が遠くなればなるほど、負担が少なくなるようにモデルの形を変更させる方法があります。LoDを設定しておけば、レベルの段階に合わせて、簡単モデルを表示させられるわけです。

さて、「カメラからの距離に合わせて、描写するモデルを簡略化させる」と簡単には書きましたが、よくよく考えると、いまいち仕様が分かりません。

例として、縦長のモデルがあったとします。このモデルを上から見れば小さく表示されて、横から見れば大きく表示されます。つまり、正確に実装するとするならばモデルを見る方向によって、描画詳細度を変える必要があるのです。モデルのバウンディングボックスを2次元平面に投影した後に、面積を調べるといった形になります。ただ、目的としては負担を減らすためにやっているはずなので、そういうことまではしていないとは思うのですが、確証はありません。

今回実際にセカンドライフ、ビューアはCatznipを使用して調べてみました。まずは、LoDにあわせて4つのモデルを作成します。なお、LoDは、低くなるにつれて必ずポリゴン数、頂点数が上がらないようにする必要があります。

MaruRo
ShikakuSankaku最低

作ったモデルをセカンドライフにアップロードします。
UploadS
上記のファイルをそれぞれのLoDに設定します。

では、まずは表示する面積によって、LoDが変わるのかテストしたいと思います。

HaichiS
次のように配置しました。
手前から奥に向かって、大きさが大きくなっていきます。
上の段は、奥行はうすっぺらいですが、横と縦の大きさを大きくしていっています。1×1, 2×2, 4×4, 8×8
下の段は、さらに奥行も大きくなっています。1x1x1, 1x1x2, 1x1x4, 1x1x16

そうそう、実際に見る前に公平性を保つためにカメラの設定をします。
ShiyakakuS
カメラの視野角を最低にしておきます。こうすることで、カメラの画角による影響を減らします。

さて、下が水平から見てある程度でカメラを離れたところにおいた時の画像となります。
SLLODTest1

ここから見ると、上の段にある奥行が薄っぺらいモデルの方が大きくみえるのですが、表示されるディテールが悪くなっています。従って、実際に画面に表示される大きさによって、ディテールを変更しているわけではないのです。

次はモデルのバウンディングボックスの体積が関係あるのでは、と仮定をして配置します。

SLLODTest2
左のモデルは2x2x2。右のモデルは1x1x8となります。
このモデルを離れたところから見て、2つとも同時にディテールの変更があれば、体積が影響するといえます。

しかし実際にやってみるとそうではありませんでした。
SLLODTest3
左のモデルの方が先にディテールが低くなったのです。

次は「モデルの体積」ではなく、
SLLODTest4
「モデルの大きさの最大値」を使用しているのではと仮定して配置しなおしました。
左のモデルは2x2x8。右のモデルは1x1x8となります。

この場合は、ほぼ同じ位置でディテールの変更がありました。
SLLODTest5
これらの結果から「モデルの大きさの最大値」がディテールに影響することが分かりました。

脱線しますが、セカンドライフのディテールの設定は、デバッグ設定の RenderVolumeLODFactor に依存します。
SLLODTest6

これが大きいと、ディテールの低下を下げることができます。グラボの性能が良いのであれば、少し上げても問題ないと思われます。


オマケ
カメラの座標を取得するスクリプトです。

integer	isStartTimer	= FALSE;

default {

	state_entry() {
	}
	
	touch_start(integer total_number) {
		if(isStartTimer) {
			isStartTimer = FALSE;
			llSetTimerEvent(0.0);
			llClearCameraParams();
		}
		else {
			llRequestPermissions(llGetOwner(), PERMISSION_TRACK_CAMERA);
			isStartTimer = TRUE;
			llSetTimerEvent(1.0);
		}
		llOwnerSay("isStartTimer = " + (string)isStartTimer);
	}
	
	timer() {
		llOwnerSay("llGetCameraPos = " + (string)llGetCameraPos());
	}
	
}
広告

コメントをどうぞ(承認された後に公開されます。メールアドレスの記入は自由ですが、記入した場合でも一般公開されることはありません)

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中