HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2022
0430
GENKIバッファからコピーすると3Dモデルが透明になる[hgimg4]8解決


GENKI

リンク

2022/4/30(Sat) 17:45:18|NO.96193

 hgimg4(HSP3.6/HSP3.7β1)のレンダリングバッファを使っていたところ、理屈が理解できない現象に遭遇しました。どのように理解すればいいのでしょうか。もしかして不具合?

 症状としては、celput命令でバッファ画像をメインウィンドウにコピーする際、gmode 0 ではなく gmode 1 で行うと3Dモデルが透明になってしまいます。本来であれば、モード1はモード0と同じ結果であるはずなので透明になることは無いはずです。また、同様の症状は gmode 2 でも発生します。3Dモデルは黒ではないため透明にならないはずですが、透明になってしまいます。

 これらの現象は、gploadで読み込んだモデルでのみ発生し、gpboxやgpfloorは影響を受けません。

 サンプルです。アヒルのモデルを使用しています。\sample\hgimg4 の res フォルダをコピーして実行してください。

#include "hgimg4.as" gpreset setcls CLSMODE_SOLID, $404040 widMain = 0 ; メインウィンドウ widBuffer = 1 ; レンダリングバッファ buffer widBuffer, , , screen_offscreen ; モデル ;gpbox id_model, 1 ; こっちなら透明にならない gpload id_model,"res/duck" ; モデルを読み込むと透明になる gpfloor id_floor, 8,8, $00ffff ; 床ノード ; デフォルトのカメラ setpos GPOBJ_CAMERA, 0, 2.0, 5 gplookat GPOBJ_CAMERA, 0, 0.3, 0 ; 2台目のカメラ gpnull id_camera gpcamera id_camera, , 640.0/480.0 setpos id_camera, 0, 4.0, 0.1 gplookat id_camera, 0, 0.3, 0.0 gsel widMain *main stick key,15 if key&128 : end ; ノードオブジェクトを回転 addang id_model, 0, 0.02, 0.01 ;----------------------------- ; レンダリングバッファ ;----------------------------- ; 1台目のカメラ映像 gsel widBuffer gpusecamera GPOBJ_CAMERA gpdraw ;----------------------------- ; メインバッファ ;----------------------------- ; 2台目のカメラ映像の上に、レンダリングバッファの画像を貼り付け。 gsel widMain redraw 0 ; 描画開始 gpusecamera id_camera gpdraw pos 300, 200 ; gmode 0 ; 通常のコピー gmode 1 ; アヒルが切り抜かれる?! ; gmode 2 ; アヒルが切り抜かれる?! ; gmode 6,,,128 ; 調整が効かない celput widBuffer, 0, 0.5, 0.5 redraw 1 ; 描画終了 ;----------------------------- ; ループ終了処理 ;----------------------------- await 16 ; 待ち時間 goto *main

 この現象はうまく使えば活用方法がありそうなのですが、不具合なのか仕様なのか判断がつかず利用できずにいます。



この記事に返信する


youdai

リンク

2022/4/30(Sat) 20:30:50|NO.96197

gpusecamera命令とは「カメラを切り替える命令」ではなく「そのカメラでレンダリングされるノード(オブジェクト)を設定する」命令となっています。

例えば

gpusecamera camera1 gpload モデル1 gpload モデル2 gpusecamera camera2 gpload モデル3 gpload モデル4

とした場合、camera1にはモデル1、モデル2だけが表示され、camera2にはモデル3、モデル4だけが表示されます。

GENKIさんの上記のスクリプトの場合、モデルが透明になっているのではなく、そのカメラにモデルが設定されていない状態のため、
モデルが結果的に表示されていない状態となっているのだと思います。

シーン(カメラ)ごとに描写するオブジェクトを切り分けたい場合、
setobjmodeで手動で非表示設定をする必要があります。

setobjrenderでレンダリンググループを指定して非表示を管理することも可能なようですが応用が利きにくいため、
通常はsetobjmodeで手動で設定した方が便利かもしれません。



GENKI

リンク

2022/4/30(Sat) 23:03:39|NO.96198

ありがとうございます。hgimg4は情報少ないので返信あるだけでもすごくありがたいです。

> とした場合、camera1にはモデル1、モデル2だけが表示され、camera2にはモデル3、モデル4だけが表示されます。

 説明いただいた通りであれば、上記スクリプトはカメラ id_camera を作成する前に gpload しているので、「gmode 0」を有効にしてもカメラ id_camera にはアヒルがレンダリングされないということになるのだと思います。
 しかし現状はカメラ id_camera ではアヒルはシルエットは確認できるので、レンダリングはされています。celputでコピーする際に透明と認識されている状況です。また「gmode 0」を有効にすれば、アヒルは正しく表示されます。

 今回のケースは「表示されていない」のではなくモデルが存在する部分に透明色が割り当てられているような状態です。アヒルのシルエット部分が切り抜かれて、背景画像だけがコピーされています。
実行時の絵はこちらの一番下の画像のような状態です。
https://mclab.uunyan.com/lab/hgimg4/hgimg4_010.htm

 オブジェクトを非表示にしたいわけではないので、setobjmode命令での OBJ_HIDEの有効化やレンダリンググループの設定は今回は必要としていません。



アキアキノヒロロ

リンク

2022/5/1(Sun) 06:55:15|NO.96202

バッファが絡むと、予期せぬ画面表示になってしまうことがあります。
特に文字表示と関連して起こるような感じがしてなりません。
恐縮ですが、「アキアキノヒロロ 文字表示」で掲示板検索していただけると、
関連がヒットします。そのうちの

NO.92368
> [HGIMG4] の setreq SYSREQ_USEGPBFONT,0
> による、または、非表示の既定の設定による、[mes]

NO.92373
> 文字表示用に使っている [buffer]? が、「他の処理をBufferで行っている環境で競合する可能性」

ということで、[font 設定不可](hsp351までの方式)となっている、『[hsp351] のエディタ』でやってみました。

やはりと言うか、予感的中。アヒルは透明にならず、思い通りの表示になりました。
そこで、現在のエディタで
> setreq SYSREQ_USEGPBFONT,1
を書き加えたらどうかと。しかし、何故かこれはダメ。
ならばと、screen_offscreen のバッファを色々代えてやってみましたが、上手くいきませんでした。

今の私に出来ることは、ここまでです。
https://twitter.com/akiakinohiroro/status/1520521930755166209



アキアキノヒロロ

リンク

2022/5/1(Sun) 07:34:44|NO.96203

> これらの現象は、gploadで読み込んだモデルでのみ発生し、gpboxやgpfloorは影響を受けません。

これって、gpload の3Dモデルと、gpboxやgpfloor のモデルでは、
[setalpha] の機能の仕方が違うのも関係していそうな気がします。
gpboxやgpfloor のモデルは、半透明になるけれど、
gpload の3Dモデルは、完全な透明か透明でないかのどちらかにしかなりませんよね。
だからどうなんだ、と言われても、その先は分からないですが。



GENKI

リンク

2022/5/1(Sun) 23:35:01|NO.96226

>> アキアキノヒロロさん
ありがとうございます。こちらでもHSP3.51で試したところ、gmode 0 と同じ出力結果が得られました。やはりこれが本来の正しい出力結果なのでしょうね。
3.6になった際にHGIMG4は大きく修正されているようなので、この影響で出来た不具合のような気がします。



youdai

リンク

2022/5/2(Mon) 05:15:02|NO.96229

まず前回の自分のgpusecameraについてのアドバイスですが、これは間違っていました。
gpusecameraについてですが、これは単純に「作ったカメラ設定を切り替える命令」のようです。
前回自分は


gpusecamera camera1 gpload オブジェクト1 gpload オブジェクト2 gpusecamera camera2 gpload オブジェクト3 gpload オブジェクト4

とするとcamera1にはオブジェクト1と2が表示され、camera2にはオブジェクト3と4が表示されると書きましたが、
そうではありませんでした。
これは主にgpuselightのカレントライトに関する設定で適用される概念でした。


gpuselight light1, 1 gpload オブジェクト1 gpload オブジェクト2 gpuselight light2, 1 gpload オブジェクト3 gpload オブジェクト4

混乱させたことをお詫びします。

●「gmode 1だと透過指定していないオブジェクトでも、くり抜いたように透過される現象」について

今回の「gmode 1だと透過指定していないオブジェクトでも、くり抜いたように透過される現象」について研究を進めていくにつれ、
いくつかの事柄が分かってきました。

検証するために、普段自分が組んでいるスクリプトの構造にできるだけ近づけるため、0から書き直しました。


#include "hgimg4.as" #enum SCID_MAIN = 0 ; メインのスクリーン #enum SCID_BUF0 ; バッファ0番 #enum SCID_BUF1 ; バッファ1番 #enum SCID_BUF2 ; バッファ0番と1番を結合する用のバッファ #const FPS_AWAIT 1000 / 60 gosub *setup ; 準備処理 goto *main ; 繰り返し処理 ;------------------------------------------------------------------------------- ; 準備処理 *setup ; スクリーンやカメラ等の設定 screen_width = 800 screen_height = 600 bairitu = 0.5 fov = 48 aspect = 1.33333333333333333333 ; 4 : 3 のアスペクト比 near = 0.5 far = 768.0 sw = 0 gosub *create_screen gosub *create_camera gosub *create_obj return *create_screen setreq SYSREQ_VSYNC, 1 ; VSYNC同期ON setreq SYSREQ_CLSMODE, 0 ; 背景を自動で消去しない(手動で行う) setreq SYSREQ_LOGWRITE, 0 ; log出力をしない gpreset screen SCID_MAIN, screen_width, screen_height ; メインのスクリーン buffer SCID_BUF0, screen_width, screen_height, screen_offscreen ; オフスクリーンバッファ buffer SCID_BUF1, screen_width / 2, screen_height / 2, screen_offscreen ; オフスクリーンバッファ buffer SCID_BUF2, screen_width, screen_height, screen_offscreen ; オフスクリーンバッファ return ; カメラを作成 *create_camera ; 今回の処理の場合、1台だけで良い gpnull id_camera gpcamera id_camera, fov, aspect, near, far, sw setpos id_camera, 0.0, 0.0, 0.0 setang id_camera, 0.0, 0.0, 0.0 ; カメラの位置と角度はblender基準と同一にしてある ; HGIMG4のsample等でよく見る座標基準とは異なることに注意 camera1_pos = 7.3589, -6.39258, 4.9583 camera1_angZ = deg2rad(63.6), deg2rad(0.0), deg2rad(46.7) camera2_pos = -0.18266, 1.0128, 11.476 camera2_angZ = deg2rad(-5.24), deg2rad(0.0), deg2rad(13.1) ;lookat_target = 0.0, 0.3, 0.0 return ; 通常のオブジェクトを作成 *create_obj gpusecamera id_camera ; id_cameraの状態に対して、以下のオブジェクトを生成する gpnull id_gpb ; tamane2バージョン gpload id_gpb, "res/tamane2", "" setobjmode setpos id_gpb, 0.0, 0.0, -3.0 ; tamane2はスケールが大きすぎるため、調整する setscale id_gpb, 0.025, 0.025, 0.025 ; tamane2はBlenderと同じ角度を入力すると倒れているため、角度を調整する setangZ id_gpb, deg2rad(90.0), 0.0, 0.0 ; duckバージョン /* gpload id_gpb, "res/duck", "" setpos id_gpb, 0.0, 0.0, 0.0 setangZ id_gpb, deg2rad(90.0), 0.0, 0.0 setscale id_gpb, 1.0, 1.0, 1.0 */ /* gpnull id_floor gpfloor id_floor, 8.0, 8.0, $00ffff setpos id_floor, 0.0, 0.0, 0.0 */ return ; 終了処理 *escape stick key,15 if key&128 : end return *sub_draw gosub *buf0_draw gosub *buf1_draw gosub *ketugou ;gosub *ketugou_nashi ; 結合なし版 return *buf0_draw gsel SCID_BUF0 ; カメラの位置と向きを変更 setpos id_camera, camera1_pos.0, camera1_pos.1, camera1_pos.2 setangZ id_camera, camera1_angZ.0, camera1_angZ.1, camera1_angZ.2 ;gplookat id_camera, lookat_target.0, lookat_target.1, lookat_target.2 redraw 0 ; 背景の手動消去 rgbcolor $808080 boxf ; 通常のgpdraw gpdraw return *buf1_draw gsel SCID_BUF1 ; カメラの位置と向きを変更 setpos id_camera, camera2_pos.0, camera2_pos.1, camera2_pos.2 setangZ id_camera, camera2_angZ.0, camera2_angZ.1, camera2_angZ.2 ;gplookat id_camera, lookat_target.0, lookat_target.1, lookat_target.2 redraw 0 ; 背景の手動消去 ; 意図的に色は変えてあります。こちらは赤で表示されます rgbcolor $800000 boxf ; シーンのみ描写する。自動移動等はしない gpdraw GPDRAW_OPT_DRAWSCENE return *ketugou gsel SCID_BUF2 redraw 0 gmode 0 pos 0, 0 celput SCID_BUF0 pos 200, 100 gmode 1 celput SCID_BUF1 return *ketugou_nashi gsel SCID_BUF2 redraw 0 gmode 0 pos 0, 0 celput SCID_BUF0 return *main_copy gsel SCID_MAIN redraw 0 pos 0, 0 gmode 0 ; この場合、このcelputそのものが画面初期化になる celput SCID_BUF2 redraw 1 ; この地点で全て一度に描画される return *action addang id_gpb, 0.0, 0.02, 0.0 return ;------------------------------------------------------------------------------- ; 繰り返し処理 *main gosub *escape gosub *action gosub *sub_draw gosub *main_copy await FPS_AWAIT goto *main

(上記のスクリプトはsample/hgimg4フォルダに入れれば動くようになっています)

まず、GENKIさんの最初のスクリプトを再現するに当たって、カメラは1台で済むことは予め分かっていたので、1台で組みました。
gplookatについては角度によっては「不自然な捻じれ」現象が起こりやすいので、今回は検証の厳密さが必要ですから使いませんでした。

バッファについては0番と1番を描画して、その0番と1番を結合するためのバッファを作りました。
そして、その結合したバッファをメインスクリーンへコピーします。
わざわざ結合用のバッファを作成し、そこからメインスクリーンへコピーする理由はチラつき防止と、
スクリプト上で整理整頓がしやすいからです。
加えて、今回は行いませんでしたが、この方がポストエフェクトが掛けやすいからです。

現象をわかりやすくするために、小さいバッファの方の背景は赤で表示してあります。

それで「gmode 1だと透過指定していないオブジェクトでも、くり抜いたように透過される現象」ですが、
その現象はduckでは分かりやすく全体が透過されますが、tamane2では当該の現象は起きませんでした。
もしかしたらもっとよく見ればどこかに起きているのかもしれませんが、パッと見て、どこにも起きていないように見えます。
スカートの裏面が消えていますが、それは元々の仕様だと思うので今回の問題とは無関係な現象です。

tamane2とduckの違いは、シェーダーの違いかもとも思ったのですが、
tamane2もduckも共にtexturedのシェーダーしか使っていませんでした。

次にマテリアルの設定を確かめてみたのですが、
tamane2のdefinesにはDIRECTIONAL_LIGHT_COUNT 1が設定されていなくて、
duckの方には設定されていました。

そこでtamane2にDIRECTIONAL_LIGHT_COUNT 1を設定してみましたが、この場合tamane2もgmode 1でduckのように透過されました。
次にduckのDIRECTIONAL_LIGHT_COUNT 1を削除してみましたが、今度はduckがtamane2のように正常に表示されました。

つまり、今回の現象はDIRECTIONAL_LIGHT_COUNTと関係する現象のようです。

gpboxやgpfloorですが、もしかしたらこちらもDIRECTIONAL_LIGHT_COUNTのマテリアル設定をすれば、
gmode 1で透過現象が起きるかもしれません。

現状の現象をあえて言い換えるなら「gmode 1は、ライト設定をしたマテリアルだけ、くり抜くモード」と
言えるのかもしれません。



アキアキノヒロロ

リンク

2022/5/2(Mon) 17:41:23|NO.96234

ライトのマテリアル設定が関係しているというのは、ありだと思います。

光源がものに遮られていれば、その後ろには光は行かないはずです。
光は遮ったものに当たるのは当然ですが、今の[hgimg4] では、しかし、
その後ろにあるものにも当たるのです。
まるで、そのものが存在しない(透明)かのように、その陰になるものにも光が反映します。
これも、今回のことに関係するように思えます。
https://twitter.com/akiakinohiroro/status/1475573476530753536

また、[gptexmat]を使わず、色指定の[gpfloor]や[gpplate]の場合。
その色指定の色の要素に、ライトの色の要素が含まれていないと、
ライトの色は「床」や「板」に反映しないように見えます。
反映されないということは、色のオーバーレイ か?元の色要素が [0] なら、変化なしになるんじゃないか。
これってすごく意味深で、光線は空気に反映されて、光線になってる訳?だとすれば、
空気がない3D空間では光線は表現できないってことで、3D空間にも、漂う無数の塵ノードが必要?

あれやこれやと考え合わせると、[hgimg4] では、光の表現にレイヤーを利用していて、
レンダリングバッファを使っているのではないか。この表現があっているか分かりませんが。

こう考えてくると、やはり、ライトのマテリアル設定からくる光の表現方法が関係しているようです。



GENKI

リンク

2022/5/2(Mon) 19:31:12|NO.96237

>> youdaiさん NO.96229
> これは主にgpuselightのカレントライトに関する設定で適用される概念でした。

情報の修正ありがとうございます。
ライトはそういう仕様なんですね。つまづきそうなポイントですねこれ。

DIRECTIONAL_LIGHT_COUNT の設定変更での動作について、手元の環境でも確認できました。ライト関連っぽいですね。どうやってここまでたどり着いたのか…すごいです。

hgimg4は、テクスチャ関連がまだ開発中のようなので、アキアキノヒロロさんのツイートもそうですが、こういう物体表面関連の不具合は今後も見つかるかもしれませんね。しかし今回のは今のところ悪影響はないので修正を待つばかり。



ONION software Copyright 1997-2023(c) All rights reserved.