パラメータ

目次

はじめに

 前回のHGIMG4のイベント関連で出てきた パラメータについて、一部を少し掘り下げてみようと思います。 ここで言うパラメータは、命令の引数のことではなく、HGIMG4で取り扱うノードオブジェクトが持つさまざまな情報のことです。 次のような命令で取り扱います。

命令パラメータ操作event_系命令
gpsetprm値を上書きevent_prmset
gpsetprmon指定ビットをONevent_prmon
gpsetprmoff指定ビットをOFFevent_prmoff
gpgetprm値を取得-

 マニュアル(HDL)に記載されているような設定を扱うことができます。 たくさんあるので、個人的に気になったPRMSET_FLAGPRMSET_MODEPRMSET_ALPHAについて少し調査しました。

PRMSET_FLAG

 PRMSET_FLAG「オブジェクト登録フラグ」は、マニュアルには説明がありません。(HSP3.7Bβ4現在) HGIMG3にも同名のPRMSET_FLAG「存在フラグ」という名前のパラメータがありましたが、HGIMG4のものとは動作が異なります。 基本的には常に1を持っています。

 マニュアルの説明では、基本的に呼び出しのみで利用する事になっていますが、gpsetprmで値を書き込むことができてしまいます。 0を指定するとオブジェクトが破棄され、0以外は挙動に影響ありません。 影響ないならユーサー側で好きに使っていい領域!便利!とも考えたのですが、どうやらそうもいかないようです。 この動作は保証されているわけでなく、決められていないので影響がない、という状況のようです。 将来、仕様が変わってしまうと挙動に影響が出る可能性もあるので、「呼び出しのみ」と書かれている項目は呼び出しのみで使ったほうが良さそうです。

 本来の用途は何なのでしょうね。 オブジェクトが使用できるかどうかを確認するフラグかとも考えたのですが、delobjなどでオブジェクトが破棄されてしまえば、gpgetprmで情報を取得しようとするとエラーになるのでPRMSET_FLAGの状態取得ができません。 うーん。

PRMSET_MODE

 PRMSET_MODEパラメータを指定すると、ノードオブジェクトに対して動作モードを設定できます。 ラベルによって、表示/非表示やワイヤーフレーム表示の切り替え、自動移動のON/OFFなど、さまざまな情報を設定できます。 詳しくは、マニュアル参照。

HGIMG4プログラミングガイド 17.オブジェクトのモード設定
https://www.onionsoft.net/hsp/v37/doclib/hgimg4.html#MODE_OBJ

 大変有益な機能なのですが、設定できるモードについて個別の詳しい説明が不足しています。 OBJ_HIDEOBJ_TIMEROBJ_LATEOBJ_MOVEについては、HGIMG4プログラミングガイド内で触れられている部分がありますが、その他については概要を記述した1行程度の情報しかありません。

 これではどんな機能があるのかを把握しにくいので、調べてわかった使い方と、既存の情報についてをまとめて記載してみました。

 まずは、どんなラベルがあるのか。HGIMG4プログラミングガイドにまとめてありますが、setobjmodeにHGIMG3も合わせた情報があったので表に追加してみました。 HGIMG3でも使用しているラベルは、hgimg3.txtに説明が載っていることがあるので参考にできそうです。 ただし、必ずしもhgimg3.txtの説明と同じ動作をすることが保証されているわけではない点に注意が必要です。

ラベル内容HGIMG3HGIMG4
OBJ_HIDE 非表示(画面から消す)
OBJ_CLIP 3Dクリッピングを有効にする
OBJ_XFRONT 正面属性(常に画面に正面を向く)
OBJ_WIRE ワイヤーフレームで描画する
OBJ_MOVE 自動移動を行なう(XYZ移動量を参照する)
OBJ_FLIP ボーダー領域で反転する
OBJ_BORDER ボーダー領域を有効にする
OBJ_2D 2Dスプライト
OBJ_TIMER タイマーを有効にする
OBJ_LATE 後から描画される(半透明オブジェクト用)
OBJ_FIRST 常に最初に描かれる
OBJ_SORT 自動的に奥から描かれる(3Dオブジェクト用)
OBJ_LOOKAT 特定オブジェクトの方向を常に向く
OBJ_LAND Y座標を常に一定に保つ
OBJ_GROUND 地面として認識される
OBJ_STAND 地面の上に配置する
OBJ_GRAVITY 重力計算を有効にする
OBJ_STATIC 障害物として認識される
OBJ_BOUND 地面で反発する(メッシュマップコリジョン用)
OBJ_ALIEN ターゲットに向ける(メッシュマップコリジョン用)
OBJ_WALKCLIP移動の制限を受ける(メッシュマップコリジョン用)
OBJ_EMITTER エミッター発生オブジェクトになる

 HGIMG3とHGIMG4で重複するラベルが結構ありますね。重複するものは、hgimg3.txtも参考にすると理解が深まると思います。 HGIMG3にはあって、HGIMG4にはないラベルが結構あります。これについては、実装方法が変わった影響で不要になったものとかもあるので、あまり気にしなくていいと思います。

 一覧表ができたので、次は個別の機能について概略を整理しました。といっても資料はないので、実際に使ってみた結果などが根拠です。

OBJ_HIDE
非表示(画面から消す)
 画面上に表示されません。表示されないだけで、実体は存在しています。描画だけが行われない状態です。 物理特性を設定すれば、衝突判定も行われます。
少ないポリゴン数で衝突判定用のオブジェクトを使って非表示にし、画面上の同じ位置にはポリゴン数が多い複雑な形状のモデルを置く、という運用ができるので便利な機能です。
OBJ_CLIP
3Dクリッピングを有効にする
 名前から推測すると、有効にするとカメラに写っていない場合は描画しない機能だと思います。 ポリゴン数が大きいノードオブジェクトを使う際に処理負荷が軽くなるのだと思います。 確認は保留。
OBJ_XFRONT
正面属性(常に画面に正面を向く)
 X回転軸がカメラのX回転軸と同期します。gpplateを使うと、カメラに対して常に同じ面を同じ向きで表示する板を配置できます。 詳細は後述。
OBJ_WIRE
ワイヤーフレームで描画する
 ワイヤーフレームで表示します。面が表示されずに、頂点同士を結ぶ辺だけの表示になります。
OBJ_MOVE
自動移動を行なう(XYZ移動量を参照する)
 dirグループ(移動ベクトル)による自動移動を行うようになります。dirグループに0より大きい値を設定して、このパラメータをONにすることで自動移動が有効になります。 dirグループとOBJ_MOVEの両方を設定しなければ見た目の変化はありません。
HGIMG4プログラミングガイド 13.3D動作の概要
https://www.onionsoft.net/hsp/v37/doclib/hgimg4.html#3DABSTRACT
OBJ_FLIP
ボーダー領域で反転する
 HGIMG4付属のサンプルtest12.hspで動きを確認できます。 ボーダー領域から外に出ようとした場合に、壁にあたって反射するような動きをするみたいです。 基本的にOBJ_BORDERとセットで使うものだと思います。
OBJ_BORDER
ボーダー領域を有効にする
 HGIMG4付属のサンプルtest12.hspで動きを確認できます。 ボーダー領域を有効にして、使用できるようにします。ボーダー領域の説明がないのですが、描画エリアとどう違うんだろうか…。 基本的にOBJ_FLIPとセットで使うものだと思います。というか、OBJ_FLIPでしかボーダー領域を使用していません。
OBJ_2D
2Dスプライト
 スプライト関連?説明もサンプルもなく、hgimg3でも同じ状況です。
OBJ_TIMER
タイマーを有効にする
 オブジェクトタイマーが有効になります。PRMSET_TIMERで指定したフレーム数が経過すると、オブジェクトは破棄されます。 詳しくは、HGIMG4プログラミングガイド「オブジェクトタイマー」を参照。HGIMG3とは、挙動が異なるので移行してきた方は注意。
https://www.onionsoft.net/hsp/v37/doclib/hgimg4.html#TIMER_OBJ
OBJ_LATE
後から描画される(半透明オブジェクト用)
 半透明オブジェクトを表示する際に使用します。
 半透明オブジェクトの描画結果は、表示する順番の影響を受けます。 半透明オブジェクトを期待した通りの描画を行うためには、必ず不透明オブジェクトを描画し終わった後に半透明オブジェクトを描画しなければいけません。 しかしオブジェクトを描画する順番は、オブジェクトを作成した順番で決定されます。
 OBJ_LATEを有効にすると、OBJ_LATEが無効になっているオブジェクト(不透明オブジェクト)よりも後に描画されるようになります。
 少しわかりにくいので、詳細は後述します。

 自分が使いそうなものを中心に、ざっくりまとめてみました。 説明し足りない項目については、あとで掘り下げます。

PRMSET_MODE サンプル

 言葉だけの説明だと確認が面倒ですよね。ということでサンプルです。キーボードのカーソルキーで動かせます。


  #include "hgimg4.as"
  title "HGIMG4 Test"
  
    gpreset
    setcls CLSMODE_SOLID, $808080		; 画面クリア設定
    setpos GPOBJ_CAMERA, 0, 2, 10		; カメラ位置を設定
  
    ; 箱ノード
    gptexmat id_texmat, "res/qbox.png"
    gpbox   id_box, 1, -1, id_texmat
    setpos  id_box,	0, 0.5, -3
    gppbind id_box, 1, 0.5				; 箱の物理設定を行なう
    gppset  id_box, GPPSET_ANGULAR_FACTOR, 0,0,0	; 回転を固定
  
    ;	箱ノード量産
    dim id_boxc, 11
    repeat 11
      dx = 2. * cnt - 10
      gpbox   id_boxc(cnt), 1, -1, id_texmat
      setpos  id_boxc(cnt), dx, 0.5, 0.0
      
      ;	半透明テスト
      ;gpsetprm id_boxc(cnt), PRMSET_ALPHA, 127
      
      ;	フェードテスト
      ;gpsetprm id_boxc(cnt), PRMSET_FADE, -1
      
      ;	移動テスト
      setdir id_boxc(cnt), 0, 0.01, 0
      
      ; タイマーをセット
      ; 指定フレーム数後にオブジェクト削除
      gpsetprm id_boxc(cnt), PRMSET_TIMER, 1000
    loop
    
    ;	パラメータ設定
    gpsetprm id_boxc( 1), PRMSET_MODE, OBJ_HIDE		; 非表示(画面から消す)
    gpsetprm id_boxc( 2), PRMSET_MODE, OBJ_CLIP		; 3Dクリッピングを有効にする
    gpsetprm id_boxc( 3), PRMSET_MODE, OBJ_XFRONT	; 正面属性(常に画面に正面を向く)
    gpsetprm id_boxc( 4), PRMSET_MODE, OBJ_WIRE		; ワイヤーフレームで描画する
    gpsetprm id_boxc( 5), PRMSET_MODE, OBJ_MOVE		; 自動移動を行なう(XYZ移動量を参照する)
    gpsetprm id_boxc( 6), PRMSET_MODE, OBJ_FLIP		; ボーダー領域で反転する
    gpsetprm id_boxc( 7), PRMSET_MODE, OBJ_BORDER	; ボーダー領域を有効にする
    gpsetprm id_boxc( 8), PRMSET_MODE, OBJ_2D		; 2Dスプライト
    gpsetprm id_boxc( 9), PRMSET_MODE, OBJ_TIMER	; タイマーを有効にする
    gpsetprm id_boxc(10), PRMSET_MODE, OBJ_LATE		; 後から描画される(半透明オブジェクト用)
  
  
    ; 床ノードを追加
    gpfloor id_floor, 30,30, $404040
    gppbind id_floor, 0				; 床の物理設定を行なう
  
  repeat
    stick key,15
    if key&128 : end
  
    ; 箱
    objexist id_box
    if stat = 0 {
      ;	カーソルキーで箱を動かす
      if key&1 : gppapply id_box, GPPAPPLY_IMPULSE, -0.1,  0  , 0
      if key&4 : gppapply id_box, GPPAPPLY_IMPULSE,  0.1,  0  , 0
      if key&8 : gppapply id_box, GPPAPPLY_IMPULSE,  0,0,  0.1
      if key&2 : gppapply id_box, GPPAPPLY_IMPULSE,  0,0, -0.1
      ; カメラを自機に向ける
      getpos id_box,dx,dy,dz
      gplookat GPOBJ_CAMERA, dx,dy,dz
    }
    
    redraw 0
      gpdraw
  
      ; 箱の量産品
      repeat 11
        objexist id_boxc(cnt)
        if stat = 0 {
          getpos id_boxc(cnt), px, py, pz
          gpcnvaxis vx, vy, vz,  px, py-0.5, pz+0.5, 0
          pos vx, vy
          gpgetprm v, id_boxc(cnt), PRMSET_MODE
          mes "PRMSET_MODE\n" + strf("0x%04X", v)
          if v & OBJ_HIDE   : mes "OBJ_HIDE"
          if v & OBJ_CLIP   : mes "OBJ_CLIP"
          if v & OBJ_XFRONT : mes "OBJ_XFRONT"
          if v & OBJ_WIRE   : mes "OBJ_WIRE"
          if v & OBJ_MOVE   : mes "OBJ_MOVE"
          if v & OBJ_FLIP   : mes "OBJ_FLIP"
          if v & OBJ_BORDER : mes "OBJ_BORDER"
          if v & OBJ_2D     : mes "OBJ_2D"
          if v & OBJ_TIMER  : mes "OBJ_TIMER"
          if v & OBJ_LATE   : mes "OBJ_LATE"
  
          if v & OBJ_TIMER {
            gpgetprm v, id_boxc(cnt), PRMSET_TIMER
            mes "Timer:" + v
          }
          
        }
      loop
      
    redraw 1			; 描画終了
    await 1000/60		; 待ち時間
  
  loop  

 OBJ_MOVEOBJ_TIMERを有効にしたオブジェクトは、いつの間にか画面から消えてしまうのでご注意ください。

 また、コメントを外せば半透明やフェードも試せますが…、サンプルとしては分かりにくいので、あまり意味はなかったかも。

正面属性 OBJ_XFRONT

 正面属性(常に画面に正面を向く)という名前だけ聞くとビルボードかな?と思ってしまったのですが、調べてみると違う動作をするものでした。

 ビルボードというのは、常にカメラに対して「同じ側の面を向く」ように、オブジェクトのY軸回転が自動的に制御されるものです。 一方で正面属性は、常にカメラに対して「同じ面を向けて、上下左右の向きも同じ方向を向く」ように、オブジェクト姿勢が自動的に制御されるものです。

 具体的には、こういう仕組みで制御されています。 正面属性を持つノードは、X回転軸がカメラのX回転軸とまったく同じ方向と姿勢を向くように回転されます。 この動きによって、ノードのZ軸が必ずカメラの方向を向きますし、X軸もカメラと同じなので傾いたりもしません。

 なお、正面属性を指定したノードは、getangによる姿勢変更後の値を取得できますが、setangによる姿勢変更はできません。

 言葉だけの説明だとわかりにくいのでサンプル書きました。 説明の動きは、gpboxでやってみると理解の助けになります。


  ;	正面属性
  ;
  ; カーソルキーとZ,Xキーでカメラを動かせます。
  ;
  #include "hgimg4.as"
  title "HGIMG4 Test"
  
    gpreset
    setcls CLSMODE_SOLID, $808080		; 画面クリア設定
    camx = 0.0
    camy = 2.0
    camz = 7.0
    setpos GPOBJ_CAMERA, camx, camy, camz
  
    ; 箱ノード
    gptexmat id_texmat, "res/qbox.png"
    gpbox   id_box, 1, -1, id_texmat
    setpos  id_box,	0, 0, 0
  
  
    ;	ノード量産
    ; カメラの周りに円柱状に配置。
    ; カメラの後ろには、配置していません。
    dim id_obj, 180
    id = 0
    repeat 10
      dy = 2.0 * (cnt-5)
      repeat 18, 18
        dx = 10.0 * cos(deg2rad(10.0 * cnt)) + camx
        dz = 10.0 * sin(deg2rad(10.0 * cnt)) + camz
        ;gpplate id_obj( id ), 1, 1, -1, id_texmat
        gpbox   id_obj( id ), 1, -1, id_texmat
        setpos  id_obj( id ), dx, dy, dz
        
        ; 正面属性(常に画面に正面を向く)
        gpsetprm id_obj( id ), PRMSET_MODE, OBJ_XFRONT
        id++
      loop
    loop
    
  
  repeat
    stick key,15 + 2048 + 4096
    if key&128 : end
  
    ; 	カーソルキーでカメラを動かす
    r = deg2rad( 1)
    if key & 1 : addang GPOBJ_CAMERA, 0, r, 0
    if key & 4 : addang GPOBJ_CAMERA, 0, -r, 0
    if key & 8 : addang GPOBJ_CAMERA, -r, 0, 0
    if key & 2 : addang GPOBJ_CAMERA,  r, 0, 0
    if key & $0800 : addang GPOBJ_CAMERA, 0, 0, -r ; Z
    if key & $1000 : addang GPOBJ_CAMERA, 0, 0,  r ; X
  
  
    
    redraw 0
      gpdraw
  
      ; 箱の量産品
      repeat 180
        getpos id_obj(cnt), px, py, pz
        gpcnvaxis vx, vy, vz,  px, py-0.5, pz, 0
        pos vx, vy
        getang id_obj(cnt), x,y,z
        ;mes strf( "%3.1f, %3.1f, %3.1f", rad2deg(x), rad2deg(y), rad2deg(z) )
  
        ; 効果がない
        ;setang id_obj(cnt), 0,0,0
      loop
      
    redraw 1			; 描画終了
    await 1000/60		; 待ち時間
  
  loop
  • カメラを操作できます。カーソルキーで移動、Z、Xキーで回転させることができます。
  • 実行直後、中央に表示される箱は動きません。動かない箱は、カメラの姿勢を把握するための目印です。
  • 背景に配置した箱はすべて、正面属性を付与しています。
  • 正面属性が付与された箱は、常にカメラに対して同じ面を同じ向きで表示していることが確認できます。

 箱gpboxだと起きていることは理解しやすいのですが、運用を考えると使い道が思いつきません。 この機能は、主にgpplateを使った表現を想定したものだと思われます。 gpplateに正面属性を適用すると、常にカメラに対して表面を見せるように姿勢が自動調整されます。


gpplate id_obj( id ), 1, 1, -1, id_texmat

 これなら活用方法がすぐに思いつきますね。パーティクルとして使う。 キャラクターの頭の上座標に、アイコンを表示する。 ヘッドアップディスプレイのような演出として使用する。 などの運用方法ができそうですね。

半透明オブジェクトの描画

 半透明オブジェクトを取り扱う場合、内部での「描画順」がとても重要です。 HGIMG4は、描画順にしたがってオブジェクトを1個ずつ描画します。 先に書いたオブジェクトと同じ方向にある、より遠くにあるオブジェクトは描画を行いません。 先に書いたオブジェクトで隠れてしまって見えないはずだからです。

 ところが、先に書いたオブジェクトが半透明だった場合、隠れたオブジェクトは見えるはずなので、描画されないというのは困ります。

 この問題は、遠くにあるものから順に描画されるような「描画順」になってくれていれば解決します。 しかし現在(HSP3.7β4)のHGIMG4にはこの機能がなく、基本的に「描画順=オブジェクトを作成した順番」です。

 これでは、常に半透明オブジェクトの作成順を気にする必要がありとても不便です。 そこでHGIMG4では、「不透明オブジェクトをすべて描画し終わってから、半透明オブジェクトを描画する」という方法でこの問題を解決しています。 全部のオブジェクトを奥行きでソートして描画順を決めるよりも、はるかに低負荷で効果的な実装方法ですね。

 しかしこの方法にも問題が残っていて、半透明オブジェクトどうしが重なった場合は、オブジェクト作成順で描画されてしまうので、半透明なのに透けない問題が発生する場合もあります。 半透明オブジェクトどうしの重なりを正しく描画したい場合は、オブジェクトの作成順を調整する必要があります。

半透明オブジェクトの実装

 半透明オブジェクトを取り扱う場合、大きく分けて以下のようなケースがあります。

  • オブジェクトノード全体を半透明にする場合
  • テクスチャを使ってオブジェクトの一部を半透明にする場合

 いずれの場合も、描画順番を気にする必要があるという共通事項がありますが、実装時の作業内容が若干異なります。 違いを確認するため、表にしてみました。

描画結果必要な処置
(全体)
必要な処置
(テクスチャ)
非表示OBJ_HIDEを設定テクスチャ画像のα値に 0 を指定する
半透明PRMSET_ALPHAを設定テクスチャ画像にα値(1~254)を指定する
不透明なしテクスチャ画像に不透明(α値=0)を指定する

 オブジェクト全体を半透明にするためPRMSET_ALPHAを使用した場合、OBJ_LATEを設定する必要はありません。 楽でいいのですが、設定する値によって挙動が異なるので、表にまとめました。

PRMSET_ALPHA描画結果補足説明
0 非表示PRMSET_ALPHAで0にすると見えなくなるだけですが、PRMSET_FADEで0になるとオブジェクトが破棄されます。
1~254半透明自動で不透明のオブジェクトよりも後に描画されるようになります。OBJ_LATEをONにしたときと同じ挙動です。ただしOBJ_LATEがONになるわけではない。ややこしい。
255 不透明通常の表示なので何もしなくて良い。

 PRMSET_ALPHAを使用すると、HGIMG4側はオブジェクトが「半透明」であることを知ることができます。なのでHGIMG4側が描画順を勝手に設定してくれます。 しかしテクスチャの場合は、半透明か不透明かをHGIMG4側は知ることができません。 ユーザー側が、HGIMG4にプログラムする際、OBJ_LATEを使って描画順を最後にする必要がある事を知らせる必要があります。

αチャンネル描画結果必要な処置補足説明
0 表示されないなし 標準でピクセルのカットオフが適用される。カットオフされたピクセルは、完全な透明になる。
1~254半透明 OBJ_LATEを有効にする。描画順の影響を受けるため、不透明のオブジェクトよりも後に描画する必要がある。
255 不透明 なし 通常の表示なので何もしなくて良い。

 半透明を使用した場合、上記の対応を行っても半透明同士が重なった際に、適切な描画が行われない場合もあります。 原因は、描画順(オブジェクト作成順)が描画結果に影響を与えるためです。 適切な描画結果を得るためには、手動でZ座標をソートして奥から順番に描画する必要がありますが、現在のHGIMG4(HSP3.7β3)にはその機能はありません。 正しくない描画結果がなるべく目立たなくなるようにうまく工夫したほうが解決は早いと思います。 将来的にこの問題はHGIMG4側が解決してくれる計画らしいので、それをあてにするのもありですね。

 サンプルを使って描画順の動作確認してみます。


  ;	半透明の描画順序
  #include "hgimg4.as"
  
    gpreset
    setcls CLSMODE_SOLID, $808080		; 画面クリア設定
    setpos GPOBJ_CAMERA, 0, 2, 10		; カメラ位置を設定
  
    ; 箱ノード用テクスチャ
    gptexmat id_texmat, "res/qbox.png"
  
    ;	箱ノード量産
    dim id_boxc, 6
    repeat 6
      gpbox   id_boxc(cnt), 1, -1, id_texmat
    loop
    ; 左の3つ
    setpos  id_boxc(0), -2.0, 0.5,  0.0	; 先に描画されるため、
    setpos  id_boxc(1), -1.5, 1.0, -1.0	; 奥のオブジェクトの深度情報を遮ってしまい、
    setpos  id_boxc(2), -1.0, 1.5, -2.0	; 奥側が描画されない。
    
    ; 右の3つ
    setpos  id_boxc(3), 1.0, 1.5, -2.0
    setpos  id_boxc(4), 1.5, 1.0, -1.0
    setpos  id_boxc(5), 2.0, 0.5,  0.0
  
    ; 左の3つ
    gpsetprm id_boxc(0), PRMSET_ALPHA, 127
    ;gpsetprm id_boxc(1), PRMSET_ALPHA, 254	; 255
    gpsetprm id_boxc(2), PRMSET_ALPHA, 127
    
    ; 右の3つ
    gpsetprm id_boxc(3), PRMSET_ALPHA, 127
    ;gpsetprm id_boxc(4), PRMSET_ALPHA, 254	; 255
    gpsetprm id_boxc(5), PRMSET_ALPHA, 127
  
    ; 後から描画される(半透明オブジェクト用)
    ;gpsetprm id_boxc(1), PRMSET_MODE, OBJ_LATE
  
    ; 床ノードを追加
    gpfloor id_floor, 30,30, $404040
  
  *main
    stick key,15
    if key&128 : end
  
    redraw 0
      gpdraw
      ;pos 10,10
      ;mes "(ID) PRMSET_MODE, PRMSET_ALPHA"
      ;repeat 6
      ;	gpgetprm m, id_boxc(cnt), PRMSET_MODE
      ;	gpgetprm a, id_boxc(cnt), PRMSET_ALPHA
      ;	mes "(" + cnt + ") " + strf("0x%04X, %d", m, a)
      ;loop
    redraw 1
    await 1000/60
  
    goto *main

 箱ノード3個を2グループ左右に配置しています。不透明オブジェクト1つを半透明オブジェクト2つではさむような形で配置しています。 左右のグループでは、オブジェクトを作成する順番が異なります。左のグループは手前から奥に、右のグループは奥から手前の順に作成しています。全体としては、左の箱から順にオブジェクトを作成しました。

サンプル実行結果

 不透明と半透明のオブジェクトが重なった場合は、とくに支障はありません。 PRMSET_ALPHAが指定されたオブジェクトは、自動的に不透明オブジェクトの後に描画される設定となるためです。 すべて半透明オブジェクトになると描画順の影響が確認しやすくなります。


gpsetprm id_boxc(1), PRMSET_ALPHA, 254
…
gpsetprm id_boxc(4), PRMSET_ALPHA, 254

サンプル実行結果

 すべての箱ノードが半透明オブジェクトになったので、オブジェクト作成順がそのまま描画順になります。 左側のグループは手前から奥に向かって描画しているので、一番手前の箱が描画されると、その影で隠れている部分はもう描画されません。 描画されないので、透けて見えるはずがありません。

 右側のグループは奥から手前の順に描画されるので、透けて見えるべき部分が先に描画されるためちゃんと透けて見えます。

 半透明オブジェクト用のオプション、OBJ_LATE(後から描画される)を試してみます。 透過色を使用したテクスチャを使用している場合は、このような処置が必要になります。 id_boxc(1)id_boxc(4)PRMSET_ALPHAを無効にして、不透明オブジェクトに戻しておいてください。次のように記述して、不透明オブジェクトにOBJ_LATEを追加してみます。


gpsetprm id_boxc(1), PRMSET_MODE, OBJ_LATE

サンプル実行結果

 これで他の半透明オブジェクトと同じタイミングで描画されるようになりました。 同じタイミングならオブジェクト作成順が優先されるので、手前の半透明オブジェクト描画後に描画されます。 透けているのに描画されませんね。

 半透明オブジェクトどうしの重なりがある場合は、描画順を理解していないと想定通りの描画になりません。 理解していても想定通りの描画に出来ない場合もあります。オブジェクトを作成する順番を工夫してもダメな場合は、あきらめましょう。(´・ω・`)

まとめ

パラメータは、機能がたくさんある割に情報不足で困りますね。 ここであまり説明していない項目については、次のいずれかです。気になる方は、ご自身で調査してください。

  • マニュアルに説明があるので十分じゃないかと思っている。
  • 自分が使わなさそうだから保留した。
  • よくわからない機能だから保留した。
  • 面倒だから誰か調査してほしい。

OBJ_2Dを使ってる方はいるんですが、どこで使い方調べたんだろう。

関連記事

  1. イベントリスト 目次 イベントリスト イベントの設定方法 制御系 ang、a...
  2. マテリアルの設定変更 目次 materialファイルを書き換えてみる ZテストとZ...
  3. Zバッファ値 目次 はじめに gpcnvaxis モード0の戻り値 問題点...
  4. 丸影 目次 はじめに 板モデル 半透明 レイ gppraytest...