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


HSPTV!掲示板


未解決 解決 停止 削除要請

2023
0916
鈍なくらhgimg4 で、3D空間の板ノードの、UVアニメーションを表現しました。14解決


鈍なくら

リンク

2023/9/16(Sat) 09:26:53|NO.100038

 こんにちは!
もっと良い方法が無いか、知恵をお借りしたく スレッドを立てました。

 ここで言う「UVアニメ」とは、ウディタでいう キャラチップ歩行アニメです。
1枚のテクスチャの UV座標を変えてくアニメ表現。

 3D空間の板オブジェクトでやります。
2D空間の gpspr スプライトなら、簡単ですが(-ω-;)
gpplate で UVアニメを書けませんでした。


 試作スクリプトを添付します。
「メッシュノードを作っては消し」まくり、力技で良くないです。

 前作『ジェイルアイランド』は hgimg3 でした。
hgimg3 では texload addplate event_uv で簡単でしたが、
hgimg4 では これらを使えないように見えます。
hgimg4 のマテリアル最大数は 128 と少ないので、うまく工夫したいのですが。


#include "hgimg4.as" #define BASETIME 30 //コマが変わる時間。 chdir dir_exe+"\\sample\\hgimg4" //サンプル素材のあるディレクトリ。 //カメラを設置 setpos GPOBJ_CAMERA, 8,8,10 //カメラ位置。 gplookat GPOBJ_CAMERA, 0,0,0 //メッシュノードのある座標を見る。 //repeat 前の準備 gptexmat id_mat, "res/ball64.png" //テクスチャマテリアルを生成。 id_node = -1 //メッシュノードのオブジェクトID。生成すると 0 に。 koma = 0 //uv アニメのコマ番号 = ボールに書かれた番号 time = BASETIME //経過時間。 repeat if(time >= BASETIME){//コマを変える。 time = 0 //前回のコマのメッシュノードを削除。 if(id_node >= 0){ delobj id_node id_node = -1 } //今回のコマのメッシュノードを作成。 x1 = 64 * koma x2 = 64 * (koma + 1) Make_meshNode 512, x1, 0, x2, 64 //次回のコマへ。 koma ++ if(koma >= 3){ koma = 0 };コマ 0~2 だけでアニメ。 } time ++//時間経過 //画面を描画。 redraw 0 gpdraw redraw 1 await 1000 / 60 loop //■■■■■■■■■■■■■■■■■■■■■■ //メッシュノードを作成する命令。 #deffunc Make_meshNode double _size, double _tl_x, double _tl_y, double _br_x, double _br_y /// _size :テクスチャ画像の縦横(pixel) /// _tl :UV 左上座標 x,y(pixel) /// _br :UV 右下座標 x,y(pixel) //pixel を「テクスチャ縦横の割合 0.0~1.0」に変換。 _uv_tl_x = _tl_x / _size _uv_tl_y = 1.0 - _tl_y / _size _uv_br_x = _br_x / _size _uv_br_y = 1.0 - _br_y / _size //カスタム3Dメッシュの登録情報を初期化。 gpmeshclear //頂点を登録。 a = 1 gpmeshadd p1, -a, -a, 0, 0, 0, 1, _uv_tl_x, _uv_br_y;頂点 gpmeshadd p2, a, -a, 0, 0, 0, 1, _uv_br_x, _uv_br_y gpmeshadd p3, -a, a, 0, 0, 0, 1, _uv_tl_x, _uv_tl_y gpmeshadd p4, a, a, 0, 0, 0, 1, _uv_br_x, _uv_tl_y //カスタム3Dメッシュにポリゴン情報を登録。 gpmeshpolygon p1,p2,p3,p4 //メッシュノード オブジェクトを生成。 id_node = 0 gpmesh id_node, $FFFFFF, id_mat setpos id_node, 0, 0, 0 return



この記事に返信する


zrs90(5さい)

リンク

2023/9/16(Sat) 11:57:10|NO.100039

勘違いなら申し訳ないですが...

>hgimg4 のマテリアル最大数は 128
この件、増やせる様です

http://hsp.tv/play/pforum.php?mode=pastwch&num=97105#97187

〜#97188(※おにたま さんからの回答)

私の手持ちのバージョンが
3.7β5なので、ズレがあるかも?

hgimg4プログラミングガイド内を
「マテリアル最大数」で
HDLのメニューバーから、表示→ページ内検索
して見て下さい
44.登録の限界数 にこの件が載ってます



鈍なくら

リンク

2023/9/16(Sat) 13:41:47|NO.100040

 zrs90(5さい)さま、コメント本当に有難うございます! (*-ω人)
「マテリアル最大数を増やす」方向で考えると、
試作コードの「//カメラを設置」に 下記を追記すると、600枚に増やせますネ!


#define MAT_MAX 600 setreq SYSREQ_MAXMATERIAL, MAT_MAX dim mat_id, MAT_MAX for i, 0, MAT_MAX gptexmat mat_id(i), "res/ball64.png" next gpreset


 ただ、今回のトピックは「UV操作」としたいです! (*´ω`)
マテリアル最大数を増やしても、板オブジェクトを削除&再生成するに変わらず、
強引な試作スクリプトの問題が解決しません。

 また、HGIMG3 では「テクスチャ最大数を増やせない」バグあったので、
念のため 増やさないよう開発してます (*'▽')


 「マテリアル 128枚以上は多すぎる」と 私は愚考しております。

 Spine など 2Dモーフィングソフトでは、パーツをすべて1枚のテクスチャに圧縮します。
https://www.google.com/search?client=firefox-b-d&sca_esv=565842615&sxsrf=AM9HkKmjo5siR5e-JwqG3YZcTodpsxZ-aQ:1694837469315&q=Spine+%E3%83%86%E3%82%AF%E3%82%B9%E3%83%81%E3%83%A3&tbm=isch&source=lnms&sa=X&ved=2ahUKEwjs0r3Koa6BAxVU_mEKHZfuDVwQ0pQJegQIDBAB&biw=1907&bih=1015&dpr=1
これはなぜかとゆ〜と、UV操作しないと マテリアル数が数十倍になるからです。


 例えば ウディタのキャラチップ歩行アニメを考えてみます。
1つの方向 3枚、8方向 24枚。マテリアル最大数 600枚だと、25人しか登場しません(-_-;)
RPG なら最初の街で終わっちゃいます。

 これを UV操作すると、25枚で済みます。
拙作の場合、歩行アニメだけでなく、走りやダウンなどもあり、1キャラ最低 36枚は必要です。
HGIMG4 を使う理由は、ブラウザゲームだからです。
http://n-nakura.sakura.ne.jp/JAil_islaND3/


 あとづけ説明ばかりして、本当に申し訳ないです m(__)m
こんな感じで「HGIMG4 でオブジェクトを削除せず UV操作するには?」を考えたいです(*´ω`)



鈍なくら

リンク

2023/9/16(Sat) 14:12:10|NO.100041

 あ。
gptexmat 	id_mat, "res/ball64.png"

をコメントアウトすると 表示されない。  最大数 600に増えないのかな、もしかして。  まぁこんな風に、HGIMG4 の開発者さまに負担かかってしまうので、 マテリアル最大数は増やさないよ〜にしたいのです(*´ω`)



鈍なくら

リンク

2023/9/16(Sat) 14:31:19|NO.100042

ゴメンなさい、勘違い。最大数は 600に増える。
ちゃんと 600枚のマテリアルを作成してました。



法貴藤五郎

リンク

2023/9/16(Sat) 15:56:16|NO.100043

UV操作じゃなくて申し訳ないですが3.7b6ならドットをつぶさずテクスチャ―の差し替えが可能です。
画像は用意してください。
…ただこれ今チェックしてたけどメモリリークしてるかもしれません。


#include "hgimg4.as"
#include "mod_gputil.as"

screen 0, 1280, 720, 0
gpreset

setcls CLSMODE_SOLID, 0 ; 画面クリア設定
setpos GPOBJ_CAMERA, 0,0,5 ; カメラ位置を設定

// テクスチャマテリアル作成
gptexmat fmat, "res/grp/z00.png", GPOBJ_MATOPT_UVOFFSET|GPOBJ_MATOPT_NOCULL |GPOBJ_MATOPT_NOLIGHT
gpmatprmf fmat, "filter", "nearest"

gpplate mdl, 1, 1, -1, fmat
gpnodeinfo mat, mdl, GPNODEINFO_MATERIAL

repeat
stick key,15
if key&128 : end

m_fTime += 1
if (m_fTime >= 60) {
m_fTime -= 60;
m_nAni++
m_nAni &= 1;
if (m_nAni == 0) {
gpmatprmt mat, , "res/grp/z00.png", GPOBJ_MATOPT_NOMIPMAP
gpmatprmf mat, "filter", "nearest"
}
else {
gpmatprmt mat, , "res/grp/z01.png", GPOBJ_MATOPT_NOMIPMAP
gpmatprmf mat, "filter", "nearest"
}
}

addang mdl, 0.0, 0.02, 0.0;

; カーソルキーでカメラ位置を動かす
if key&1 : addpos GPOBJ_CAMERA, -0.2
if key&4 : addpos GPOBJ_CAMERA, 0.2
if key&8 : addpos GPOBJ_CAMERA, 0, 0, 0.2
if key&2 : addpos GPOBJ_CAMERA, 0, 0, -0.2

redraw 0 ; 描画開始
gpdraw ; シーンの描画
redraw 1 ; 描画終了
await 1000/60 ; 待ち時間

loop




鈍なくら

リンク

2023/9/16(Sat) 16:55:35|NO.100044

 法貴藤五郎さま、コメント本当に有難うございます! (*-ω人)
一時的に 3.6 から 3.7b6 へアプデし、動作を確認できました!

 gpmatprmt 初めて知りました (。゚ω゚)
この方法なら「消すたびにオブジェクトID を取得し直す」なんて不要ですね!
書いて頂いたコードのが 私のよりずっと良いと思います。

 gpmatprm の命令が増えてるみたいで、勉強してみます。

 「メモリリークしてる可能性」、
私には repeat~loop 内の どこも問題ないように見え、わかりませんでした。
addang なのかな?


 私はまた試作して、gpscrmat と celdiv をうまく使えないのが悔しいです  (つ∀≦。)・゚。


【失敗コード】 #include "hgimg4.as" #define BASETIME 30 //コマが変わる時間。 chdir dir_exe+"\\sample\\hgimg4" //サンプル素材のあるディレクトリ。 gpreset //カメラを設置 setpos GPOBJ_CAMERA, 8,8,10 //カメラ位置。 gplookat GPOBJ_CAMERA, 0,3,0 //メッシュノードのある座標を見る。 id_screen = 1 /* buffer id_screen, 512, 512, screen_offscreen gpscrmat id_tex, id_screen gpmatprmt id_tex, "u_diffuseTexture", "res/ball64.png" celdiv id_screen, 64, 64, 32,32 */ celload "res/ball64.png", -1 id_screen = stat celdiv id_screen, 64, 64, 32, 32 gpscrmat id_mat, id_screen gpplate id_plate, 1.8, 1.8, -1, id_mat ; 板ノードを追加 setpos id_plate, -1, 2.1, 0 newevent ev event_uv ev, 0 event_wait ev, BASETIME event_uv ev, 1 event_wait ev, BASETIME event_uv ev, 2 event_wait ev, BASETIME event_jump ev, 0 setevent id_plate, ev ; 床ノードを追加 gpfloor id_floor, 40,40, $008080 gppbind id_floor, 0 repeat //画面を描画。 redraw 0 gpdraw redraw 1 await 1000 / 60 loop



砂時 計

リンク

2023/9/16(Sat) 17:47:40|NO.100045

シェーダーの uniform を使う方法で実装してみました。

以下の内容で sample/hgimg4/res/shaders/_tiletex.vert ファイルとして保存してください。

attribute vec4 a_position; attribute vec2 a_texCoord; uniform mat4 u_worldViewProjectionMatrix; uniform vec4 u_info; varying vec2 v_texCoord; void main() { vec4 position = a_position; gl_Position = u_worldViewProjectionMatrix * position; v_texCoord = a_texCoord * u_info.zw + u_info.xy; }

以下の内容で sample/hgimg4/res/shaders/_tiletex.frag ファイルとして保存してください。

#if defined(OPENGL_ES) || defined(GL_ES) #ifdef GL_FRAGMENT_PRECISION_HIGH precision highp float; #else precision mediump float; #endif #endif uniform sampler2D u_tileTex; varying vec2 v_texCoord; void main() { gl_FragColor = texture2D(u_tileTex, v_texCoord.xy); }

以下の内容で sample/hgimg4/tilebyuniform.hsp ファイルとして保存して実行してください。

#include "hgimg4.as" texfile = dirinfo(5) + "tamadot.png" // タイルテクスチャ sdir = "res/shaders" vsh = sdir + "/_tiletex.vert" fsh = sdir + "/_tiletex.frag" gpusermat mtlid, vsh, fsh gpmatprmt mtlid, "u_tileTex", texfile, GPOBJ_MATOPT_NOMIPMAP gpplate id1, 2, 2, -1, mtlid setpos id1, 0, 0, 80 gpplate id2, 2, 2, -1, mtlid setpos id2, 3, 0, 90 step = 0.02 dirindex = 0 repeat getreq timer, SYSREQ_TIMER topo = timer \ 2000 stick key,15 if (key & 15) == 0 { walking = 0 } else { walking = 1 if key & 1 { // 左 dirindex = 1 addpos id1, -step, 0,0 } if key & 2 { // 上 dirindex = 2 addpos id1, 0, step, 0 } if key & 4 { // 右 dirindex = 3 addpos id1, step, 0, 0 } if key & 8 { // 下 dirindex = 0 addpos id1, 0, -step, 0 } } redraw 0 // 珠音1 incx = walking * 4 + topo / (2000 / 4) incy = dirindex inid = id1 gosub *update // 珠音2 incx = topo / (2000 / 4) incy = 5 inid = id2 gosub *update gpdraw redraw 1 await 1000/60 loop *update wimg = 512 // tamadot.png 全体の幅 himg = 512 w2d = wimg / 8 // tamadot.png の1セルの幅 h2d = himg / 8 x2d = incx * w2d y2d = incy * h2d // 上から下座標系での基点Y dw = double(wimg) dh = double(himg) x = double(x2d) / dw y = 1.0 - double(y2d + h2d) / dh z = double(w2d) / dw w = double(h2d) / dh gpmatprm4 inid, "u_info", x, y, z, w return

ご参考まで。
# うーむ、0.5 テクセルずらしてもどっちかからゴミ出るなぁ。どなたか助けてw



鈍なくら

リンク

2023/9/16(Sat) 19:08:52|NO.100046

 砂時 計さま、コメント本当に有難うございます! (*-ω人)
カメラオブジェクトを置き、正常な動作を確認しました。

こここ こんなこと出来るんですね……すごすぎる! 神か
ついでに ↓ も大丈夫でした。

setobjmode id1, OBJ_XFRONT, 0 ;オブジェクトのモード設定

 たしかに、アニメの端に ゴミが。
もとの tamadot.png が セルの端ぎりぎりまでドット打ってあるので、
端をα値0のピクセルで囲めば、正常になるかと思います。


 ひとまず、スレッドに解決チェックしました〜。
あの、このシェーダーを 拙作に使ってもよろしいでしょうか…?
宜しければ クレジットにお名前や、URL などを載せたいのですが。



砂時 計

リンク

2023/9/16(Sat) 19:57:14|NO.100047

はい、使っていただいて構いません。
※今回のシェーダーは uniform を参照する基本的なコードですので、まさにサンプルですね。
なお砂時としてのホームページはありません。



buhio

リンク

2023/9/16(Sat) 23:49:27|NO.100048

あ、、、、解決しちゃいましたね。。。
ちょっと自分用に再度メモ書きとして、UPしておこう。。。
質問内容と違ったらごめんね。


;HSP ver3.7b6で検証 #include "hgimg4.as" chdir dir_exe+"\\sample\\hgimg4" gpreset setcls CLSMODE_SOLID, $000000 ; 画面クリア設定 ;===カスタムマテリアルの描画元部品=== buffer 2,512,512,screen_offscreen ;バッファー2を作成 celload "res/ball64.png",2  ;64ボール画像読込 celdiv 2,64,64,0,0 ;====カスタムマテリアル============== buffer 3,64,64,screen_offscreen ;バッファー3を作成 gpscrmat id_texmat, 3 ;テクスチャマテリアル作成 ;==================================== gpbox id_model, 10,, id_texmat ;描画先GPBOX+カスタムマテリアルを設定 timer=0.0f repeat redraw 0 ; 描画開始 addang id_model,0,0.01,0 ;GPBOXを回転 gpdraw ;シーンの描画 gosub *draw ;カスタムマテリアルの描画 redraw 1 ; 描画終了 await 1000/60 ; 待ち時間 loop ;======================================================= *draw ;カスタムマテリアルの描画 gsel 3 redraw 0 ;テスト1 色が変わる四角形 color timer,timer/2,255-timer;背景の四角 boxf 0,0 ;テスト2 単純な円 color 0,255,0 circle 0,0,64,64,0 ;テスト3 celput timer+=0.1f gmode 2 pos 0,0 celput 2,timer\64 ;テスト4 文字列の描画 color 255,0,0;文字 pos 0,0 mes "test"+timer redraw 1 gsel 0 return ;=======================================================

ちょっと改造



buhio

リンク

2023/9/17(Sun) 02:40:46|NO.100049

透過pngを適用できないのか、なんか気になって眠れないので、試してみました。
標準のシェーダーを使用。公式のサンプルあり(gptexmat)
もう寝る。。。


;HSP ver3.7b6で検証 #include "hgimg4.as" chdir dir_exe+"\\sample\\hgimg4" gpreset setcls CLSMODE_SOLID, $000000 ; 画面クリア設定 ;====テクスチャマテリアル============== gptexmat id_texmat, "res/ball64.png",GPOBJ_MATOPT_UVOFFSET|GPOBJ_MATOPT_UVREPEAT ; テクスチャマテリアル作成 ;==================================== gpplate id_model, 10,10,-1, id_texmat ;描画先モデル+テクスチャマテリアルを設定 setpos id_model,0,0,60 gpbox id_model2,100 ;透過確認用ダミーモデル setpos id_model2,0,0,-200 offsetx = 0.0f ;UVオフセット初期化 offsety = 0.0f timer = 0.0f ;タイマー初期化 repeat redraw 0     ; 描画開始 offsetx = 1f/8*int(timer\8)      ;UVの考え方がよくわからん offsety = -1f/8*int(timer/8)-1f/8 gpmatprm2 id_model, "u_textureOffset", offsetx , offsety ;UVオフセットのシェーダー設定 gpmatprm2 id_model, "u_textureRepeat", 1.0f/8.0f , 1.0f/8.0f ;UVリピートのシェーダー設定 addang id_model ,0,0.05,0 ;プレートモデルを回転 addang id_model2,0,0.01,0 ;ボックスモデルを回転 gpdraw ;シーンの描画 timer+=0.1f ;タイマー加算 redraw 1 ; 描画終了 await 1000/60 ; 待ち時間 loop

おやすみzzz



usagi

リンク

2023/9/17(Sun) 17:18:23|NO.100050

こんにちわ。もう解決してますが、buhioさんのアイデアを参考にして
こういうのもシンプルで良いかもしれませんね。
(セガサターンのRPGとか思い出します)

;37beta4以降限定 #include "hgimg4.as" chdir dir_exe+"\\sample\\hgimg4" : gpreset : setcls CLSMODE_SOLID, $ff ; ★テクスチャとモデル生成 gptexmat id_tex, dir_tv+"tamadot.png", GPOBJ_MATOPT_UVOFFSET|GPOBJ_MATOPT_UVREPEAT gpplate id_model, 4, 4,, id_tex : setpos id_model, 0,2,0 ; ★オマケこういうのは見栄えを考えビルボードにした方が良いかも setobjmode id_model, OBJ_XFRONT setobjmode id_model, OBJ_LATE ; ★ここがceldiv的なイメージ TEX_SIZE = 512f ; 画像のサイズ CH_SIZE = 64f ; キャラクタのサイズ REP_SIZE = CH_SIZE / TEX_SIZE ; テクスチャの位置を指定するのに使う gpmatprm2 id_model, "u_textureRepeat", REP_SIZE , REP_SIZE ; アニメーション用のパターン(仮) ani_time = 4,5,6,7 ani_dir = 6,5,4,7 ; 背景(仮) gpfloor id_floor, 32, 32, $FF00 gpbox id_box, 4, $FFFF : setpos id_box, 8,2 gpclone id_box2, id_box : setpos id_box2, -8,2 gpclone id_model2, id_model ; カメラ(仮) setpos GPOBJ_CAMERA, 0,16,32 gplookat GPOBJ_CAMERA, 0,1,0 *MAIN stick pad, 15 if pad&1 : ch_dir = 0 : addpos id_model, -0.2 if pad&2 : ch_dir = 1 : addpos id_model,,, -0.2 if pad&4 : ch_dir = 2 : addpos id_model, 0.2 if pad&8 : ch_dir = 3 : addpos id_model,,, 0.2 if tick\10=0 : ch_time++ : ch_time\=4 ; ★テクスチャ座標は左下から右上へ指定 offset = REP_SIZE*ani_time(ch_time), REP_SIZE*ani_dir(ch_dir) gpmatprm2 id_model, "u_textureOffset", offset.0, offset.1 redraw 0 : gpdraw : redraw 1 : await 16 : tick++ goto *MAIN



usagi

リンク

2023/9/17(Sun) 17:38:46|NO.100051

ついでで、bata6 が使えるのであれば、オマケの下に

gpmatprmf id_model,"filter","nearest"
入れておくと、キャラが重なった時の、α抜きが綺麗いくと思います。
※ただし、補間が適応されなくなるのでドットは目立ちます。
 が、コレ系のアプローチはボケないで個人的には好きです。



鈍なくら

リンク

2023/9/18(Mon) 11:34:27|NO.100053

 わ、すごい! このスレは、HGIMG4 で
「オクトパストラベラー」「ゼノギアス」みたいな
「2Dドットキャラを3D空間で動かす」とき ご活用ください!


>>NO.100048
 buhio さま、コメ本当に有難うです! (*-ω人)

 透過の問題あっても、celdiv gpscrmat celput で
3Dオブジェクトにセル番号で描けるのは 目から鱗!
バッファの理解が深まるコード。


>>NO.100049
 シンプル、すごく良い! gpmatprm2 は ver.3.7 からか。
gpmatprm の引数「パラメーター名」 よく分からなかったのですが、
gptexmat の「マテリアルオプション値」と連動してるんですね。

★メモ: GPOBJ_MATOPT_UVOFFSET で UVオフセット値(u_textureOffset)を設定可能に。


>>NO.100050
 usagi さま、ご助言 本当に有難うです! (*-ω人)
メガドライブなゲームを作るところでした(それもいい)
 
 わぁ、完璧! NO.100051 も すごい良い効果ですね(*´ω`)
シンプルなコード、勉強になります。

 UV操作とは違う話題ですが、HGIMG4 ならゲーム「RimWorld」みたく
「草や炎のビルボードをゆらゆら揺らす」のも、
ポリゴンの頂点を動かして できそーな気します(知らんけど)



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