3Dテキスト
はじめに
プロジェクトでは HUD だけでなく、3Dシーンの一部としてテキストを表示することがあります。Godot ではこれを実現するために Label3D ノードと、 MeshInstance3D ノードに TextMesh リソース を使うという2つの方法を提供しています。
さらに Godot ではカメラ上の3Dポイントの位置にコントロールノードを配置できます。これは Label3D と TextMesh の柔軟性が十分でない場合に、「真の」3Dテキストの代替として使用できます。
参考
3D Labels and Texts は、3Dテキストの動作を実際に確認できるデモプロジェクトです。
このページでは、3D環境内で GUI シーンを表示する方法については解説しません。それを実現する方法については GUI in 3D デモプロジェクトを参照してください。
Label3D
Label3D は Label ノードのように動作しますが、3D空間で動作するノードです。Label ノードとは異なり、この Label3D ノードは GUI テーマのプロパティを継承しません。ただし外観はカスタマイズ可能であり、Control ノードと同じフォントサブリソースを使用します (MSDF フォントレンダリングのサポートを含む)。
利点
Label3D は TextMesh よりも生成が高速です。どちらもキャッシュメカニズムを使用して新しいグリフを1回だけレンダリングしますが、特に長いテキストの場合は Label3D の方が (再) 生成が高速です。これにより、ローエンドの CPU やモバイルでのゲームプレイ中にテキスト生成負荷でアニメーションが途切れるのを防ぐことができます。
Label3D はビットマップフォントとダイナミックフォント (MSDF またはミップマップの有無にかかわらず) を使用できます。これにより TextMesh と比較して、特に自己交差するアウトラインを持つフォントや、色付きフォント (絵文字など) を柔軟にレンダリングすることができます。
参考
フォントのインポートを構成するためのガイドラインについては、 Using Fonts を参照してください。
制限事項
デフォルトでは Label3D は 3D環境との相互作用が制限されています。Shaded フラグが有効になっている場合は、ジオメトリによって遮蔽され、光源によって照らされる可能性があります。ただし Label3D の GeometryInstance3D プロパティで Cast Shadow が On に設定されていても、影は投影されません。これはノードが透明なテクスチャを持つ四角形メッシュ (四角形ごとに 1 つのグリフ) を内部的に生成するため、Sprite3D と同じ制限があるためです。複数の Label3D が重なり合っている場合、特にアウトラインがある場合は、半透明描画の並べ替えの問題も発生します。
これは Label3D の透過モードを Alpha Cut に設定することで軽減できますが、テキストのレンダリングが滑らかではなくなります。Opaque Pre-Pass モードでは、Label3D が影を落とすことを可能にしながらテキストの滑らかさを維持できますが、半透明描画の並べ替えの問題がいくつか残ります。
詳細については、3D レンダリングの制限事項ページの 半透明のソート セクションを参照してください。
Label3D を遠くから見ると、テキストのレンダリング品質が低下することもあります。テキストのレンダリング品質を向上させるには、フォントのミップマップを有効にする か、 MSDFレンダリングを使用するようにフォントを切り替える を検討してください。
TextMesh
TextMesh リソースは Label3D と似ています。どちらも3Dシーンにテキストを表示し、同じフォントサブリソースを使用します。ただし TextMesh は透明な四角形を生成する代わりに、グリフの輪郭から3Dジオメトリを生成します。その結果 TextMesh はデフォルトでシェーディングされ、自動的に環境に影を落とします。TextMesh にはマテリアルを適用することもできます (カスタムシェーダーを含む)。
以下はテクスチャの例と、それがメッシュにどのように適用されるかを示したものです。以下のテクスチャは生成されたメッシュの UV マップの参照として使用できます。
利点
TextMesh には Label3D に比べていくつかの利点があります。
TextMesh はテクスチャを使用して、テキストの色を側面ごとに変更できます。
TextMesh ジオメトリには実際の深さを持たせることができるため、グリフに3Dの外観を与えることができます。
TextMesh は Label3D とは異なり、カスタムシェーダーを使用できます。
制限事項
TextMesh にはいくつかの制限があります:
Label3D とは異なり、アウトラインのサポートは組み込まれていません。ただしカスタムシェーダーを使用してシミュレートすることができます。
動的フォントのみがサポートされています (
.ttf、.otf、.woff、.woff2)。.fntまたは.font形式のビットマップフォントは サポートされていません。自己交差するアウトラインを持つフォントは正しくレンダリングされません。Google Fonts などのWebサイトからダウンロードしたフォントでレンダリングの問題が発生する場合は、代わりにフォント作成者の公式 Web サイトからフォントをダウンロードしてみてください。
テキストレンダリングのアンチエイリアシングには、MSAA、FXAA、テンポラル アンチエイリアシング (TAA) などのフルシーンアンチエイリアシングメソッドを有効にする必要があります。アンチエイリアシングメソッドが有効になっていない場合、特に遠くから見るとテキストが粗く表示されます。詳細については 3D antialiasing を参照してください。
投影Labelノード(またはその他のControl)
最後に設定がより複雑ですが、最も柔軟性の高いソリューションとして、2Dノードを3D空間に投影する方法があります。これはスクリプトの _process() 関数内の Camera3D ノードの unproject_position メソッドの戻り値を使用して実現できます。この戻り値はControlノードの position プロパティを設定するために使用する必要があります。
この例については、3D waypoints デモを参照してください。
利点
Label、RichTextLabel、Button などのノードを含む任意のControlノードを使用できます。これにより強力な書式設定と GUI 操作が可能になります。
スクリプトベースのアプローチでは、配置の自由度が完全に高まります。たとえばコントロールが画面外になったときに画面の端に固定することが非常に簡単になります (例: ゲーム内の3Dマーカーなど)。
Controlのテーマ設定が適用されます。これによりプロジェクト全体に適用されるカスタマイズが容易になります。
制限事項
投影Controlは、3Dジオメトリによって遮られることはありません。コントロールのターゲット位置がコライダーによって遮られている場合は、RayCast を使用してコントロールを完全に非表示にすることができますが、コントロールを壁の後ろに部分的に隠すことはできません。
距離に応じてテキストサイズを変更するには、Controlの
scaleプロパティの調整を手動で行う必要があります。Label3D と TextMesh は、柔軟性が低くなるという代償を払って、これを自動的に処理します (ピクセル単位で最小/最大のテキスト サイズを設定できません)。解像度とアスペクト比の変更の処理はスクリプトで考慮する必要があり、これは対応が難しい場合があります。
Label3D、TextMesh、投影Controlのどれを使用するべきか?
ほとんどのシナリオでは、セットアップが簡単でレンダリング品質も高い (特に3Dアンチエイリアシングが無効になっている場合) Label3D が推奨されます。
高度なユースケースでは、TextMesh はカスタムシェーダーを使用してテキストをより柔軟にスタイリングできます。カスタムシェーダーを使用すると、テキストを表面に沿って曲げるなど、最終的なジオメトリも変更できます。テキストは実際の3Dジオメトリであるため、オプションでテキストに深みを持たせることができ、グローバルイルミネーションにも寄与できます。
BBCode やControlのテーマ設定サポートなどの機能が必要な場合は、投影 RichTextLabel ノードを使用するのが唯一の方法です。