符号付き距離フィールドフォントを使用したシャープコーナー


49

この論文では、Valveによる解像度に依存しないフォントレンダリングを実現する高速ソリューションとして、符号付き距離フィールド(SDF)が提示されました。

私はすでにValveソリューションを動作させていますが、角の周りのシャープネスを維持したいと思います。Valveは、2番目のテクスチャチャンネルとベースチャンネルのANDを使用することで、この方法でシャープなコーナーを実現できると述べていますが、この2番目のチャンネルがどのように生成されるかを説明していません。

実際、このホワイトペーパーには実装の詳細が数多く残されています。

鋭い角のあるSDFフォントレンダリングを取得する方向性を指摘できる方がいるかどうかを知りたいと思います。


実際のところ、Adamはすでにshadertoyにソースコードを投稿しています。ここにリンクがあります:shadertoy.com/view/ltXSDB
フェリペ・リラ

あなたは私を興奮させました。彼はシェーダートイにベジエのものを投稿しましたが、テクスチャ距離フィールドのものは投稿しませんでした!
アランウルフ

@AlanWolfe彼は手続き的に設定されたベジェ曲線に対してのみ行ったと思います。これをttf render libに統合するのに必要な作業がわからない。時間があれば、それを見てみましょう。
フェリペ・リラ

彼は実際にテクスチャからの距離を保存および取得する側に魔法のソースを持っているようです。テクスチャが使用されていない場合、シェードトイの例には方程式のその部分がありません。
アランウルフ

少し遅れて相手になく、のredditから、この古いスレッドには、SDFベースのレンダリングのシャープネスを向上させるための様々な方法についての情報のトンを持っていますreddit.com/r/gamedev/comments/2879jd/...
Necrolis

回答:


7

Adam Simmonsはこの分野でいくつかの興味深い仕事をしています。彼がどのようにそれを達成しているのか具体的にはわかりませんが、彼のSDFベースのベクターレンダリングは、Valve以外で実際に見た中で最もシャープです。http://twitter.com/adamjsimmons/status/611677036545863680


もちろん、私はすべての詳細を知っているわけではありませんが、この人は通常のフィールドの代わりに擬似距離フィールドを使用しただけであるように思われます。リアルタイムのテクスチャマップベクトルグリフ」は、Valveの論文でも参照されています。アウトラインのマイターにのみ影響し、コーナーの外観を改善するものは何もありません。シャープに見える理由は、彼が非現実的に大きな距離フィールドテクスチャを使用しているためだと思います。私は間違っているかもしれません。
Detheroc

69

編集:具体的な解決策と私の他の答えをご覧ください。

私は実際に修士論文のために1年以上前にこの正確な問題を解決しました。バルブペーパーでは、2つの距離フィールドとこれを実現することができることを示しています。これは、凸状のコーナーが1つしかない限り機能します。凹型コーナーの場合は、OR演算も必要です。この男は、実際には、4つのテクスチャチャネルを使用して2つの操作を切り替えるための不明瞭なシステムを開発しました。

しかし、状況に応じてANDとORの両方を容易にすることができるはるかに単純な操作があり、これが私の論文の主要な考えです:3の中央値。したがって、基本的には、完全に交換可能な正確に3つのチャネル(RGBに最適)を使用し、中央値演算を使用してそれらを結合します(3つから中央の値を選択します)。

アンチエイリアシングに対応するために、ブール値だけではなく、浮動小数点値、およびAND演算が最小になり、ORが2つの値の最大値になります。3の中央値は実際に両方を行うことができます:a < bの場合aab)の場合、中央値は最小であり、(abb)の場合、最大値です。

レンダリングプロセスは依然として非常に簡単です。アンチエイリアスを含むフラグメントシェーダー全体は、次のようになります。

int main() {
    // Bilinear sampling of the distance field
    vec3 s = texture2D(sdf, p).rgb;
    // Acquire the signed distance
    float d = median(s.r, s.g, s.b) - 0.5;
    // Weight between inside and outside (anti-aliasing)
    float w = clamp(d/fwidth(d) + 0.5, 0.0, 1.0);
    // Combining the background and foreground color
    gl_FragColor = mix(outsideColor, insideColor, w);
}

したがって、元の方法との唯一の違いは、テクスチャをサンプリングした直後に中央値を計算することです。ただし、中央値関数を実装する必要があります。これは、わずか4 min / max操作で実行できます。

もちろん、問題は、このような3チャンネルの距離フィールドをどのように構築すればよいのかということです。そして、これはトリッキーな部分です。私が最初に取った最も明白なアプローチは、入力形状/グリフを3つのコンポーネントに分解し、それぞれから従来の距離フィールドを生成することでした。この分解のルールはそれほど複雑ではありません。まず、3つのチャネルのうち少なくとも2つがオンになっているエリアが内側です。次に、これをRGBカラーチャネルと考える場合、凸状の角は2次色で作成する必要があり、その2つの主要コンポーネントは外側に向かって続きます。凹角は逆です。2つの2次色は共通の1次色を囲み、両方のエッジが内側に続く部分の間のくさびは白です。また、アーティファクトを回避するために2つのプライマリカラーまたは2つのセカンダリカラーが接触する場合は、いくつかのパディングが必要であることがわかりました(たとえば、「N」

次の図は、私の論文のプログラムによって生成された分解の例です。

グリフのマルチチャネル分解

ただし、このアプローチにはいくつかの欠点があります。その1つは、アウトラインや影などの特殊効果が正しく機能しなくなることです。幸運にも、距離フィールドを直接生成し、すべてのグラフィック効果をサポートする、よりエレガントな2番目の方法も思いつきました。私の論文にも含まれているので、1年以上も経っています。現在、この2番目の手法を詳細に説明する論文を執筆しているため、これ以上詳細を説明するつもりはありませんが、完了したらすぐにここに投稿します。

とにかく、ここに品質の違いの例があります。テクスチャ解像度は各画像で同じですが、左のものは通常のテクスチャを使用し、中央のものは通常の距離フィールドを使用し、右のものは私の3チャンネル距離フィールドを使用します。パフォーマンスのオーバーヘッドは、RGBテクスチャのサンプリングとモノクロテクスチャのサンプリングの違いのみです。

ここに画像の説明を入力してください


5
偉大な最初の答え、コンピューターグラフィックスSEへようこそ!:)あなたの論文は公開されていますか?(または、あなたがその論文を書き終えた後でしょうか?)もしそうなら、おそらくそれにリンクすることも非常に役立つでしょう。
マーティンエンダー

一般公開される予定ですが、学校はまだ公開していないようです。とにかく、私が書いている記事は重要な部分をよりよく説明し、それを実装する方法に焦点を合わせているので、今すぐ広めたくないと思います。
Detheroc

@Detheroc記事を読み終えたら、こちらとgamedev Qでお知らせください。説明はまだ100%明確ではありません。構図を段階的に画像で示すことをお勧めします。
エンジニア

1
あなたの現在の結果が将来の結果ほど良くない場合でも、あなたの現在の結果を再現できることを望みます。可能な限り詳細を共有するために+1します。とてもわくわくする。レイマーチング(球体追跡)へのいずれかの手法の適用を検討しましたか?ボリュームテクスチャまたは類似...で
アラン・ウルフ

4
論文は、ここに公開されている:dspace.cvut.cz/bitstream/handle/10467/62770/...
ロマン・ガイ

43

長い間待って申し訳ありませんが、約束した記事は基本的に完了していますが、公開プロセスには時間がかかることが明らかになりました。したがって、代わりに、新しいマルチチャネル距離フィールド構築アルゴリズムmsdfgenを使用してオープンソースプログラムを準備しました。これは今すぐ試すことができます。

GitHubで入手できます:https : //github.com/Chlumsky/msdfgen

(私はこれが初めてなので、リポジトリに問題がある場合はお知らせください。)

誰かがそれをより大きなモノクロ距離フィールドと比較する方法についても尋ねたので、ここに品質の違いのティーザーがあります。ただし、実際には特定のフォントに依存するため、常に追加データの価値があるとは言いません。

マルチチャネル距離フィールド16x16 モノクロ距離フィールド32x32


3

とても面白い!私は、バルブ署名距離紙の著者です。実装の詳細が少しまばらであることを申し訳ありません。将来の作業として2つのチャネルの例のみを含めました。ジェネレーターはありませんでした。高解像度のsdfを生成し、sdfの勾配の角度に基づいてセグメント化するのは合理的な戦術だと考えました。しかし、決してそれには至らなかった。アプリが必要とする拡大率のために、同じメモリフットプリントの高解像度シングルチャネルデータを使用する場合と比較して、マルチチャネルスキームを比較検討する必要があります。


0

私は決してこのテーマの専門家ではありませんが、標準のバイリニアフィルターの代わりにバイラテラルフィルターまたは指向性バイキュービックフィルターを使用した場合、少なくとも理論的には、単色の擬似SDFの鋭い角を維持できるかもしれません。メモリを節約することの明らかな利点に加えて、マルチカラーのSDFデカール用に複数のチャネルを使用することもできます。

別の方法として、2番目のチャネルを使用しても構わない場合は、1つのチャネルを水平距離に、もう1つのチャネルを垂直距離に設定し、ラプラスタン(DoL)エネルギーピラミッドの違いを使用してテクスチャを圧縮して冗長な情報を取得することもできます記録されません。

3番目の最終的な理論的解決策は、配列セットアドレッシングを介して六角形にサンプリングされたテクスチャを実験することです。

残念ながら、私は現在、私のアイデアをテストする手段がなく、私のアイデアに似たものを説明またはテストするドキュメントを見つけることができませんでした。すぐに情報やアイデアを入手した関連記事をすべてリンクします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.