Question

J'implémente un logiciel de rendu javascript (à des fins académiques).Il gère la représentation d'un objet 3D sous forme de triangles et gère la projection en perspective de l'espace 3D à l'espace 2D.

Jusqu'à présent, j'utilisais le lineTo et fillRect pour représenter les sommets et les lignes à l'écran.J'ai même utilisé lineTo pour effectuer le remplissage du triangle Scan Line.(vous pouvez consulter le projet ici)

Jusqu'à présent, les FPS sont plutôt bons.Mais la dernière partie de la mission consiste à implémenter z-Buffering :P.A ma connaissance, la seule façon d'y parvenir est d'arrêter de remplir mes triangles en utilisant lineTo et remplissez-les soit avec un tableau de lignes de 1 px, soit avec un tableau de carrés de 1 px.(car avant de dessiner chaque "pixel", je dois vérifier le tampon de profondeur et voir si je dois réellement le dessiner ou non.)

Le problème est que remplir des triangles avec de minuscules rectangles ou lignes est LENT.Réduit tout à 2FPS.Ma question est donc la suivante : existe-t-il une méthode pour dessiner un pixel au lieu d'une petite ligne (ce qui peut être plus rapide) ?

Sinon, que puis-je faire d’autre pour accélérer les choses ?Mon objectif est de le faire tourner suffisamment vite pour démontrer le principe.(6 à 10 images par seconde suffiraient)

Acclamations.

[EDIT] Pendant que j'attends une réponse, je vais procéder à la modification de mes fonctions de remplissage de triangle pour dessiner des "pixels" de taille 4px au lieu de 1px.Mais cela aura l'air irrégulier...

Était-ce utile?

La solution

Regarde ça: 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;
    ...
}

Ce n'est en aucun cas le moyen le plus efficace de faire la moyenne/tri des valeurs de points, et cela peut probablement être fait avec moins de lignes de code en utilisant les propriétés préexistantes du cube, mais le concept de base reste le même.

Je trouve l'indice z moyen et je l'utilise pour supposer l'ordre des couches.Évidemment, cela ne fonctionnera pas pour tout, mais pour de simples polyèdres, cela devrait suffire.

Cela peut être simplifié en :

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

Il semble y avoir des cas marginaux où il y a un problème de commande rapide.

Cela semble être plus précis : 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);
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top