forma - 効率的なベクターグラフィックスレンダラー

(An efficient vector-graphics renderer)

Created at: 2022-11-17 22:21:47
Language: Rust
License: Apache-2.0

フォルマ ロゴ

crates.io バッジ

ソフトウェア(CPU)とハードウェア(GPU)の両方を備えた(徹底的に)並列化された実験的なRustベクターグラフィックスレンダラー 次の目標を持つバックエンドをこの順序で示します。

  1. ポータビリティ;Fuchsia、Linux、macOS、Windows、Android、iOSをサポートしています。
  2. パフォーマンス;命令レベルとスレッドレベルの両方で高度に並列化されたコンピューティング重視のパイプラインを利用します。
  3. シンプルさ;わかりやすい4段パイプラインの実装。
  4. サイズ;依存関係の数を最小限に抑え、ベクターグラフィックスのみに焦点を当てます。

RustのSIMD自動ベクトル化/組み込み関数とRayonに依存してCPUで優れたパフォーマンスを発揮し、WebGPU(wgpu)を使用してGPUを活用します。

はじめ

依存関係に以下を追加します。

Cargo.toml

forma = { version = "0.1.0", package = "forma-render" }

4段パイプライン

1.曲線の平坦化 2. 線分のラスタライズ 3. ソート 4.塗装
ベジェ曲線 線分 ピクセルセグメント ソートされたピクセルセグメント、古いタイル
⬇️⬇️⬇️ ⬇️⬇️⬇️ ⬇️⬇️⬇️ ⬇️⬇️⬇️
線分 ピクセルセグメント ソートされたピクセルセグメント 塗りたてのタイル

実装のハイライト

ここでは、一般的に使用されるベクターレンダラーからformaを際立たせる実装のハイライトをいくつか紹介します。

曲率を考慮した平坦化

すべての高次立方ベジエは二次ベジエで近似され、次に並行して、曲率に従って線分に平坦化されます。この技術はラフ・レヴィアンによって開発されました。

安価な翻訳と回転

平行移動と回転は、完全な品質を維持しながら、曲線を再平坦化することなくレンダリングできます。

平行ピクセルグリッド交点

線分は、ピクセル グリッドと交差することによってピクセル セグメントに変換されます。この計算をO(1)で実行し、並列に実行する簡単な方法を開発しました。

効率的な仕分け

crumsortをRustに移植し、Rayonと並列化することで、64ビットランダムデータのpdqsort実装よりもパフォーマンスが向上しました。ある種のピクセルセグメントを散乱させることは、スピネルに関するアランマッキノンの研究に触発されました。

変更されたタイルのみを更新する (現在は CPU のみ)

ペイント手順を完全にスキップしようとするタイルごとのフェイルファストオプティマイザーを実装しました。同様のアプローチをGPUでテストすることもできます。

画面に表示されるアニメーション 更新されたタイルのみ
ジュースアニメーション更新タイル

上記のデモは、次のように実行できます。

cargo run --release -p demo -- spaceship

類似のプロジェクト

Formaは、以下のプロジェクトから大きなインスピレーションを得ています。

  • スピネル、Vulkan 1.2バックエンド付き
  • WGPU バックエンドを備えた Vello

含まれている例を使用して、いくつかの例をレンダリングできますが、そのうちの1つは非準拠で不完全なSVGレンダラーです。

demo

cargo run --release -p demo -- svg assets/svgs/paris-30k.svg

CPU上でも、インタラクティブなフレームレートで巨大なSVGをレンダリングします:(Webブラウザと比較してください)

ドイツのウィンドウレンダリングマップ

(現在)欠けている部分 🧩

このプロジェクトは進行中であるため、APIの破損は劇的ではありませんが、予想されます。GPUバックエンドのパフォーマンスは、特にパフォーマンスが低いことが知られており、代わりにCPUバックエンドが現在推奨されているモバイルでも改善されることが期待されます。

そのほかにも:

  • レイヤーの自動順序付け
  • ストローク
  • ブレンドとグラデーションのためのより多くの色空間
  • より高速なGPUソーター
  • 優れたモバイルGPUパフォーマンスのためのの使用
    f16

手記

これは公式にサポートされている Google サービスではありません。