可変線幅のトゥーン/セルシェーディング?


15

私はセルシェーディングを行うためにそこにいくつかの広範なアプローチを見ています:

  1. 法線が反転したモデルの複製と拡大(私にとってはオプションではありません)
  2. エッジ検出へのSobelフィルター/フラグメントシェーダーアプローチ
  3. エッジ検出へのステンシルバッファアプローチ
  4. 面とエッジの法線を計算するジオメトリ(または頂点)シェーダーアプローチ

たとえば、ジオメトリ中心のアプローチが照明や線の太さを最大限に制御できると仮定するのは正しいでしょうか。丘のシルエットラインが徐々に平野に合流するのを見るかもしれない地形のために?

地形の表面にピクセル照明が必要ない場合はどうすればよいですか?(そして、セルベースの頂点ベースまたはテクスチャマップベースのライティング/シャドウイングを使用する予定ではないでしょう。)それから、ジオメトリタイプのアプローチを続けるか、代わりにスクリーンスペース/フラグメントアプローチを使用する方が良いでしょうか物事をシンプルに保つために?もしそうなら、メッシュ全体のアウトラインだけではなく、メッシュシルエットの丘の「インク」をどのように取得し ますか(そのアウトライン内に「インク」の詳細はありませんか?(示唆的な輪郭折り目))。

最後に、ジオメトリシェーダーを使用して、反転法線アプローチを安価にエミュレートすることは可能ですか?これに関する私の懸念は、すべての頂点を確実に複製し、それに応じてスケーリングできることですが、法線の反転やフラグメントシェーダーの明確な色付けにどのようにアプローチするのでしょうか?

私が欲しいもの-シルエット内の邪魔な線で線の太さを変える...

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

欲しくないもの...

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


編集:さらなる研究により、次のことが明らかになりました...

私は地形に大量の頂点を持っているため、距離ベースのLoDを考慮しても、すべての複製とスケーリングに伴う計算の複雑さのために、フリップされた法線もジオメトリシェーダーベースのアプローチも(錐台カリングを使用しても)賢明なオプションになりますアップロードされた頂点。

テレインサーフェス上でソリッドトーンシェーディングの形でピクセル単位のライティングを必要としないことを考慮すると、これらのように、フェース法線ベースのアプローチ(そうでない場合は正しいサーフェスライティングの要件)を検討することも賢明ではなくなります計算するのは当然非常に高価です。しかし、それらが最高レベルの制御を提供することは事実です。たとえば、「芸術的な」ストロークを使用してエッジをシェーディングする機能:美しいですが、非常に複雑なゲーム環境では実際には実行できません。

ステンシルバッファーは、シェーダーですべての作業を行うことを好むため、避けたいものです。(上記の赤いアウトラインの例は、ステンシルバッファーで行われました-古い学校です。)

これにより、フラグメントシェーダーのイメージ空間アプローチが残ります。計算の複雑さは、頂点の数ではなくフラグメントの数に削減されます(私の場合、これはジオメトリシェーダーで行う必要がある操作よりも10〜100倍少ない操作です)。これには、不連続フィルター(Sobel演算子など)を適用できるgバッファー(通常バッファーとオプションで深度バッファーで構成される)を生成するために、複数のレンダーパスが必要です。深さの不連続性は、示唆的な輪郭と折り目を可能にします。このアプローチの私の唯一の問題は、インクエッジの幅をより細かく制御できないことですが、フラグメントシェーダーの適切なアルゴリズムを使用すれば、これが可能になると確信しています。

質問はより具体的になりました:フラグメントシェーダーで、特に外側のシルエットで、可変エッジ幅をどのように正確に取得するのですか?


線の太さを変えることは、幾何学的アプローチの特徴です。他の方法では効率的に取得できません。あなたがそれを望むので、私はピクセルシェーダーが「より効率的な方法」であるとは思わない:検索されるピクセル数=(line_thickness * 2 + 1)^ 2-1。それは基本的にあなたのポストプロセスシェーダー最大の場合、かなり遅くなります(推定値:10倍)。線幅は2です。事前に判断して、ジオメトリシェーダーアプローチを試してください。
snake5

@ snake5 GSでは、レンダリング更新ごとに1億5000万の頂点(ビューカリングで約2500万)を実行することを正直に提案していますか?私は本当にそれを買っているわけではありませんが、インプットに感謝します。頂点の数と複雑さについて上で述べたことに戻って参照してください。10xの数字であっても、フラグメントシェーダーは少なくとも均等に描画し、おそらくはるかに良くなります。
エンジニア

2,500万の頂点(線形読み取り/書き込み)vs 2,300万のテクスチャサンプル(キャッシュの読み取りが不十分で、レンダリングターゲットデータの圧縮解除)@ 1280x720。ところで、頂点数の制限/削減はずっと簡単です。特に最近では、大きなモニター(1920x1080 +)とマルチモニターのセットアップが非常に普及しています。
snake5

赤いアウトラインを生成するアルゴリズムと同じアルゴリズムを使用してから、その深さに基づいてラインを細く/成長させるのはどうですか
Ali1S232

@Gajoo、私が質問で言っていたように、それはシルエットだけではありません。最初の画像の少女の肩の後ろにある邪魔な線に注意してください。これらは反転法線アプローチの機能であり、示唆的な輪郭/折り目として機能します。私も同じことが必要です。
エンジニア

回答:


4

深度バッファの不連続フィルタリングを介したフラグメントシェーダーアプローチを採用することにしました。この理由は次のとおりです。

  1. メッシュLoDを使用しても、ビューの距離が非常に大きいため、世界の頂点数は非常に多くなります。
  2. 同じパスで同じ構造(ボックスまたはガウスサンプリング/フィルタリング)の恩恵を受けることができるDoFぼかしなど、他の多くのフラグメントシェーダー操作を行っています。

それをテストした後、将来のプロジェクトでは、複雑さの理由から、代わりにジオメトリベースのアプローチを採用すると思います。その理由は、(他のコメントで示唆されているように)エッジ検出へのフラグメントシェーダーアプローチは、特に混乱半径の円、したがってフラグメントあたりのサンプル数が非常に多くなるDoF実装では、計算量が多いためです。幸いなことに、これはアウトラインシェーダーの懸念事項ではありません。


法線の不連続性を使用すると、平坦な法線が得られた場合により良い結果が得られると思います。サンプルをさらに離すことで、線幅を変えることができます。
グライフハート

@Grieverheartこれは受け入れられた答えです。私が使用している方法はうまく機能しているからです。ありがとう。
エンジニア

0

後遺症を使用できる場合、実際には非常に簡単な一般的な解決策があります。すばらしいのは、ポリカウントがどれだけ高いかは関係ありません。深度マップをグレースケールとしてレンダリングし、隣接する2つのピクセル間のコントラストがしきい値よりも高い場合に、必要な線の色でドットを作成します。レンダリングした画像のコントラストや光のレベルに応じて、ドットを大きくすることができます。

このソリューションを作成したフランス人の前でさえ、2000/2001年にtoonShaderアルゴリズムを発明しました。私は実際の材料の形状に基づいていました。次に、基本的に2つの方法があります。1.法線を見る。線に接続された2つの平面の法線がカメラの方向を向いている場合、その線をレンダリングします。2.レンダリングされたジオマーティを確認します(遠近法変換後)。各ラインセグメントを取得します。接続面の頂点がこのラインセグメントの同じ側にある場合は、ラインをレンダリングします。方法1. 3.これら3つの手法を組み合わせて作成することもできますが、最初に言及したのは、膨大なポリカウントを示しているためです。

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