2

私は疑似 3D を行う方法を考え出そうとしており、javascript キャンバスでテクスチャを歪めています。

これまでの私のニーズに対する最良の方法は、このチュートリアルとソース コードの例から主に従っているディスプレイスメント マップを使用することでした。

基本的な原則は、ディスプレイスメント マップで選択したピクセルのチャネル レベル (RGBA) を使用してから、ピクセル シフト アルゴリズムを適用することです。

問題は、テクスチャ イメージのピクセルをシフトするこの方法が非常にバイナリであり、わずかに「ギザギザ」のエッジをレンダリングすることです。これは、単純に「フル」ピクセルをシフトしているためです。

ここにある PhotoShop やImageMagick のいくつかの例と比較すると、javascript メソッドはあまり現実的ではないように見えます。これは、PS および IM のサブピクセル処理能力によるもので、ピクセル間データの中央値を導き出すことができます。

質問:出力にガウス/エイリアスされた滑らかさを生成するために私のアルゴリズムに統合できるステップを誰かが提案できますか?

おそらく、FFTを介して画像データを実行し、再び戻すことができますか?これが実際に行われている例はありますか?

私は少し困惑しており、いくつかの指針をいただければ幸いです。

4

1 に答える 1

2

1)あなたは2つの非常に異なるアルゴリズムについて言及しています:変位マッピングは3D技術であるため、「Z」と投影が含まれ、もう1つは2Dピクセルシフトアルゴリズムの方が簡単です。

(提供されているサウンドステップ リンクでは、「ディスプレイスメント マッピング」という言葉が使用されていますが、これはピクセル シフト技術です。)

2) MVC プロジェクトのサイズに関係なく、アルゴリズム分離され、次のような署名が必要です。

var pixelShift = function (sourceCanvas, shiftCanvas, xOffset, yOffset) 

新しいキャンバスを返すか、sourceCanvas を変更します。

そのような機能がない場合は、MVC について話さないでください。ただし、M が「Mess」を表す場合を除きます。;-) -

3) アルゴリズムは実際には非常に単純です。目的のピクセルを繰り返し処理し、元のピクセルの色を確認する必要があります (その逆ではありません)。

var pixelShift = function (sourceCanvas, shiftCanvas, xOffset, yOffset) {
    var shiftXY           = { xS:0, yS:0     };
    var shiftCanvasWidth  = shiftCanvas.width ;
    var shiftCanvasHeight = shiftCanvas.height;
    for ( var x=0 ; x < shiftCanvasWidth ; x ++) {
        for ( var y = 0 ; y < shiftCanvasHeight ; y++ ) {
            readShift ( shiftCanvas, x, y, shiftXY );
            var sourceColor = readPixelColor ( sourceCanvas, 
                                                 xOffset + shiftXY.xS, 
                                                         yOffset + shiftXY.yS) ;
            writePixel(sourceCanvas, xOffset + x , yOffset + y, sourceColor );
        }
     }
 };

 // sourceColor represents the color within a 32 bits integer (r,g,b,a * 8 bits).

ここにすべてを書くのは長すぎますが、

-- pixelShift ループ内では、ソース キャンバスを処理するのではなく、32 ビットのパフォーマンス配列を処理する必要があります。

-- シフト キャンバスは Int8Array 配列に 1 回変換し、これとして格納する必要があります。
この配列サイズは shiftWidth * shiftHeight です。
奇数インデックスには x シフトが含まれ、偶数インデックスには y シフトが含まれます。
配列は前処理されており、シフト値 - 128 が含まれています
。この shiftArray の場合:

shiftX (x,y) = shiftArray [ 2 * (x + y * shiftWidth)     ] ;                                               
shiftY (x,y) = shiftArray [ 2 * (x + y * shiftWidth) + 1 ] ;  

-- したがって、pixelShift は次のようになります。

var pixelShift = function (sourceCanvas, 
                               shiftArray, shiftWidth, shiftHeight, xOffset, yOffset) {  
          [ Get a 32 bit performance array out of the canvas's target area ]  
          [ process this array using the shiftArray ]  
          [ write back the processed array onto the canvas's target area ]  
 }

-- また、コア ループは直線的に処理できます。

        var areaSize = shiftWidth * shiftHeight ;
        for ( pixelIndex=0 ; pixelIndex < areaSize ; pixelIndex++ ) {
            var linearShift = shiftArray [ 2*pixelIndex ] 
                                       + shiftWidth * shiftArray [ 2*pixelIndex + 1 ]  ;
            targetAreaArray [ pixelIndex ] = targetAreaArray [ pixelIndex + linearShift ] ;
            }

-- Rq : [0, areaSize[.

-- 今では、これ以上速くなることはできないと思います。
パフォーマンスのボトルネックは、ターゲット領域を取得/配置するために必要な getImageData と putImageData になりますが、私の知る限り、キャンバスでバイナリ ビューを取得する方法は、これら 2 つの遅い関数よりも他にありません。

于 2013-02-05T13:25:15.437 に答える