Prototyping levels with CSG

CSGは Constructive Solid Geometry (空間領域構成法) の略で、基本的な形状あるいはカスタムのメッシュを組み合わせることで、より複雑な形状を作成するツールです。3Dモデリングのソフトウェアでは、CSGは『ブーリアン演算』という名でも知られています。

レベルのプロトタイプ作成は、GodotでCSGを使う主な理由の一つです。このテクニックにより、ユーザーはプリミティブを組み合わせることで、よく使う形状の簡易版を作れます。インテリア環境も反転したプリミティブで作成できます。

注釈

The CSG nodes in Godot are mainly intended for prototyping. There is no built-in support for UV mapping or editing 3D polygons (though extruded 2D polygons can be used with the CSGPolygon node).

If you're looking for an easy to use level design tool for a project, you may want to use Qodot instead. It lets you design levels using TrenchBroom and import them in Godot.

../../_images/csg.gif

CSGノードの入門

Godotの他の機能と同様に、CSGもノードとしてサポートされています。これらがCSGノードです:

../../_images/csg_nodes.png ../../_images/csg_mesh.png

CSGツール機能

すべてのCSGノードは3種類のブーリアン演算に対応しています:

  • Union (和集合): プリミティブのジオメトリを結合させて、共通部分のジオメトリは除去されます。

  • Intersection (共通部分): ジオメトリの共通部分のみを残し、他は除去されます。

  • Subtraction (差集合): 第一の形状を、第二の形状で差し引いて、形状に穴を開けます。

../../_images/csg_operation_menu.png ../../_images/csg_operation.png

CSGPolygon

The CSGPolygon node extrude along a Polygon drawn in 2D (in X, Y coordinates) in the following ways:

  • Depth (深さ): 指定された量で後ろに押し出します。

  • Spin (回転): 原点を中心に、回転しながら押し出します。

  • Path (パス): Pathノードに沿って押し出します。ロフティングともよく呼ばれる操作です。

../../_images/csg_poly_mode.png ../../_images/csg_poly.png

注釈

Path モードを動かすには、まずPathノードを用意しなければなりません。このPathノードにてパスを描くと、CSGPolygonのポリゴンはそのパスに沿って押し出されます。

カスタム メッシュ

CSGMeshなら、どんなメッシュでも使用できます。他のソフトウェアでモデリングしてからGodotにインポートしたメッシュでも可能です。複数のマテリアルにも対応しています。ジオメトリにはいくつかの制限があります:

  • 閉じていること、

  • 自己交差していないこと、

  • 内部に面がないこと、

  • すべてのエッジは2つの面のみに接していること。

../../_images/csg_custom_mesh.png

CSGCombiner

CSGCombiner ノードは、整理のための空のシェイプです。子ノードを一つにまとめます。

処理の順番

すべてのCSGノードは、まずその子ノードから処理を始め、その和、共通部分、差の演算をツリー順に行ってから、自身に適用してそれを繰り返します。

注釈

複雑なメッシュは処理に時間がかかるので、性能を上げるためには、CSGジオメトリを比較的シンプルなままに保ってください。(テーブルや部屋の物体など) 複数の物体を一緒にする場合は、それぞれ別のCSGツリーに分けましょう。ひとつのツリーに多くのオブジェクトを入れすぎると、やがて性能に影響が出始めます。バイナリ演算は本当に必要な時にだけ使用するようにしてください。

レベルのプロトタイプ作成

CSGツールの練習に、部屋のプロトタイプを作ってみましょう。

ちなみに

CSGシェイプを組み合わせるときは、平行投影のほうが見えやすくなります。

これから作るレベルには次のような物体があります:

  • 部屋、

  • ベッド、

  • ランプ、

  • 机、

  • 本棚。

Spatial ノードをルートにしてシーンを作成します。

ちなみに

環境のデフォルトの照明設定では、角度によってはシェーディングがきれいに表示されません。3Dビューポート メニューにて表示モードをオーバードロー表示にするか、あるいは DirectionalLight をひとつ追加すれば、はっきりと見えるようになります。

../../_images/csg_overdraw.png

CSGBoxをひとつ作成し、roomという名前を付けて、Invert Facesを有効にしてから、部屋のサイズを変更してください。

../../_images/csg_room.png ../../_images/csg_room_invert.png

次に、CSGCombiner を作成してdeskという名前を付けます。

デスクにはひとつの平面と4本の脚があります:

  • 平面として、子ノードのCSGBoxをひとつ作成し、Union (和集合)モードにしてから大きさを変更します。

  • 脚には、子ノードのCSGBoxを4個作成し、Unionモードにしてから大きさを調節します。

それらの位置を調節してデスクの形にしましょう。

../../_images/csg_desk.png

注釈

CSGCombiner の中にあるCSGノードは、その combiner(連合) の中だけで演算処理を行います。そのため、CSGノードの整理には CSGCombiner が使われます。

CSGCombiner を作り、bedと名付けます。

ベッドは3つのパーツからなります: ベッド本体、マットレス、そして枕です。CSGBox を作成して、サイズ調整してベッド本体にします。さらに CSGBox をもうひとつ作って、大きさ変更をしてマットレスにします。

../../_images/csg_bed_mat.png

bedの子として、pillowという名前の CSGCombiner を作ります。シーンツリーはこのようになるでしょう:

../../_images/csg_bed_tree.png

それから3つの CSGSphere ノードを Union (和) モードにして組み合わせ、枕にします。それぞれの球体をY軸でサイズ変更し、Smooth Faces を有効にします。

../../_images/csg_pillow_smooth.png

pillowノードを選択して、モードをSubtraction (差)に切り替えます。すると組み合わせた球体により、マットレスに穴が開きます。

../../_images/csg_pillow_hole.png

pillowノードの親を、ルートSpatialに変更してみましょう。そうすれば穴は消えます。

注釈

これはCSGの処理順による影響を示すためのものです。ここでのルートノードは CSGノードではないため、CSGCombiner ノードの処理は最後になります。これが CSGCombiner を使ったCSGシーン整理の一例です。

結果を確かめてから、親の変更とモード変更を取り消すと、ベッドはこのようになっているはずです:

../../_images/csg_bed.png

CSGCombiner を作成してlampと名付けます。

ランプはスタンド、支柱、そしてランプシェードの、3つのパーツからなります。CSGCylinder を作成し、Cone オプションを有効にしてスタンドにします。それから、もうひとつ CSGCylinder を作って、大きさを調整して支柱にします。

../../_images/csg_lamp_pole_stand.png

ランプシェードには CSGPolygon を使います。CSGPolygon を Spin モードにし、ビューを前面図 (テンキーの1) にしてから台形を描きましょう。この形状は原点を中心に、回転しながら押し出されてランプシェードを形作ります。

../../_images/csg_lamp_spin.png ../../_images/csg_lamp_polygon.png ../../_images/csg_lamp_extrude.png

3つのパーツの位置を調整して、ランプに見えるようにします。

../../_images/csg_lamp.png

CSGCombiner を作り、bookshelfと名付けます。

本棚には3つの CSGBox を使います。CSGBox をひとつ作って、サイズを調節してください。これが本棚のサイズになります。

../../_images/csg_shelf_big.png

この CSGBox を複製して、すべての軸で縮小させてから、モードを Subtraction (差) に変更します。

../../_images/csg_shelf_subtract.png ../../_images/csg_shelf_subtract_menu.png

本棚はもうすぐ完成です。CSGBox をもうひとつ作成して、棚を二段に分けます。

../../_images/csg_shelf.png

部屋の中に家具を自由に配置すれば、シーンはこういう風になるはずです。

../../_images/csg_room_result.png

これで部屋のレベルのプロトタイプを、Godot の CSG ツールを使って作ることができました。迷路や街など、あらゆる種類のレベルをデザインするのに CSG ツールは使えます。ゲームをデザインするときは、その限界まで探ってみてください。

Using prototype textures

Godot の 空間素材triplanar mapping をサポートしています。Godot はまだ CSG ノード上の UV マップの編集をサポートしていないので、これは CSG を使うときに便利です。トリプラナーマッピングは比較的低速なので、地形のような有機的なサーフェスには通常は不向きです。しかし、プロトタイピングの際には、CSGベースのレベルにテクスチャを素早く適用するために使用できます。

注釈

If you need some textures for prototyping, Kenney made a set of CC0-licensed prototype textures.

There are two ways to apply a material to a CSG node:

  • Applying it to a CSGCombiner node as a material override (Geometry > Material Override in the Inspector). This will affect its children automatically, but will make it impossible to change the material in individual children.

  • Applying a material to individual nodes (Material in the Inspector). This way, each CSG node can have its own appearance. Subtractive CSG nodes will apply their material to the nodes they're "digging" into.

CSGノードにトリプラナーマッピングを適用するには、CSGノードを選択してインスペクタに移動し、 Material Override (個々のCSGノードの場合は Material) の隣にある [empty] テキストをクリックします。 New SpatialMaterial を選択します。新しく作成されたマテリアルのアイコンをクリックして編集します。 Albedo セクションを展開し、 Texture プロパティにテクスチャをロードします。次に、 Uv1 セクションを展開し、 Triplanar にチェックを入れます。上の ScaleOffset プロパティを使用して、各軸のテクスチャオフセットとスケールを変更することができます。 Scale プロパティの値を高くすると、テクスチャがより頻繁に繰り返されるようになります。

ちなみに

You can copy a SpatialMaterial to reuse it across CSG nodes. To do so, click the dropdown arrow next to a material property in the Inspector and choose Copy. To paste it, select the node you'd like to apply the material onto, click the dropdown arrow next to its material property then choose Paste.