プロジェクション

プロジェクション  プロジェクションというのは、おおざっぱに言って3D空間内の表示範囲の設定のようです。

 ウィンドウ内に表示される3D空間内の表示範囲は右の図の緑色の部分です。この範囲内の部分だけが表示され、これ以外の 範囲は画面に表示されません。(表示はされませんが、衝突判定などの計算は行われます。)
この範囲はカメラ位置と向きを中心にした、3つの値から決定されます。次の3つです。

  意味 デフォルト値
near 近い方のクリップ面との距離 100.0
far 遠い方のクリップ面との距離 10000.0
fovdeg 視野角(degree、度) 45.0

 表示範囲の大きさは若干ですが処理速度に影響します。広ければ軽く、広ければ重くなります。
ポリゴン数が多ければ重く、少なければ軽くなるためです。

 視野角はあまり変な値を入れると画面が不自然に歪むので注意が必要です。
 参考までに、視野角は広げれば360度見渡すことも可能です。
望遠鏡(ライフルスコープ)の映像などは視野角を小さくして表現できます。
また人間の視野角は測定方法によりまちまちで、88~240度とかなり開きがありあまりあてにはなりません。
とりあえずデフォルト値が無難なところでしょう。
この辺はカメラに詳しい方に聞くのがいいでしょうね。広角とか遠近感とか何とか…、私にはわかりません。その辺のサイトを調べてください。


※ 視野角の方向は上下方向であるようです。
普通なら気にすることはないと思いますが、正確に角度をあわせたい場合は注意が必要です。

サンプル

適当に操作しつつ値の変化と映像の変化を確認してください。

キー 内容
Znear増加
Xnear減少
far増加
far減少
fovdeg増加
fovdeg減少

実行に必要なファイル:e3d3004.zip

解凍に成功すると、Mediaフォルダとe3d3004.hspが作成されます。

次に、下のスクリプトをコピーして、HSPのスクリプトファイルを作成してください。
作成したファイルは、e3d3004.hspがある場所と同じ場所におきます。

これでサンプルを実行することが出来ます。

;
;	プロジェクションを変えてみるサンプル
;

#include "e3dhsp3.as"

	;/////////////////
	;
	;	初期化
	;
	wid = 0		;ウインドウID
	objid = -1	;オブジェクトID
	fullscreenflag = 0		;フルスクリーンフラグ
	bits = 16	;色数ビット数(fullscreenflag = 1 のときのみ有効)
	multisamplenum = 0		;アンチエイリアスのマルチサンプル数(0,2~16)
	;scid	スワップチェインID
	E3DInit wid, objid, fullscreenflag, bits, multisamplenum, scid
	dim keybuf, 256		;キー入力
	camdegxz = 135		;カメラ向き

	;/////////////////
	;
	;	カメラの初期化
	;
	camposx = 0.0 : camposy = 2500.0 : camposz = 0.0
;	camposx = 0 : camposy = 0 : camposz = 4200	;デフォルト値
	E3DSetCameraPos camposx, camposy, camposz	;カメラ座標を設定
	targetx = 10		;注視点座標
	targety = camposy
	targetz = 10
	upvecx = 0		;カメラの上方向のベクトル
	upvecy = 1
	upvecz = 0
	E3DSetCameraTarget targetx, targety, targetz, upvecx, upvecy, upvecz	;カメラの注視点を設定
	;プロジェクションの設定
	proj_near = 100.0 : proj_far = 50000.0 : proj_fov = 45.0
	E3DSetProjection proj_near, proj_far, proj_fov

	;/////////////////
	;
	; ライトの設定
	;
	E3DCreateLight lid1 ;光源を作成
	lightdirx1 = 1 ;平行光の向き
	lightdiry1 = -1
	lightdirz1 = 0
	lightr1 = 255	;平行光の色
	lightg1 = 255
	lightb1 = 255
	E3DSetDirectionalLight lid1, lightdirx1, lightdiry1, lightdirz1, lightr1, lightg1, lightb1 ;光源を平行光源に設定

	;/////////////////
	;
	;	地面の作成
	;
	sdim pathbuf, 2048, 4
	pathbuf.0 = dir_cur + "\\Media\\yama.bmp"	;地面の座標情報
	pathbuf.1 = dir_cur + "\\Media\\michi.bmp"	;地面の道の情報
	pathbuf.2 = dir_cur + "\\Media\\kawa.bmp"	;地面の川の情報
	pathbuf.3 = dir_cur + "\\Media\\bazou.bmp"	;地面、道、川の模様を決める、BMPファイル

	;地面作成用の値
	mapsize = 60000.0		;X,Z座標の最大値
	mapdiv = 60			;座標の分割数
	mapheight = 3000.0	;高さの最大値

	E3DLoadGroundBMP pathbuf.0, pathbuf.1, pathbuf.2, pathbuf.3, mapsize, mapsize, mapdiv, mapdiv, mapheight, hsid0
	posx0 = 0.0 : posy0 = 0.0 : posz0 = 0.0
	degx0 = 0.0 : degy0 = 0.0 : degz0 = 0.0
	E3DSetPos hsid0, posx0, posy0, posz0	;地面表示位置を設定
	E3DSetDir hsid0, degx0, degy0, degz0	;地面の向きを設定
	frameno0 = 0	;モーションは使用しない。


;/////////////////
;
;	メインループ
;
*main
	E3DGetKeyboardState keybuf	;キー状態取得
	E3DChkInView scid, hsid0	;モデルが、視野内にあるか判定
	E3DBeginScene	;-----シーンスタート
		;バックバッファへの書き込み作業を行う

		if keybuf.VK_ESCAPE = 1 : goto *bye ; [ESC]で終了

		gosub *setpro		;プロジェクション変更

		E3DRender scid1, hsid0, 0, frameno0, 0	;バックバッファにレンダリングする。(地面描画)

	E3DEndScene			;-----シーン終了
	E3DPresent scid1	;バックバッファの内容を、プライマリバッファに転送。描画する。

	E3DWaitByFPS 60, chkfps1 : await 0
	title ""+chkfps1 + " FPS"

goto *main


;/////////////////
;
;	終了処理
;
*bye
	E3DDestroyLight lid1	;ライトを破棄
	E3DBye
	end


;/////////////////
;	プロジェクションの設定
;
*setpro
	if keybuf.VK_UP = 1	: proj_far+=100	;矢印上
	if keybuf.VK_DOWN = 1	: proj_far-=100	;矢印下
	if keybuf.VK_LEFT = 1	: proj_fov--	;矢印左
	if keybuf.VK_RIGHT = 1	: proj_fov++	;矢印右
	if keybuf.'Z' = 1	: proj_near+=100	;z	前進
	if keybuf.'X' = 1	: proj_near-=100	;x	後退

	;プロジェクションの設定
	E3DSetProjection proj_near, proj_far, proj_fov

	E3DDrawText 10,10, 1, 255,255,255, "(z,x)near = "+proj_near
	E3DDrawText 10,24, 1, 255,255,255, "(up, down)far = "+proj_far
	E3DDrawText 10,38, 1, 255,255,255, "(-->, <--)fov = "+proj_fov
	return