Pergunta

Eu sou a implementação de um javascript software de composição (para fins acadêmicos).Trata representando um objeto 3d como triângulos, e lida com Projeção em Perspectiva do espaço 3d para o 2d espaço.

Até agora, eu usei o lineTo e fillRect para representar os vértices e as linhas na tela.Eu mesmo usado lineTo para fazer a Varredura de Linha do triângulo de enchimento.(você pode conferir o projeto aqui)

Até agora, o FPS tem sido muito bom.Mas a última parte do trabalho é implementar z-Buffering :P.Para meu conhecimento, a única maneira de fazer isso é parar de encher meu triângulos usando lineTo e preenchê-los com uma matriz de 1px linhas ou uma matriz de 1px quadrados.(porque antes de eu desenhar cada "pixel", eu tenho que verificar o buffer de profundidade e ver se eu realmente desenhá-lo ou não.)

O problema é que, enchimento de triângulos com pequenos retângulos ou linhas é mais LENTA.Fica tudo para 2FPS.Então, minha pergunta é, existe algum método para desenhar um pixel em vez de uma pequena linha (que pode ser mais rápido)?

Como alternativa, o que mais posso fazer para acelerar as coisas?Meu objetivo é ter que girar rápido o suficiente para demonstrar o princípio.(6-10fps seria o suficiente)

Cheers.

[EDITAR] Enquanto espero por uma resposta, eu vou prosseguir para modificar a minha triângulo preenchimento de funções para desenhar 4px de tamanho "pixels" em vez de 1.Mas que vai olhar jaggedy...

Foi útil?

Solução

Confira: 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;
    ...
}

Este é, de maneira nenhuma, a forma mais eficiente de média/classificar os valores de ponto, e ele provavelmente pode ser feito com menos linhas de código usando o cubo pré-existente propriedades, mas o conceito básico permanece o mesmo.

Eu estou achando a média de z-index e usar isso para assumir a ordem das camadas.Obviamente, isto não funciona para tudo, sempre, mas para simples poliedros, ele deve ser suficiente.

Isso pode ser simplificado para:

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);
});

Não me parecem ser alguns franja casos onde não há uma ordenação rápida-problema.

Este parece ser mais precisa: 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);
});
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top