2017/09/26(火) [n年前の日記]
#1 [pi3d][python][raspberrypi] pi3dでeggを使う際の注意点
pi3dで、複数のテクスチャ画像を使っているeggモデルデータを表示しようとすると、テクスチャが一枚分しか反映されなくて悩んでいたのだけど。
正常に描画される _pi3d_demos内の egg の中身を眺めているうちに、なんとなく原因が分かってきた。
ちゃんと表示されるeggデータは、どうもテクスチャ画像毎にポリゴン群をグループ化しているようで。例えば以下のような感じでデータが並んでる。
対して、blender + YABEE でエクスポートした、テクスチャがちゃんと反映されないeggは、テクスチャ毎にグループ分けなんかしてなくて。
Panda3D SDK の pview でプレビュー表示すると、後者のeggも描画されるので、おそらく Panda3D の eggフォーマットとしては後者もサポートされていてしかるべき、なのだろうと想像するのだけど。
ただ、pi3d の場合、OpenGL ES を利用するライブラリだから、テクスチャ画像毎に描画していかないと描画パフォーマンスが出ない等の理由で、あらかじめデータ側で、テクスチャ別の並びで整理整頓しておいてくれないと困る、てな事情でもあるのかもしれない。
でもまあ…。
ちなみに、blender からエクスポートした obj + mtl は、マテリアル別=テクスチャ別にポリゴン群がまとまって並んでいるので、pi3d が egg に望んでる仕様 ―― テクスチャ別にグループ分けして並べろ、的な仕様は、obj + mtl の場合既に満たされている可能性が高い。 *2
正常に描画される _pi3d_demos内の egg の中身を眺めているうちに、なんとなく原因が分かってきた。
ちゃんと表示されるeggデータは、どうもテクスチャ画像毎にポリゴン群をグループ化しているようで。例えば以下のような感じでデータが並んでる。
テクスチャAを使ってるグループ ポリゴン群データ グループ終わり テクスチャBを使ってるグループ ポリゴン群データ グループ終わり テクスチャCを使ってるグループ ポリゴン群データ グループ終わり
対して、blender + YABEE でエクスポートした、テクスチャがちゃんと反映されないeggは、テクスチャ毎にグループ分けなんかしてなくて。
グループ このポリゴンはテクスチャC このポリゴンはテクスチャB このポリゴンはテクスチャC このポリゴンはテクスチャA グループ終わり
Panda3D SDK の pview でプレビュー表示すると、後者のeggも描画されるので、おそらく Panda3D の eggフォーマットとしては後者もサポートされていてしかるべき、なのだろうと想像するのだけど。
ただ、pi3d の場合、OpenGL ES を利用するライブラリだから、テクスチャ画像毎に描画していかないと描画パフォーマンスが出ない等の理由で、あらかじめデータ側で、テクスチャ別の並びで整理整頓しておいてくれないと困る、てな事情でもあるのかもしれない。
でもまあ…。
- pi3d は、obj + mtl を読み込むことでも、3Dモデルデータの描画ができる。
- pi3d_demos の中にも、obj + mtl が結構入っている。eggしか使えないというわけではない。
- eggを使わないなら、Panda3D SDK のインストールも不要。
ちなみに、blender からエクスポートした obj + mtl は、マテリアル別=テクスチャ別にポリゴン群がまとまって並んでいるので、pi3d が egg に望んでる仕様 ―― テクスチャ別にグループ分けして並べろ、的な仕様は、obj + mtl の場合既に満たされている可能性が高い。 *2
[ ツッコむ ]
#2 [pi3d][python][raspberrypi] pi3dで3Dモデルデータを描画
とりあえず、pi3d で 3Dモデルデータを描画できた。ような気がする。
以下は、Raspberry Pi Zero W + pi3d 2.21 で動作確認した際の様子。デジカメで撮影したから画質が汚いけど、動いてることぐらいは分かるかなと。
結構滑らかに動いてる。OpenGL ESってスゴイ。もっとも、画面が出てくるまで随分時間がかかってるけど…。そのあたりは Raspberry Pi Zero W だから仕方ない、のかな。
以下は、Raspberry Pi Zero W + pi3d 2.21 で動作確認した際の様子。デジカメで撮影したから画質が汚いけど、動いてることぐらいは分かるかなと。
結構滑らかに動いてる。OpenGL ESってスゴイ。もっとも、画面が出てくるまで随分時間がかかってるけど…。そのあたりは Raspberry Pi Zero W だから仕方ない、のかな。
◎ ソース。 :
ソースは以下。
_draw_model.py
_モデルデータ(models.zip)
モデルデータは解凍して、ソースに対して models/*.obj となるように置いてもらえれば。自作データだからライセンスはCC0ってことで。
_draw_model.py
_モデルデータ(models.zip)
モデルデータは解凍して、ソースに対して models/*.obj となるように置いてもらえれば。自作データだからライセンスはCC0ってことで。
u""" pi3d draw model sample. モデルデータ(.obj + .mtl or .egg)を描画してみるサンプル。 ESCキーで終了する。 Windows10 x64 + Python 2.7.12 32bit + pi3d 2.21 """ from __future__ import absolute_import from __future__ import division from __future__ import print_function from __future__ import unicode_literals import pi3d # ウインドウ生成 display = pi3d.Display.create(frames_per_second=60) # ライトを設定. position, color, ambientを指定 light = pi3d.Light(lightpos=(10.0, -10.0, -5.0), lightcol=(1.0, 1.0, 1.0), lightamb=(0.3, 0.3, 0.3), is_point=False) # シェーダを生成 shader = pi3d.Shader("uv_light") # カメラ生成 camera = pi3d.Camera.instance() # モデルデータを読み込み # modelpath = "models/cube_quad_tex2.obj" # modelpath = "models/robo_01.obj" modelpath = "models/robo_02.obj" # modelpath = "models/cube_quad_tex2.egg" # modelpath = "models/robo_01.egg" # modelpath = "models/robo_02.egg" my_model = pi3d.Model(file_string=modelpath, name="my_model", rx=0, ry=0, rz=0, # rotate sx=1.0, sy=1.0, sz=1.0, # scale x=0.0, y=0.0, z=4.0 # position ) # モデルのシェーダを設定 my_model.set_shader(shader) # my_model.set_light(light) # キーボード取得用クラスを生成 keys = pi3d.Keyboard() # メインループ while display.loop_running(): camera.reset() # モデルを描画 my_model.draw() # モデルを回転 my_model.rotateIncX(0.25) my_model.rotateIncY(1.0) if keys.read() == 27: # ESCキーが押されたら終了 keys.close() display.destroy() break
◎ 少し解説。 :
モデルデータの読み込みは、以下のような感じで指定するらしい。
モデルデータを描画する際にシェーダが必要になるようなので、シェーダの生成と、モデルデータへの割り当てをする。
モデルデータには、カメラやライトも割り当てられるようだけど…。
ちなみに、lightpos がライトの位置 or 光線の向き。lightcol がライトの色。lightamb が環境光の色だか強さだか。is_point で、点光源か平行光源だかの指定ができるのだろうか。ホントかな。自信無し。 _pi3d Package - pi3d 2.21 documentation に説明があるので、英語が分かる人は読んでください…。
my_model = pi3d.Model(file_string="モデルデータへのパス", name="モデルのID(名前)", rx=0, ry=0, rz=0, # 回転角度 sx=1.0, sy=1.0, sz=1.0, # 拡大縮小率 x=0.0, y=0.0, z=4.0 # 位置 )name がよく分からないのだけど…適当な名前でいいのかな。おそらく name を使って他のモデルデータと区別したりするのだろうから、他と重ならない名前をつけとけばいいのではないかと。分からんけど。
モデルデータを描画する際にシェーダが必要になるようなので、シェーダの生成と、モデルデータへの割り当てをする。
shader = pi3d.Shader("uv_light") my_model.set_shader(shader)「uv_light」は、「テクスチャ(UV値)を使用 + 照明計算有り」てな処理をするシェーダを指定、ということじゃないかなと。
モデルデータには、カメラやライトも割り当てられるようだけど…。
light = pi3d.Light(lightpos=(10.0, -10.0, -5.0), lightcol=(1.0, 1.0, 1.0), lightamb=(0.3, 0.3, 0.3), is_point=False) # my_model.set_light(light)今回試した範囲では、反映のされ方がよく分からなかったのでコメントアウトしてある。
ちなみに、lightpos がライトの位置 or 光線の向き。lightcol がライトの色。lightamb が環境光の色だか強さだか。is_point で、点光源か平行光源だかの指定ができるのだろうか。ホントかな。自信無し。 _pi3d Package - pi3d 2.21 documentation に説明があるので、英語が分かる人は読んでください…。
[ ツッコむ ]
#3 [nitijyou] 日記をアップロード
気が付いたら、最後にアップロードしたのが2017/09/04だった…。ということでせっせとアップロード。
[ ツッコむ ]
以上、1 日分です。