0

私はjavascriptソフトウェアレンダラーを実装しています(学術目的で)。3Dオブジェクトを三角形として表現し、3D空間から2D空間へのパースペクティブプロジェクションを処理します。

これまで、 画面上の頂点と線を表すためにlineToとを使用していました。fillRectlineToはスキャンラインの三角形の塗りつぶしを行ったことさえあります。(ここでプロジェクトをチェックできます)

これまでのところ、FPSは非常に良好です。ただし、割り当ての最後の部分は、z-Buffering:Pを実装することです。私の知る限り、これを行う唯一の方法は、を使用して三角形をlineTo塗りつぶすのをやめ、1pxの線の配列または1pxの正方形の配列のいずれかで三角形を塗りつぶすことです。(各「ピクセル」を描画する前に、深度バッファーをチェックして、実際に描画する必要があるかどうかを確認する必要があるためです。)

問題は、三角形を小さな長方形や線で塗りつぶすのが遅いことです。すべてを2FPSまで取得します。だから私の質問は、小さな線の代わりに1つのピクセルを描く方法はありますか(より速いかもしれません)?

あるいは、物事をスピードアップするために他に何ができますか?私の目標は、原理をデモするのに十分な速さで回転させることです。(6-10fpsで十分です)

乾杯。

[編集]答えを待つ間、三角形の塗りつぶし機能を変更して、1pxではなく4pxサイズの「ピクセル」を描画します。しかし、それはギザギザに見えます...

4

1 に答える 1

2

これをチェックしてください:http://jsfiddle.net/ZXjAM/2/

// points 0,1,2,3 front face
var fAvgZ = (cube.processPoints[0].colorZ + 
    cube.processPoints[1].colorZ + 
    cube.processPoints[2].colorZ + 
    cube.processPoints[3].colorZ) / 4 / 20;

// points 0,2,4,6 top
var tAvgZ = (cube.processPoints[0].colorZ + 
    cube.processPoints[2].colorZ + 
    cube.processPoints[4].colorZ + 
    cube.processPoints[6].colorZ) / 4 / 20;

// points 4,5,6,7 rear
var reAvgZ = (cube.processPoints[4].colorZ + 
    cube.processPoints[5].colorZ + 
    cube.processPoints[6].colorZ + 
    cube.processPoints[7].colorZ) / 4 / 20;

// points 1,3,5,7 bottom
var bAvgZ = (cube.processPoints[1].colorZ + 
    cube.processPoints[3].colorZ + 
    cube.processPoints[5].colorZ + 
    cube.processPoints[7].colorZ) / 4 / 20;

// points 2,3,6,7 right side
var rAvgZ = (cube.processPoints[2].colorZ + 
    cube.processPoints[3].colorZ + 
    cube.processPoints[6].colorZ + 
    cube.processPoints[7].colorZ) / 4 / 20;

// points 0,1,4,5 left side
var lAvgZ = (cube.processPoints[0].colorZ + 
    cube.processPoints[1].colorZ + 
    cube.processPoints[4].colorZ + 
    cube.processPoints[5].colorZ) / 4 / 20;

var layers = [{key:0, val:fAvgZ},
          {key:1, val:fAvgZ},
          {key:2, val:tAvgZ},
          {key:3, val:tAvgZ},
          {key:4, val:reAvgZ},
          {key:5, val:reAvgZ},
          {key:6, val:bAvgZ},
          {key:7, val:bAvgZ},
          {key:8, val:rAvgZ},
          {key:9, val:rAvgZ},
          {key:10, val:lAvgZ},
          {key:11, val:lAvgZ}];

var outLay = layers.sort(function(a,b){
    return (a.val - b.val);
});

for(var i = 0; i < outLay.length; i++)
{
    var k = outLay[i].key;
    ...
}

これは、ポイント値を平均化/ソートするための最も効率的な方法ではありません。キューブの既存のプロパティを使用して、より少ないコード行で実行できる可能性がありますが、基本的な概念は同じです。

私は平均z-indexを見つけ、それを使用して階層化順序を想定しています。明らかに、これはこれまですべてに機能するわけではありませんが、単純な多面体の場合はそれで十分です。

これは次のように簡略化できます。

var layers = [];
for (var i = 0; i < cube.sides.length; i++){
    var side = cube.sides[i];
    var avg = (cube.processPoints[side.a].colorZ + 
               cube.processPoints[side.b].colorZ + 
               cube.processPoints[side.c].colorZ) / 3 / 20;                   
    layers.push({key:i, val:avg});
}

var outLay = layers.sort(function(a,b){
    return (a.val - b.val);
});

迅速な注文の問題があるフリンジケースがいくつかあるようです。

これはより正確なようです:http://jsfiddle.net/ZXjAM/4/

var layers = [];
for (var i = 0; i < 12; ++i){
    var side1 = cube.sides[i];
    var side2 = cube.sides[++i];
    var avg = (cube.processPoints[side1.a].colorZ + 
               cube.processPoints[side1.b].colorZ + 
               cube.processPoints[side1.c].colorZ + 
               cube.processPoints[side2.a].colorZ + 
               cube.processPoints[side2.b].colorZ + 
               cube.processPoints[side2.c].colorZ) / 6;                   
    layers.push({key:i-1, val:avg});
    layers.push({key:i, val:avg});
}

var outLay = layers.sort(function(a,b){
    return (a.val - b.val);
});
于 2012-10-01T19:00:17.810 に答える