はじめに
OpenSiv3Dで3Dゲームを作っているときに、なぜかUIが表示されないといったことはありませんか?
この、「3D描画はされるのに、2DのUIは表示されない」といった問題の解決方法を説明します。
2025-05-22
OpenSiv3Dで3Dゲームを作っているときに、なぜかUIが表示されないといったことはありませんか?
この、「3D描画はされるのに、2DのUIは表示されない」といった問題の解決方法を説明します。
先に結論を述べると、「2DのUI描画は3D描画の後に行なう」ということを守れば確実に描画されます。
どういうことか、コードを実際に見てみましょう。
次のコードは、OpenSiv3Dで3D描画するときのメインループ内のサンプルコードを超簡略化したものです。
#include <Siv3D.hpp>
void Main() {
// ウインドウとシーンを 1280x720 にリサイズ
Window::Resize(1280, 720);
while (System::Update()) {
// 3D描画処理
{
// 3D 描画をこの仮の画面(MSRenderTexture)に行う
const ScopedRenderTarget3D target{ renderTexture.clear() };
// 床を描画
Plane{ 64 }.draw(Palette::Red);
}
// 3D シーンを 2D シーンに描画
{
// renderTexture を resolve する前に 3D 描画を実行する
Graphics3D::Flush();
// マルチサンプル・テクスチャのリゾルブ
renderTexture.resolve();
// リニアレンダリングされた renderTexture をシーンに転送
Shader::LinearToScreen(renderTexture);
}
//================================
// ここから2DのUI描画をはじめる!!
//================================
RectF{ lineX - 2, 0, 2, Scene::Height() }.draw(ColorF{ 1.0, 1.0, 1.0, 0.04 });
}
}
メインループ内では、3D描画→3Dシーンを2Dシーンに描画という流れで進行します。
ここで、3D描画の途中で2DのUIを描画しようとしても描画されません!!
必ず、
{
// renderTexture を resolve する前に 3D 描画を実行する
Graphics3D::Flush();
// マルチサンプル・テクスチャのリゾルブ
renderTexture.resolve();
// リニアレンダリングされた renderTexture をシーンに転送
Shader::LinearToScreen(renderTexture);
}
この処理の後に2DUIを描画するようにしましょう。
これを守れば必ず描画されます。
ここからは完全に推測なので、間違っている可能性があることを念頭に置いてください。
「3D描画を2Dシーンに描画する」といった処理は、いわゆる「バックバッファに描画している」ことと同義なのだと思います。
OpenSiv3Dで3Dを描画するときの流れを振り返ってみると、
という流れです。
つまり、3Dとして描画した後に画面に表示されているのは2Dの画像のようなものです。
UIを描く場合は、「この3Dの仮のキャンバスの上」ではなく、「3Dを2Dにした画像の上」ですよね。
だから、UIを一緒に描画したい場合は、この画像の上、つまり3D描画が終わった後にコードを書く必要があるというわけです。
今回は3D描画の時にUIが表示されない問題の解決方法を解説しました。
まだまだOpenSiv3Dの3D関連の情報は少ないので、参考になったら幸いです。