0

我正在实现一个 javascript 软件渲染器(用于学术目的)。它处理将 3d 对象表示为三角形,并处理从 3d 空间到 2d 空间的透视投影。

到目前为止,我使用 lineToandfillRect来表示屏幕上的顶点和线条。我什lineTo至曾经做过扫描线三角形填充。(你可以在这里查看项目)

到目前为止,FPS已经相当不错了。但任务的最后一部分是实现 z-Buffering :P。据我所知,这样做的唯一方法是停止使用填充我的三角形lineTo,并用 1px 线条数组或 1px 正方形数组填充它们。(因为在我绘制每个“像素”之前,我必须检查深度缓冲区,看看我是否应该实际绘制它。)

问题是,用小矩形或线条填充三角形很慢。将所有内容降至 2FPS。所以我的问题是,有什么方法可以绘制一个像素而不是一条细线(可能更快)?

或者,我还能做些什么来加快速度?我的目标是让它旋转得足够快以演示原理。(6-10fps就足够了)

干杯。

[编辑] 在等待答案的同时,我将继续修改我的三角形填充函数以绘制 4px 大小的“像素”而不是 1px。但这会看起来参差不齐...

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 回答