1

ソフトウェア フィルター オブジェクトを作成し、ライト ブルーム効果を実装しようとしています。私は単純な 2 パス畳み込みアプローチを使用していますが、効果の半径が小さく、半径を制御できないように見えることを除けば、うまく機能します。より大きなボックス フィルターで遊んで、さまざまなピクセルの重みを調整しましたが、どれも効果がないようです。効果には最大サイズ (それほど大きくはありません) があるように見えますが、パラメーターへのすべての変更は、それを小さくするのに役立ちます。

任意の半径でライト ブルームを作成できるようにしたいと考えています。多くの実験とオンラインでの検索の後、私はこれができないのではないかと考え始めています. プラズマ、勾配、およびさまざまなシード方式など、代替アプローチについて考えてきましたが、最初にこのパスを地面に追い詰めたいと思います. 任意のサイズのライト ブルームを (ソフトウェアで) 作成する方法を知っている人はいますか?

JavaScript は次のとおりです (これは HTML5 キャンバスで動作します。必要に応じてコードにコメントを追加できます)。

// the kernel functions are called via Array.map on this.backBuffer.data, a canvas surface color array
this.kernelFirstPass = function(val, index, array)
{
    if(index<pitch || index>=array.length-pitch || index%pitch<4 || index%pitch>pitch-5 || index%4==3)
        return;
    var c = 1,
        l1 = 1,
        l2 = 1,
        l3 = 1,
        r1 = 1,
        r2 = 1,
        r3 = 1;
    var avg =
    (
        c*this.frontBuffer.data[index]+
        l1*this.frontBuffer.data[index-4]+
        l2*this.frontBuffer.data[index-8]+
        l3*this.frontBuffer.data[index-12]+
        l1*this.frontBuffer.data[index+4]+
        l2*this.frontBuffer.data[index+8]+
        l3*this.frontBuffer.data[index+12]
    )/(c+l1+l2+l3+l1+l2+l3);
    //this.frontBuffer.data[index] = avg;
    array[index] = avg;
}
this.kernelSecondPass = function(val, index, array)
{
    if(index<pitch || index>=array.length-pitch || index%pitch<4 || index%pitch>=pitch-4 || index%4==3)
        return;
    var c = 1,
        l1 = 1,
        l2 = 1,
        l3 = 1,
        r1 = 1,
        r2 = 1,
        r3 = 1;
    var avg =
    (
        c*array[index]+
        l1*array[index-pitch]+
        l2*array[index-(pitch*2)]+
        l3*array[index-(pitch*3)]+
        l1*array[index+pitch]+
        l2*array[index+(pitch*2)]+
        l3*array[index+(pitch*3)]
    )/(c+l1+l2+l3+l1+l2+l3);
    array[index] = avg;
}

おそらく、最初の質問で見逃した重要な点は、実際の現象や特定の現象をシミュレートしようとしているわけではないことを説明することでした (そして、それを「明るい」ブルームと呼ぶことはおそらく役に立たないでしょう)。実際の光の現象を扱う場合、任意の半径の半影を作成するには、任意の半径のソース (つまり、「完全に飽和した領域」) が必要です。それが実際に本物のライトブルームの振る舞いであるなら、ジムとツクジーの説明はそれをシミュレートするための合理的なアプローチのように思えるでしょう. とにかく、それは私が達成しようとしていることではありません。ブルームの「グラデーション」部分の半径を、サイズ/強度などとは別に制御したいと考えています。ソースの。シングルを設定できるようにしたいのですが、

4

2 に答える 2

0

良好なブルーム効果を実現するには、ハイダイナミックレンジレンダリングを使用する必要があります。そうしないと、白が十分に明るくなりません。

この理由は、ピクセルの明るさは通常[0,1]の範囲から表されるためです。したがって、最大輝度は1に固定されます。ただし、実際の状況では、実際には最大輝度はありません。そして、本当に明るい光はすべて「1」として認識されますが、ブルームのような視覚的な副作用は同じではありません。

したがって、少なくともブルームコンボリューションでは、本当に明るい領域が最大輝度を超えるようにする必要があります。次に、レンダリングを行うときに、必要に応じて値をクランプします。

これが完了すると、畳み込みで使用されるエアリーディスクのサイズを大きくするだけで、ブルーム半径を大きくできるはずです。

于 2012-07-12T03:52:06.187 に答える
0

tskuzzyの答えの簡単な要約は次のとおりです。浮動小数点バッファを使用して開花前の画像を保存し、2番目の浮動小数点バッファに畳み込む(ピクセルを飽和させて整数形式に戻す)か、オンザフライで飽和させて変換します各出力ピクセルを整数出力バッファに直接格納する前に整数に戻します。

Airy 畳み込みはヘッドルームを使用して行う必要があります (つまり、固定小数点または浮動小数点のいずれかで、最近では前者は一般的な高速 FPU で手間をかける価値はありません)。これにより、画像内の明るいスポットがそれに応じてより多くにじみます。それらの近隣地域。

注: 色のオンザフライ彩度は、チャネルを個別にクリッピングするほど単純ではありません。これを行うと、クリッピングされたスポットの周りに色相の歪みや輪郭が生じる可能性があります。

于 2012-08-14T14:12:39.130 に答える