|
 |
|
2022/6/6(Mon) 10:51:33|NO.96576
[hgimg4] サンプルの「pronama3」を参考に、[gpscrmat] で鏡をプログラムしました。
メインカメラの位置を ( ca_x, ca_z ) とすると、
鏡となる板ノード(plate)を通るX軸を対称軸とした時の対称位置から、
鏡を見るカメラアングルでの映像が、 鏡に写る画面になるはずなので、
鏡用カメラの位置は ( ca_x, pl_z-(camz - pl_z) ) となります。
この鏡用カメラの映像バッファを [GPOBJ_MATOPT_MIRROR] オプションの
[gpscrmat] でマテリアルにして、それを鏡用板ノードに貼り付けています。
https://twitter.com/akiakinohiroro/status/1527116397016674304
ただ、鏡の面がX軸に対して、並行ならばこれでいいのですが、角度があると、
その分、鏡用カメラの設定位置がずれてきます。
このことを組み込めば、不自然さはなくなるはず、と思うのですが、
これのプログラムが上手く作れません。数学的な幾何の問題に過ぎない
とも言えるのでしょうが、お教え願えないでしょうか。
もう何日も頭を抱えています。
以下、鏡の面がX軸に並行としてのプログラムです。
#include "hgimg4.as"
#include "hspmath.as"
#packopt name pronama3
#packopt xsize 960
#packopt ysize 640
chdir dir_exe+"\\sample\\pronama3d"
; 暮井 慧(プロ生ちゃん) 3D model (C) Pronama LLC
title "HGIMG4 Test"
gpreset
;〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
;━━ [バッファ] ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
sx=960/3 : sy=640/3 : id_Kagami=1 : id_render=2
buffer id_Kagami,sx,sy,screen_offscreen
buffer id_render,sx,sy,screen_offscreen
setcls CLSMODE_SOLID, $6040f0
;━━ [地面]ノード ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
gptexmat id_tex, "res/skirt.png" ; テクスチャマテリアル作成
gpfloor id_floor, 40,40, ,id_tex ; 床ノードを追加
;━━ [モデル]ノード ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
mo_x=0.0 : mo_y=0.0 : mo_z=0.0
gpload id_model,"res/pronamachan" ; モデル読み込み
setscale id_model, 0.025,0.025,0.025
setpos id_model, mo_x,mo_y,mo_z
gpaddanim id_model,"WALK00_F" ; アニメーションクリップを設定
gpact id_model,"WALK00_F"
;━━ [鏡用板]ノード ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
pl_x=-2.5 : pl_y=2.0 : pl_z=-1.0 : angr_y=0
gpscrmat id_texmat, id_Kagami, GPOBJ_MATOPT_NOLIGHT|GPOBJ_MATOPT_NOMIPMAP|GPOBJ_MATOPT_MIRROR
gpplate id_plate, 1.6,1.2, -1,id_texmat ; 鏡本体用 板ノードを追加
setpos id_plate, pl_x,pl_y,pl_z
setangr id_plate, 0,angr_y,0
gpplate id_plateA, 2,1.5, $ff0000 ; 鏡裏板用 板ノードを追加
setpos id_plateA, pl_x,pl_y,(pl_z-0.1)
gpplate id_plateB, 0.5, 1.4, $aa0000 ; 鏡脚用 板ノードを追加
setpos id_plateB, pl_x,(1.4/2),(pl_z-0.1)
;━━ [メインカメラ]
ca_x=5.0:ca_y=3.0:ca_z=10.0
gpusecamera GPOBJ_CAMERA ; 使用するメインカメラを選択する
setpos GPOBJ_CAMERA, ca_x,ca_y,ca_z ; カメラ位置を設定
gplookat GPOBJ_CAMERA, pl_x,pl_y,pl_z ; カメラから指定した座標を見る
;━━ [サブ画面用カメラ]
; カメラ距離
to_kagami_x = ca_x
to_kagami_y = ca_y
to_kagami_z = pl_z - (ca_z - pl_z)
gpnull id_camera ; サブ画面用カメラを選択する
gpcamera id_camera, 45.0, 1.0, 0.5, 768 ; 視野(FOV)パラメーター=45.0 アスペクト比=1.0
setpos id_camera, ca_x,15,ca_z ; カメラ位置を設定
gplookat id_camera, pl_x,pl_y,pl_z ; カメラから指定した座標を見る
;━━ [鏡用カメラ]
gpnull id_Kagami_camera ; 鏡用カメラを選択する
gpcamera id_Kagami_camera, 8.0, 1.0, 0.5, 768 ; 視野パラメーター=8.0 アスペクト比=1.0
setpos id_Kagami_camera, ca_x,ca_y,to_kagami_z ; カメラ位置を設定
gplookat id_Kagami_camera, pl_x,pl_y,pl_z ; カメラから指定した座標を見る
;〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
*main
;━━━━━━━━━━━━━━━━━━━━━━━━━
gsel id_render
gpusecamera id_camera ; 使用するカメラを選択する
setpos id_camera, ca_x,15,ca_z ; カメラ位置を設定
gplookat id_camera, mo_x,mo_y,mo_z
redraw 0 ; 描画開始
; オフスクリーンバッファ使用時は、[gpdraw] オプション必須
gpdraw GPDRAW_OPT_DRAWSCENE|GPDRAW_OPT_DRAWSCENE_LATE ; シーンの描画
redraw 1 ; 描画終了
;━━━━━━━━━━━━━━━━━━━━━━━━━
gsel id_Kagami
gpusecamera id_Kagami_camera ; 使用するカメラを選択する
setpos id_Kagami_camera, ca_x,ca_y,to_kagami_z ; カメラ位置を設定
gplookat id_Kagami_camera, pl_x,pl_y,pl_z ; カメラから指定した座標を見る
redraw 0 ; 描画開始
gpdraw GPDRAW_OPT_DRAWSCENE|GPDRAW_OPT_DRAWSCENE_LATE ; シーンの描画
redraw 1 ; 描画終了
;━━━━━━━━━━━━━━━━━━━━━━━━━
gsel 0
gpusecamera GPOBJ_CAMERA ; 使用するカメラを選択する
setpos GPOBJ_CAMERA, ca_x,ca_y,ca_z ; カメラ位置を設定
gplookat GPOBJ_CAMERA, mo_x,mo_y,mo_z
stick key,15+2048+4096+8192+16384+32768+131072
if key&128 : end
; カーソルキーでモデル位置を動かす
if key&1 : mo_x -=0.01
if key&4 : mo_x +=0.01
if key&8 : mo_z +=0.01
if key&2 : mo_z -=0.01
setpos id_model, mo_x,mo_y,mo_z
; キーでカメラ位置を動かす
if key&2048 : ca_x -=0.05 ; [Z]キー
if key&8192 : ca_x +=0.05 ; [C]キー
if key&4096 : ca_z +=0.05 ; [X]キー
if key&131072 : ca_z -=0.05 ; [S]キー
if key&32768 : ca_y +=0.01 ; [W]キー
if key&16384 : ca_y -=0.01 ; [A]キー
;==================================================
redraw 0 ; 描画開始
gpdraw ; シーンの描画
color 255,255,255
pos 8,8:mes "HGIMG4 sample"
color : boxf (sx*2-6),(sy*2-5),(960-10),(640-7)
// sx=960/3 : sy=640/3
pos sx*2,sy*2
celput id_render,0,0.95,0.95
redraw 1 ; 描画終了
await 1000/60 ; 待ち時間
goto *main
;〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

| |
|
2022/6/6(Mon) 11:20:50|NO.96577
鏡には、「鏡から見た映像」が映るので、鏡用のカメラ位置は鏡の場所です。
|
|
2022/6/6(Mon) 12:37:32|NO.96578
> 鏡には、「鏡から見た映像」が映る
とすると、「鏡に空いた穴に目を当てて見た映像」になってしまいます。
正面なら、それでいいですが、位置関係が正面でなかったり、角度が付いていると
映るはずのない位置のものが映ったり、変です。鏡は鏡面反射の映像のはずで、
入射角とか、反射角とかあって、鏡を見る方角で決まってくるはずでは?
|
|
2022/6/6(Mon) 18:52:11|NO.96579
鏡は、鏡の視点からバックバッファにレンダリングし、それを左右反転してテクスチャとして板ポリに貼るだけで実現できます。
環境マッピングと同じです。
現実世界で鏡に一体何が映ってるか観察すれば理解できるのではないでしょうか?
|
|
2022/6/6(Mon) 22:14:33|NO.96580
> 鏡は、鏡の視点からバックバッファにレンダリングし、
> それを左右反転してテクスチャとして板ポリに貼るだけで実現できます。
これをプログラムしているつもりなんですが!?
ただ、私の場合、「鏡の視点」は鏡の位置ではありませんが。
[鏡用カメラ]id_Kagami_camera からの画像を、バックバッファである [id_Kagami=1] に
[gpdraw GPDRAW_OPT_DRAWSCENE|GPDRAW_OPT_DRAWSCENE_LATE] でレンダリングし、
[gpscrmat id_texmat, id_Kagami, GPOBJ_MATOPT_NOLIGHT|GPOBJ_MATOPT_NOMIPMAP|GPOBJ_MATOPT_MIRROR] で
それを左右反転して、
[gpplate id_plate, 1.6,1.2, -1,id_texmat] で
テクスチャとして板ポリに貼っています。
ギバロウ さんが言う鏡の視点からのカメラはどこを向いているのでしょうか?
仮に、常に鏡の正面を向いている、と考えるなら、鏡の真横に近いところから鏡を見ても、
鏡には、鏡の正面にあるものが映っていることになります。
しかし、そんな映り方をする鏡なんてありません。
鏡の正面を向いているのは、鏡を正面から見ている時だけです。
では、それ以外の時、カメラはどこを向いているのでしょうか?
鏡用の画像を映し出すためのカメラの位置とその向きは、どのように決まってくるのか。
様々な条件下でも常に満たすようなプログラムを求めているのです。
|
|
2022/6/6(Mon) 23:15:27|NO.96582
鏡面がカメラの視線方向と垂直なら簡単なんですけどね。投影面が斜めになるので難しい。
UV座標を変えることができればかなりそれっぽくできると思いますが、やり方は具体的には考えてないのでわかりません。
|
|
2022/6/7(Tue) 04:03:59|NO.96583
メインカメラ(視点)から鏡へのベクトル、鏡の向きベクトルから、反射する視点のベクトルが求められませんか?
|
|
2022/6/7(Tue) 04:42:13|NO.96584
ベクトルか。いいかもですが、fv系命令ですよね。
これ、便利そうで、使えるようになりたいと、常々思っていますが、
感覚的にも、全体のイメージ的にも、すんなり入ってこないところがあって、
どうも、苦手です。
GENKI さんの「GHP(仮)」の fv系命令 に関するもの、頑張って読んでみてるんですが、
私は今のところ、使えるまでにはなっていません。
でも、ベクトル、ここに応用できそうな予感はしますね。
|
|
2022/6/7(Tue) 05:05:02|NO.96585
まさかベクトルを理解しておられないとは思いませんでした。。。
視点から鏡へのベクトルと鏡の向きベクトルから入射角度を求める事が出来ます。
それによって反射角が求められるので、視点から見た鏡が映す方向を知る事が出来ます。
ですので、反射カメラは鏡の位置、向きは反射する方向となります。
|
|
2022/6/7(Tue) 05:35:04|NO.96586
『ベクトル』の意味や定義は分かっているつもりですが......。
ただ、それを具体的に実際のプログラムの中で、『fv系命令』を使って、
問題を解決することが、どうもすんなりとイメージできなくて、
結果、プログラムの組み方が分からないのです。
> 反射カメラは鏡の位置、向きは反射する方向
「向きは反射する方向」というのであれば、位置は、「鏡の位置」でもいいかもです。
そのことは、『ベクトル』云々以前から、分かっていることですが......。
具体的に実際のプログラムの中で、『fv系命令』を使って、問題を解決したいのです。
どう、『具体的に』『具体的に』『具体的に』プログラムを組んだらいいのか、ということです。
|
|
2022/6/7(Tue) 05:48:55|NO.96587
最初に載せたスクリプトでは、ベクトルやfv系命令、そのものは使っていませんが、
> setpos id_Kagami_camera, ca_x,ca_y,to_kagami_z ; カメラ位置を設定
> gplookat id_Kagami_camera, pl_x,pl_y,pl_z ; カメラから指定した座標を見る
が、そのベクトルになっているはずです。
|
|
2022/6/7(Tue) 13:37:58|NO.96591
ちょっと気になったので。。。
>そのベクトルになっているはずです。
使われている変数の事であれば、それは座標ですね。
その変数からベクトルを出すのであれば一例ですが。
fvset fv, pl_x,pl_y,pl_z
fvsub fv, ca_x,ca_y,to_kagami_z
//↓これらが視点からカメラへのベクトル
vec_x = fv.0 : vec_y = fv.1 : vec_z = fv.2
fvunit fv
//↓これらが上の単位ベクトル(つまり方向)
//これにfvdirを使うと好きに回転させられる
//fvmulを使うとその方向にベクトルを好きに伸ばせる
nvec_x = fv.0 : nvec_y = fv.1 : nvec_z = fv.2
>どう、『具体的に』『具体的に』『具体的に』プログラムを組んだらいいのか、
下記スレで「具体的」な数式をプログラム(fv系)へ落とし込み方を説明してますので、
ご参考にどうぞ(ちょうど屈折と反射の話ですね)
https://hsp.tv/play/pforum.php?mode=all&num=94058
>数学的な幾何の問題に過ぎない
>様々な条件下でも常に満たすようなプログラムを求めているのです。
ただ、標準の命令とZバッファ法では、ゲーム的な考えて表示をそれっぽく狭い範囲で限定して
いかないと難しいかもしれないですね。
レーシングゲームのバックミラーも都合よくそれっぽく切り出している物が多いですし
リアルタイムでの処理負荷もありますので、
古い方法では、鏡に対して対称に実態をおいたり(周りは建物で隠す)、
ステンシルバッファ等でくりぬいて合成したり
いろいろなそれっぽく方法はあると思います。
シミュレーション的な考えてあれば
光学的に正しく数学的に実現するにはレイトレーシング法とかする必要があると思いますが、
hgimg4から離れてしまうのでちょっと敷居が高そうです。
|
|
2022/6/7(Tue) 16:13:19|NO.96592
usagi さん、有難うございます。
以前にも、やはりベクトルと角度でお世話になりました。
youdai さんのスレの時にも、無理やり割り込ませて頂きましたが、
その時からも、ちっとも進歩していないようで、お恥ずかしい次第です。
> 使われている変数の事であれば、それは座標ですね。
はい、その通り、座標です。この二つの座標を考えていけば、
ベクトルと同じことが出来るはずと思えたので、
>そのベクトルになっているはずです。
と、言い表しました。紛らわしい表現を使ってしまいました。
実際の(市販?)ゲームでも、「それっぽく」の表現方法で現実的にやっているのであれば、
自分の実力からして、今の程度で妥協するのが、賢明に思えてきました。
ただ、感覚的にも、全体のイメージ的にも、すんなり入って行けるようにはなりたいので、
これまで避けていた、fv系命令の勉強はしっかりしていこうと思います。
有難うございます。
一応の解決と致します。
|
|
2022/6/7(Tue) 18:49:53|NO.96593
追記です。
GENKI さんの『GHP(仮)/地表を歩く』で
> gppraytest............レイとオブジェクトの衝突機能は、
> レーザー攻撃の衝突判定や、............あたった部分の法線ベクトルもわかるので、
> レーザーの反射軌道も計算できます。
この反射軌道、使えないかな。
メインカメラから鏡へのベクトル(入射角)をレイとして、オブジェクトである鏡との衝突から、
計算できる反射軌道を鏡の反射角と見なせばいいんじゃないか。
「hgimg4/physics_2.hsp」のサンプルで言えば、
カメラレイと衝突しているオブジェクトを鏡と考えればいい訳です。
このサンプルのオブジェクトは皆正面を向いているから、法線ベクトルは、皆Z軸方向ですが、
たとえ、どんな方向に向いていても、その法線ベクトルを求めることが出来るのだから、
その(レーザーの)反射軌道も分かるはず。
その軌道のベクトルで、カメラが映し出す映像が、鏡面の映像になるのではないか。
思い付きだけで、すいません。
|
|
2022/6/7(Tue) 20:35:21|NO.96594
不明な法線ベクトルは3頂点の外積で求められますが、
法線ベクトル x=0: y=0: z=1 で作った板ポリゴンを回すだけでしたら
板ポリを回転させたと同じように法線を回転させれば簡単にもとまりますよ。
fvset fv, angr_x, angr_y, angr_z
fvdir fv, 0.0, 0.0, 1.0
;fvに法線が入ってる。
レイキャストの様な重い処理をしなくても、面の法線が既知であれば
そのまま回転して利用したほうがシンプルな考えかもしれません。
反射軌道は先のリンクを参考にすればよいかと思います。
鏡の反射ベクトルはその通りも止まりますが、
細かい事を言うと、板ポリにテクスチャ張っているのでカメラ位置で歪みますね。
ちょうど良い説明サイトありました。この「鬼分かりやすい図」って所がイメージしやすいと思います。
(サイト外なので、 http の hだけ消しました。)
ttps://qiita.com/nkjzm/items/ccba41a6e7e5211aae95
|
|
2022/6/8(Wed) 19:44:01|NO.96602
鏡をプログラムで再現するのは奥が深いですね(^^;
いまさらではありますが自分なりに調べてみて作ってみました
鏡を再現するのはやはりベクトルとか内積とか必要になってくるようですが
鏡の法線ベクトルがZ軸方向ということならば
比較的シンプルにできたように思うので
変更部分だけ書いてみます
;━━ [鏡用カメラ]
gpnull id_Kagami_camera ; 鏡用カメラを選択する
gpcamera id_Kagami_camera, 25.0, 1.0, 0.5, 768 ; 視野パラメーター=8.0 アスペクト比=1.0
setpos id_Kagami_camera, pl_x,pl_y,pl_z ; カメラ位置を設定
gplookat id_Kagami_camera, ca_x,ca_y,ca_z ; カメラから指定した座標を見る
視野パラメーターとカメラ位置を変更しました
鏡用カメラは鏡の部分に調整しました
あと鏡用カメラの向く方向は座標で指定する方法と
角度で指定する方法、両方書いてみました
座標指定
gsel id_Kagami
gpusecamera id_Kagami_camera ; 使用するカメラを選択する
setpos id_Kagami_camera,pl_x,pl_y,pl_z; カメラ位置を設定
gplookat id_Kagami_camera, pl_x*2-ca_x,pl_y*2-ca_y,ca_z ; カメラから指定した座標を見る
角度指定
gsel id_Kagami
gpusecamera id_Kagami_camera ; 使用するカメラを選択する
setpos id_Kagami_camera,pl_x,pl_y,pl_z; カメラ位置を設定
fvface fv,pl_x-ca_x,pl_y-ca_y,pl_z-ca_z
setang id_Kagami_camera,M_PI-fv.0,-fv.1,M_PI
機会があれば内積なども勉強したいとは思っていますが
いまのところは私には難しいようです
|
|
2022/6/8(Wed) 23:20:41|NO.96605
> 鏡の法線ベクトルがZ軸方向ということならば
ええ、そうでしたら、kinokawa さんの方法でいいようですね。
と言いながら、「角度指定」の方は、[setang] のパラメーター指定が、
何故そうなるのか、[fv] の勉強中でよく理解出来ていませんが。
私は、今、鏡の向きを限定しない「数学的な幾何の問題」として、
やり直してみようとしています。
上手くいくかは、やってみないと分かりませんが、それでダメなら、
最初の方法で、それなりに妥協点を探っていくしかないかな、と思っています。
|
|
2022/6/9(Thu) 11:50:36|NO.96610
kinokawa さん、すいません。
> 鏡の法線ベクトルがZ軸方向ということならば
ということでなら、大丈夫のようにも思えたのですが......。
ただ、この条件というのは、鏡の向きがZ軸方向ということであり、
このスクリプトの鏡用板ノードは向きを変えていない(=常にZ軸方向)ので、たとえば、
kinokawa さんの変更スクリプトで、「キーで(メイン)カメラ位置を動かす」をやっても、
違和感ない映りになるはず、と思えるのに、そうではありません。
特に[W]キー、[A]キーでメインカメラの高さを変えてみて下さい。鏡の映り方がおかしくなります。
メインカメラが鏡の高さより低くなっても、床が見え続けてしまい、不自然になります。
このことは、多少の差はあるものの、座標指定でも、角度指定でも起こります。
どうも、鏡用の画像を映し出すためのカメラの位置を鏡の位置にすると、
その視野角設定を、その映る大きさを見てどう調節しても、
鏡より低いところも、そのカメラの視野角にほぼ常に入ってしまうため、
メインカメラからの見え具合いに合わなくなってしまいます。
申し訳ないと言うか、私の最初のスクリプトのままならば、そのような不自然は生じません。
|
|
2022/6/9(Thu) 17:53:44|NO.96613
鏡用の画像を映し出すためのカメラの位置から、鏡の方角を見た時の、
その時のカメラの視野角についてです。
鏡の大きさを丁度捉えるだけで、それ以上の範囲を映し出すことがない
大きさの視野角にするのがいいように思います。
カメラと鏡の距離が遠くなればなるだけ、視野角は狭く、
近くなればなるほど、広くなるようにです。
具体的にどうプログラムするかは難しいところですが。
> 鏡の大きさ/2 = 距離 * tan(視野角/2)
のような感じか。
|
|
2022/6/11(Sat) 14:15:15|NO.96621
現状のhgimg4だと視野角設定しにくい(初期化されるから)のと、視錐台で背面のクリップも難しい(斜めに切る)と思うので別案です。
α書き込んでおくとgmode 2,4などの透明付コピーでステンシルっぽい事が出来るようなので、
鏡だけ抜いてみました。背面は単純に消しちゃいます。
#include "hgimg4.as"
#define SCR_X 960
#define SCR_Y 640
#module
;reflect(I, N) ※Rに結果を代入 I入射ベクトル N法線
#deffunc reflect array R, array I, array N
fvset dot, N.0, N.1, N.2 : fvinner dot, I.0, I.1, I.2 : dot.0 *= 2
fvset h, N.0, N.1, N.2 : fvmul h, dot.0, dot.0, dot.0
fvset R, I.0, I.1, I.2 : fvsub R, h.0, h.1, h.2
return
#global
; 初期化 ----------------------
screen 0, SCR_X, SCR_Y : title "鏡モドキ"
randomize
chdir dir_exe+"\\sample\\pronama3d"
gpreset : setcls CLSMODE_SOLID, $99A9E8
; オフスクリーンバッファ
tex_main = 1 : buffer tex_main, SCR_X, SCR_Y,screen_offscreen
tex_mirror = 2 : buffer tex_mirror, SCR_X, SCR_Y,screen_offscreen
; メインカメラ
gpnull cam_main : gpcamera cam_main, 45.0, 1.5
; 鏡カメラ
gpnull cam_mirror : gpcamera cam_mirror, 45.0, 1.5 : setobjrender cam_mirror, 2
; 背景オブジェクト(床とランダムな箱)
gpfloor obj_floor, 50,50, $ACDFE6 : setobjrender obj_floor, 3
repeat 64
_s = 0.3*rnd(5) : _x = rnd(10)*2-10 : _y = _s/2+rnd(10) : _z = rnd(10)*2-10
hsvcolor rnd(191),128,255 : _c = ginfo_r<<16|ginfo_g<<8|ginfo_b
gpbox _o, _s, _c : setpos _o, _x, _y, _z
if _z >= 0 { setobjrender _o, 3 }
loop
; モデルオブジェクト 暮井 慧(プロ生ちゃん) 3D model (C) Pronama LLC
gpload obj_model,"res/pronamachan" : setpos obj_model, 0, 0, 2
setscale obj_model, 0.05,0.05,0.05 : gpaddanim obj_model,"WALK00_F" : gpact obj_model,"WALK00_F"
; 鏡オブジェクト
gpplate obj_mirror, 9,9 : setpos obj_mirror, 0,5,0
gpmatstate obj_mirror, "blendSrc", "CONSTANT_ALPHA" ; ★現状ステンシルっぽく動作する
gpplate obj_frame, 10,10, $F5F0DA : setpos obj_frame, 0,5,-0.01
; メイン ----------------------
*L_MAIN
gosub *L_UPDATE
gosub *L_DRAW
await 16
goto *L_MAIN
; 更新 ------------------------
*L_UPDATE
; メインカメラ移動(マウス)
_x = double(mousex-SCR_X/2)/(SCR_X/2) : _y = double(mousey-SCR_Y/2)/(SCR_Y/2)
fv = _y*M_PI/2, _x*M_PI/2, 0.0 : fvdir fv, 0,0,20
setpos cam_main, fv.0,fv.1,fv.2 : gplookat cam_main, 0,5,0
; モデルの移動
stick pad, 15|256|512
getpos obj_model, _x, _y, _z
if pad&1 : _x-=0.1
if pad&2 : _z-=0.1
if pad&4 : _x+=0.1
if pad&8 : _z+=0.1
if (_x>-7)&(_x<7)&(_z>-2)&(_z<1.5) { getpos obj_model, _x, _y, _z }
if _z >= 0 { setobjrender obj_model, 3 } else { setobjrender obj_model, 1 }
setpos obj_model, _x, _y, _z
; 鏡の法線ベクトル
fvdir normal, 0,0,1
; 反射ベクトル計算 --------
; メインカメラと鏡の位置
getpos obj_mirror, mirror.0, mirror.1, mirror.2
getpos cam_main, cam.0, cam.1, cam.2
; メインカメラから鏡へのベクトル
fvset vec_cam_mir, mirror.0, mirror.1, mirror.2
fvsub vec_cam_mir, cam.0, cam.1, cam.2
; 鏡カメラの位置計算
reflect ref, vec_cam_mir, normal ; 反射計算
fvsub mirror, ref.0, ref.1, ref.2 ; 鏡の位置から反射ベクトルを引く
getpos obj_mirror, _x,_y,_z
; 鏡カメラの位置を設定して鏡オブジェクトの方向を見る
setpos cam_mirror, mirror.0, mirror.1, mirror.2
gplookat cam_mirror, _x,_y,_z
return
; 描画 ------------------------
*L_DRAW
; 鏡カメラ描画
gsel tex_mirror : redraw 0 : gpusecamera cam_mirror : gpdraw 30 : redraw 1
; メインカメラ描画
gsel tex_main : redraw 0 : gpusecamera cam_main : gpdraw : redraw 1
; 合成(ステンシルっぽく)
; GENKIさん報告のバグ https://hsp.tv/play/pforum.php?mode=all&num=96193
; gmode 2,4などalphaコピーでステンシルっぽく動作する?(デカールとかシャドウとか出来ると思うので、何かしらの形で正式に対応したらいいな)
gsel 0 : redraw 0
pos SCR_X,0 : gmode 0 : celput tex_mirror,,-1
pos 0,0 : gmode 4,,,255 : celput tex_main, 0
; 情報表示
color 255,255,255 : gmode 0
pos 0,0 : mes "カメラ:マウス、 箱:カーソル",4
celput tex_main, 0, 0.2,0.2 : celput tex_mirror, 0, 0.2,0.2
redraw 1
return
シェーダー書かなくても良いですし(古い固定パイプラインの頃からある表現)
プロジェクションの変換など触れるところがまだ少ないので、
やはり数学的な解決は機能、構造的に厳しいと思うので、
こういう見せ方もあるんだなぁ。。と限定した汎用的に使えそうな一例としてどうぞ

| |
|
2022/6/11(Sat) 20:45:45|NO.96625
> 限定した汎用的に使えそうな一例
とは言え、みごと、不自然さを全く感じさせないものになっていますね。
ただ、鏡を鏡として見せる目的のみにしか使えないようで、残念です。
鏡がごく普通に置いてある(掛けてある)室内をキャラクタが歩き回ったりする
ごく普通にある日常風景としての鏡の様子となると、難しいですね。
鏡カメラの設定位置はこの決定の仕方で、かつ常に鏡の方向を向いているにしても、
メインカメラの向きは、鏡の方向に限定されるものではありませんから、ややこしいです。
プログラムでは、その目途にあわせて、最低限求めるもの、目をつぶってもいいものを
見定めてやって行くしかないですかね。
|
|
2022/6/12(Sun) 05:29:02|NO.96628
|
|