ソフトウェアレンダラのzバッファリングを実装するための最速の方法?
-
12-12-2019 - |
質問
JavaScriptソフトウェアレンダラを実装しています(学術目的のため)。 3Dオブジェクトを三角形として表現し、3D空間から2D空間への透視投影を処理します。
これまで、lineTo
とfillRect
を使用して画面上の頂点と行を表します。スキャンラインの三角形の充填を行うためにlineTo
を使用しました。 (プロジェクトをチェックアウトできますこちら)
問題は、小さな長方形または線を持つ三角形を充填することです。すべてを2fpsにしてください。だから私の質問は、小さな線(より速いかもしれない)の代わりに1つのピクセルを描く方法がありますか?
あるいは、物事をスピードアップするために他に何をすることができますか?私の目標は、原則をデモするのに十分な速度でスピンすることです。 (6-10fpsが十分であろう)
[編集]答えを待っている間に、私の三角形の充填関数を変更して1pxの代わりに4ピクセルサイズの「ピクセル」を描画します。しかし、それはJaggedyに見えるでしょう...
解決
これをチェックアウト: 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インデックスを見つけ、それを使用して階層化順序を想定します。明らかに、これはこれまでにすべてのためにうまくいかないが、単純な多面体のためには十分であるべきである。
これは:に簡単にできます。
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);
});
.