FloatSoda.OVR 0.3.1

dotnet add package FloatSoda.OVR --version 0.3.1
                    
NuGet\Install-Package FloatSoda.OVR -Version 0.3.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="FloatSoda.OVR" Version="0.3.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FloatSoda.OVR" Version="0.3.1" />
                    
Directory.Packages.props
<PackageReference Include="FloatSoda.OVR" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add FloatSoda.OVR --version 0.3.1
                    
#r "nuget: FloatSoda.OVR, 0.3.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package FloatSoda.OVR@0.3.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=FloatSoda.OVR&version=0.3.1
                    
Install as a Cake Addin
#tool nuget:?package=FloatSoda.OVR&version=0.3.1
                    
Install as a Cake Tool

FloatSoda: SteamVR Overlay UI Framework

NuGet NuGet Downloads CI License: MIT

FloatSoda is a UI framework for building SteamVR overlays with a Flutter-like declarative API in C# / .NET. It renders via SkiaSharp → OpenGL → OpenVR, and manages multiple overlays (dashboard, world-space, and device-tracked) in a unified way. Currently in alpha — APIs may change without notice.

📖 The documentation below is in Japanese. See the Wiki for details, or check the minimal example — the code speaks for itself.

FloatSoda は、SteamVR Overlay を Flutter のような宣言的な書き心地 で作成できるように開発中の UI フレームワークです。SkiaSharp → OpenGL → OpenVR という経路でレンダリングし、複数のオーバーレイを統一的に管理できます。


特徴

  • Flutter-like な開発体験: StatelessWidget / StatefulWidget による宣言的な UI 構築と SetState() による再ビルド
  • 差分更新: BuildOwner による Widget の差分ビルドと、dirty フラグによる RenderObject の差分レイアウト・差分ペイント
  • RenderObject ツリー: Flutter の RenderObject に相当するレイアウト・描画ツリーを実装
  • 複数オーバーレイ対応: ダッシュボード・ワールド座標固定・デバイス追従を同時に管理
  • Skia による描画: SkiaSharp を使用した高品質なレンダリング
  • スレッドセーフ: メインスレッドとレンダースレッドをレイヤークローンで分離

Getting Started

動作環境

  • .NET 10 / C# 14
  • SteamVR(起動済みであること)
  • SkiaSharp / OpenTK / OpenVR

サンプルアプリの起動

# SteamVR を起動してから実行する
dotnet run --project samples/FloatSoda.Samples.OverlayApp

SteamVR ダッシュボードにカラーボックスを表示するオーバーレイが起動します。

最小構成のコード

using FloatSoda;
using FloatSoda.Widgets;
using FloatSoda.Widgets.Layout;
using FloatSoda.Widgets.Paint;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SkiaSharp;

var builder = Host.CreateApplicationBuilder(args);
builder.Services.AddFloatSoda();

using var host = builder.Build();
var app = host.Services.GetRequiredService<FloatSodaApp>();

Widget root = new Align
{
    Child = new SizedBox
    {
        Width = 100,
        Height = 100,
        Child = new ColoredBox
        {
            Color = SKColors.Tomato
        }
    }
};

// ダッシュボードオーバーレイ(サイズは root のレイアウト結果に自動追従)
app.CreateWindow(new DashboardWindow { Title = "MyDashboard", Child = root });

// ワールド座標固定(メートル単位。Position 省略時は前方1m・高さ1m)
// app.CreateWindow(new WorldSpaceWindow { Title = "MyWorld", Child = root });

// デバイス追従
// app.CreateWindow(new DeviceTrackedWindow { Title = "MyHand", Child = root, Target = TrackedDevice.LeftController });

await host.RunAsync();

レンダリングライフサイクル

sequenceDiagram
    participant Main as メインスレッド
    participant Pipeline as RenderPipeline
    participant RO as RenderObject 群
    participant Layer as レイヤーツリー
    participant RT as レンダースレッド
    participant GL as GLView (OpenGL)
    participant VR as OpenVR Compositor

    loop メインループ
        Main->>Main: VREventDispatcher.PollEvents()
        Main->>Pipeline: FlushLayout()
        Pipeline->>RO: Layout(BoxConstraints) [再帰]
        Note over RO: 制約↓ サイズ↑
        Main->>Pipeline: FlushPaint()
        Pipeline->>RO: Paint(PaintingContext, Offset) [再帰]
        Note over RO: Skia ドローコールを記録<br/>→ PictureLayer に格納
        Main->>Layer: Clone() — スレッドセーフコピー
        Main-->>RT: PostTask(layer)
        Main->>Main: FramePacer.WaitForNextFrame()
    end

    loop レンダースレッド
        RT->>GL: Clear()
        RT->>Layer: Layout(LayerContext)
        RT->>Layer: Paint(LayerContext)
        Note over Layer: DrawPicture / SaveLayer<br/>でレイヤーを合成
        RT->>GL: Flush()
        Note over GL: SKSurface → GRContext → GL テクスチャ
        RT->>VR: Overlay.Texture.FromTexture_t(GL texture handle)
    end

詳細は docs/Architecture.md を参照。


実装済みの Widget

レイアウト系

クラス 説明
Row / Column / Flex 子を水平・垂直に並べる。MainAxisAlignment / CrossAxisAlignment を指定可
Align / Center 子を Alignment で配置
SizedBox Width / Height で固定サイズを与える
ConstrainedBox 子に BoxConstraints を付与してサイズを制約

描画系

クラス 説明
ColoredBox 矩形を指定色で塗りつぶす
Image FileImageProvider でロードした画像を描画
Text / RichText テキストを描画(TextRichText の簡易ラッパー)
ClipRect / ClipRoundRect / ClipOval 矩形・角丸矩形・楕円でクリップ
ClipCustomPath 任意の SKPath でクリップ(CustomClipper<SKPath> を渡す)

ウィンドウ系

クラス 説明
DashboardWindow SteamVR ダッシュボードに表示するオーバーレイ
WorldSpaceWindow ワールド座標に固定するオーバーレイ(メートル単位)
DeviceTrackedWindow HMD・コントローラー等のデバイスに追従するオーバーレイ

自作 Widget の基底クラス

  • StatelessWidgetBuild() をオーバーライドして UI を宣言
  • StatefulWidget<T> + State<T>SetState() で状態変更と再ビルド
  • InheritedWidget — ツリー下方向へのコンテキスト伝播

Container / Padding / Opacity / ListView / GridView / Button / GestureDetector などは API 定義のみの未実装スタブです。


ドキュメント

入り口は docs/Home.md です(GitHub Wiki にも自動同期されます)。

ドキュメント 内容
docs/Home.md ドキュメントトップ・全体像・実装状況サマリ
docs/GettingStarted.md クイックスタートガイド
docs/Architecture.md アーキテクチャ概要・フレームパイプライン・スレッドモデル
docs/WidgetSystem.md ウィジェット/エレメントシステム
docs/BuildPipeline.md BuildOwner による Widget 差分更新の仕組み
docs/RenderObjects.md RenderObject ツリーのリファレンス
docs/OVRIntegration.md OpenVR インテグレーションリファレンス
docs/APIDesign.md API 設計規約

開発ステータス

本プロジェクトは現在 Alpha 段階・Phase 1(入力基盤)進行中 です。簡単なアプリケーションは動作しますが、API は予告なく変更されます。

開発は Phase 単位で進めています。Phase は「フレームワークとして何ができる段階か」を表す機能上の到達点で、NuGet のバージョン番号とは対応しません。バージョンはリリースの通し番号として独立に上がり、同じ Phase 中に複数のバージョンが公開されることがあります(バージョン番号から Phase を推定することはできません。1.0.0 のみ Phase 7 に対応)。各 Phase の詳細スコープは GitHub マイルストーン を参照してください。

Phase 内容 作れるようになるアプリ 状況
Phase 1 入力基盤(HitTest / Pointer / Gesture) 操作できるパネル(GestureDetector で完全自作したボタン・トグル) 🚧 進行中
Phase 2 basic.dart 相当の表示系ウィジェット網羅(画像・アイコン含む) リッチな HUD / 字幕オーバーレイ 未着手
Phase 3 スクロールとアニメーションの充実(Tween / 暗黙的アニメーション / 物理シミュレーション) チャットビューア等のリスト系アプリ 未着手
Phase 4 Hooks・テキスト入力・API安定化 VR 内メモ帳などの入力を伴うアプリ 未着手
Phase 5 Cream / FizzyPop デザインシステム完成 テーマを選べる実用 UI アプリ 未着手
Phase 6 DX 向上(Storybook・manifest 自動生成・ライフサイクル) デスクトップ常駐+VR のハイブリッドツール 未着手
Phase 7 安定版リリース(1.0) 実用オーバーレイ全般 未着手

⚠️ Phase 1 が完了するまで、ヒットテスト・ボタン押下などのユーザー操作は動作しません(表示専用)。

  • RenderObject ツリー(レイアウト・描画・クリップ・画像・差分更新)
  • レイヤーツリー(ContainerLayer / PictureLayer / ClipLayer / OpacityLayer)
  • 複数オーバーレイ(ダッシュボード / ワールド座標 / デバイス追従)
  • Widget → RenderObject への inflate パイプライン(StatelessWidget / StatefulWidget)
  • BuildOwner による Widget 差分ビルド(Key による子リストの差分更新を含む)
  • InheritedWidget によるコンテキスト伝播
  • アニメーションシステム(AnimationController / Ticker / FadeTransition)
  • SteamVR のイベント処理と宣言的な入力(ヒットテスト)
  • マニフェストファイルの自動生成(検討中)
Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on FloatSoda.OVR:

Package Downloads
FloatSoda.Engine

Platform layer for FloatSoda: GLFW/OpenGL rendering via SkiaSharp, the render thread runner, overlay windows, and frame limiting.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.3.1 154 7/23/2026
0.2.0 136 7/16/2026
0.1.0 140 7/14/2026
0.0.3 151 7/12/2026
0.0.2 144 7/10/2026