2013-02-19 11 views
7

私はWebGLでいくつかの画像処理をしようとしています。しかし、モバイルデバイス上のGLSLテクスチャに大きな画像(カメラから - 8 MP)を読み込もうとすると、ブラウザがクラッシュします。小さな写真は正常に動作します。だから私はそれが記憶を使い果たしていると思う。WebGL - 大きなテクスチャをレンダリングするには?

私はたくさんのGoogle検索を行ったが、解決策を見つけられなかった。私は最善の方法は、 "タイルベースの"レンダリングを実装することだと思う。 8枚のMP画像を小さな部分に分割し、それらをレンダリングして貼り付けます。しかし、ぼかし効果を適用するような問題があります。 「サブレンダリング」のエッジが表示されます。だから私は、重複するピクセルをレンダリングし、一緒に "フェード"しなければなりません。それは良いとは言えませんでした。

私が考えている解決策はありますか?モバイルデバイスで本当に巨大なテクスチャを使用するにはどうすればいいですか?

+0

私はWebGL [here](http://media.tojicode.com/zelda/lttp.html)でタイルベースの処理の良い例を見てきました。 Nexus 7では正常に動作します。 –

+0

私が探しているものではありません。彼は一つの大きなキャンバスに多くのタイルを描いている。私は、大きな画像にシェーダ効果を適用するソリューションを探しています。何が最善の方法であるかわからない。 「タイルベースのレンダリング」とは、大きなイメージを多数の小さなイメージに分割し、各小さなイメージにシェーダを適用することです。すべてを背中合わせにするよりも。しかし、それはぼかし効果のようないくつかの効果でうまく動作しません。ぼかし(または鮮明に)するときは、周囲のピクセルを考慮する必要があります。だから、小さな画像をすべてぼかして、もう一度まとめると、すべての小さな画像のエッジが見えます。 –

+0

私の質問は、WebGLの大きな画像/テクスチャをどのように扱うかです。どのような可能性がありますか? –

答えて

3

タイルを機能させるために必要なことは、画像処理エフェクトの非局所性をカバーするために境界線に十分な入力を提供することです。ぼかしカーネルの半径。私が考えることができる最も簡単なものは次のとおりです。

出力画像の各タイルに対して、対応する入力タイルとその8近傍をにロードします。次に、すべての9を入力として使用してぼかしフィルタを実行します。通常はtexture2Dを呼び出します。代わりに、座標を取り込んで(カスタム)関数を使用して、9つのテクスチャのうちの適切なものを探します。

テクスチャを少なくするには、入力タイルと出力タイルを両方の寸法の半分の長さだけオフセットします。各タイル計算に4つの入力タイルを使用するだけで済みますが、すべての入力をカバーするのに十分なタイルを使用すると、出力タイルに余分な境界線ができます。 (一方で、後でトリミングするのが賢明な場合は良いことです;例えば、入力画像にドロップシャドウを適用すると、のように、のように出力を拡大するのではなく

これを正しく行うと、タイルの境界にのアーティファクトが存在するはずです。

(免責事項:このソリューションは単純で明白で正しいと思われますが、私は画像処理やGPUリソ​​ースの節約の専門家ではありません。そこにある)

+0

それは本当に良いアイデアですが、各タイルに「マージン」を加えて「フェーディング」するほどの計算は必要ありません。あなたのソリューションは実装が容易でなければなりません。ありがとうございました! :)おそらく、はるかに良いGLSLソリューションがありますか?どんなプロにも? –

2

1つの8mpイメージが利用可能なラムを超えることはありそうにありません。 RGB(バイト)では、24MBのRAMを占有します。浮動小数点の精度が半分であっても、RAMは50MBになります。 ARMシステムでは、GPUとCPUがRAMを共有する統合RAMアーキテクチャを使用します。例えばiPhoneには1GBのRAMがあります。

テクスチャリングのサポートは、ハイエンドの携帯電話(4096x4096は81% of mobilesでサポートされています)では問題ないと思われる、希望のサイズ(たとえば3264x2248)まででなければなりません。

最大描画バッファサイズが、サポートされている最大テクスチャサイズ(query that)よりも小さい可能性があります。

それ以外の場合は、バグが発生している可能性があります。これは迷惑です。つまり、画像を小さなタイルに細分し、各タイルを1つずつ処理することです。

フィルタカーネルがある場合は、境界線を扱う方法は2つあります。

  • あなたは正しいものを(それは遅いかもしれないが、一部のGPUが分岐サポートしていないと、すべてのコードパスを実行します)に対処するためにテクスチャルックアップで9つのテクスチャやブランチに渡すことができます。境界テクスチャは2x2にすぎないので、ラムの足跡はほとんどありません。テクスチャ間には補間がないので、それに頼ったり、自分の代わりにしたりしないでください。
  • 前処理ステップで近隣のタイルからピクセルを取って、各タイルの周りにカーネルサイズの半分の境界線を追加できます。
+0

これはとても役に立ちました、ありがとうございました!デスクトップブラウザではすべてが正常に動作していますが、モバイルではクラッシュします。私は限られた記憶を考えましたが、あなたは正しいです、十分なラムがあるはずです。そこで私は最初にいくつかのGL関数呼び出しのロギングを実装し、どの呼び出しがクラッシュするかを確認します。あなたの素晴らしい記事をありがとう! –

関連する問題