mieki256's diary



2025/01/08(水) [n年前の日記]

#1 [godot] 動的にポリゴンモデルを生成して描画したい

_昨日 に続き、Windows10 x64 22H2 + Godot Engine 4.3 64bit でゴルフゲームっぽいものが作れないものかなと試してる。

今現在、ボールを打った直後に、Sprite3D でボールの軌跡を描画してる。ボールの座標を毎フレーム、配列に記録しておいて、必要になったらその配列内の座標で Sprite3D を描画する。




一応、軌跡らしきものは描画できているものの、なんだか見た目がダサい…。この軌跡を線のように見せられないものかなと…。

そんなわけで、Godot Engine上で3D空間に線を描画する方法を調べていた。

まずは以下が参考になった。

_[Godot Engine] 3D空間にラインを引く方法

ImmediateGeometry とやらが使えるらしい。が、これは Godot 3.x の頃の話で、Godot 4.x では ImmediateMesh にリネームされたらしい。

ImmediateMeshについて :

ImmediateMesh を使うと、動的にポリゴンモデルを作成して描画することができる。使い方は OpenGL 1.x の glBegin - glEnd に似ている。begin と end の間でプリミティブの座標群を指定すると描画される感じ。

_Using ImmediateMesh - Godot Engine (stable) documentation in English
_ImmediateMesh - Godot Engine (stable) documentation in English

ノードとして ImmediateMesh があるのかなと思ったけれど、そうではないらしい。MeshInstance3D ノードを用意して、その MeshInstance3D の Mesh に ImmediateMesh を追加する。

とりあえずサンプルを書いてみた。

ノード構成は以下。

node_list_ss01.png

Node3D
├─ Camera3D           ← カメラ。これを忘れると画面に何も描画されない
├─ DirectionalLight3D ← 平行光源
├─ MeshInstance3D     ← 床box
├─ MeshInstance3D_2   ← ここに ImmediateMesh を追加する
└─ MeshInstance3D_3   ← 球

スクリプトソースは以下。

_mesh_instance_3d_2.gd
extends MeshInstance3D

var mat: StandardMaterial3D
var ang: float = 0.0

# Called when the node enters the scene tree for the first time.
func _ready():
    mat = StandardMaterial3D.new()
    mat.albedo_color = Color(0, 1, 0, 0.5)
    mat.cull_mode = BaseMaterial3D.CULL_DISABLED
    mat.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
    mat.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
        
    mesh = ImmediateMesh.new()


func _process(delta):
    var x0: float = 0.0
    var y0: float
    var z0: float
    var h: float = 5.0

    mesh.clear_surfaces()
    mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES, mat)
    mesh.surface_set_color(Color.WHITE)
    
    y0 = h * sin(deg_to_rad(ang))
    z0 = 10.0
    for i in range(1, 20, 1):
        var y1 = h * sin(deg_to_rad(ang + 10 * i))
        var z1 = z0 - 1.5
        mesh.surface_add_vertex(Vector3(x0, y1, z1))
        mesh.surface_add_vertex(Vector3(x0 + 1, y0, z0))
        mesh.surface_add_vertex(Vector3(x0 - 1, y0, z0))
        y0 = y1
        z0 = z1
    
    mesh.surface_end()
    
    ang += 120.0 * delta
    if ang >= 360.0:
        ang -= 360.0


実行するとこんな感じの画面になる。緑色で描画されてる三角ポリゴン群が、ImmediateMesh で描画している部分。Sin値を使って座標群を毎フレーム変化させている。




ここまでできれば、後は形状を工夫することでボールの軌跡っぽいものも描画できそう。

少し解説 :

マテリアルの指定は、StandardMaterial3D を使った。StandardMaterial3D.new() で確保して、色々指定していく。
  • albedo_color で基本色を指定できる。Color(R, G, B, A) で指定。RGBA は 0.0 - 1.0 を与える。
  • cull_mode で片面を描画するか、両面を描画するかを変更できる。BaseMaterial3D.CULL_DISABLED を指定すると両面を描画。
  • transparency で、半透明描画を指定できる。BaseMaterial3D.TRANSPARENCY_ALPHA でアルファ値が反映される…のだろうか?
  • shading_mode で、陰影の有無を指定できる。BaseMaterial3D.SHADING_MODE_UNSHADED で陰影無し。


MeshInstance3D の mesh に、ImmediateMesh.new() で確保した ImmediateMesh を指定する。

  • mesh.clear_surfaces() ... 今までの描画内容をクリア
  • mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLES, mat) ... 描画内容の指定を開始。PRIMITIVE_TRIANGLES は三角形ポリゴンを指定。mat はマテリアル。マテリアルの指定は省略できる。
  • mesh.surface_set_color(Color.WHITE) ... 色を指定。ただ、今回はマテリアル側で色を指定しちゃってるので、この指定は無視された。
  • mesh.surface_add_vertex(Vector3(x0, y1, z1)) ... 頂点座標を1つ指定。
  • mesh.surface_end() ... 描画内容の指定を終了。

以上です。

過去ログ表示

Prev - 2025/01 - Next
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project