Qu'est-ce qui fait qu'une surface chevauche une autre exactement?

10

Je ne peux pas vraiment comprendre ce qui fait qu'une surface chevauche une autre. Dans un moteur 3D que je crée, ma technique échoue dans les cas marginaux.

Ma méthode consiste à trier les surfaces à peindre du plus éloigné au plus proche. Pour déterminer la proximité, je compare les valeurs moyennes de z. Parfois, cependant, une surface qui se chevauche a une valeur z moyenne plus élevée que celle qu'elle chevauche. Ainsi, la surface la plus éloignée est peinte sur la plus proche - ce qui entraîne un rendu bizarre comme celui-ci:

Grand carré violet avec une section de rouge sur le côté

Ce que l'on est censé voir, c'est la surface avant violette du cube uniquement, tandis que la surface latérale rouge est peinte sur celle violette. La valeur z moyenne de la surface violette est plus élevée, et donc plus éloignée. Je doute donc que cette technique soit correcte.

Ce que j'ai également essayé, c'est d'obtenir la distance entre la caméra (c'est-à-dire l'origine) et la surface, mais j'avais besoin d'un point. J'ai choisi le milieu de chaque surface mais cela ne semble pas toujours fonctionner car toutes les surfaces ne sont pas aussi grandes les unes que les autres.

Par conséquent, quel est un moyen fiable pour déterminer l'ordre de proximité des surfaces vers l'origine?

pimvdb
la source

Réponses:

11

Vous semblez essayer d'implémenter l' algorithme des peintres . Je suppose que vous essayez d'écrire un rasteriser à partir de zéro comme exercice d'apprentissage, car la plupart des matériels 3D modernes utilisent ce que Bart a mentionné (le tampon Z / Depth). Pour que l'algorithme des peintres fonctionne dans tous les cas, vous devez être prêt à subdiviser les surfaces au fur et à mesure qu'elles sont rendues pour résoudre des scénarios possibles (tels que le problème de chevauchement des polygones montré sur la page Wikipedia).

En effectuant le rendu du plus éloigné au plus proche, vous passez également du temps à rendre des pixels qui seront éventuellement occultés par d'autres polygones, ce qui, lorsque vous commencez à mettre des textures et des shaders complexes sur les polygones, gaspille de précieux cycles. C'est la raison pour laquelle le matériel moderne préfère que vous effectuiez un rendu d'avant en arrière, en utilisant le tampon de profondeur pour déterminer si le pixel à rendre est plus éloigné que celui à l'écran (et peut donc être supprimé).

Même avec la plupart des matériels d'accélération modernes, vous devrez toujours trier et restituer d'arrière en avant tous les polygones semi-transparents, le rendu uniquement une fois que tous les polygones opaques auront été rendus.

Roger Perkins
la source
Vous avez raison de dire que je crée un simple rendu. Le fait est que je n'utilise aucune bibliothèque 3D. Je fais moi-même tous les calculs de projection, puis je dessine les lignes à l'aide d'une bibliothèque de dessins 2D. Ce n'est pas le plus rapide et je ne fais rien par pixel. J'ai juste 4 points de chaque surface et remplis la forme rectangulaire d'une couleur. Puisque je dessine une surface complète à un moment donné, ai-je raison de dire que je dois dessiner vers l'arrière?
pimvdb
Cela ressemble à beaucoup de plaisir et à une excellente façon d'apprendre. L'arrière vers l'avant est votre seul moyen si vous faites cela sans aucune forme de tampon de profondeur. Je pense que vous allez devoir travailler sur toutes les coordonnées d'écran de vos polygones, puis vérifier tout chevauchement. Là où ils se chevauchent en profondeur, vous devrez potentiellement découper les polygones pour le rendu, afin que vous puissiez réellement résoudre le tri correctement. Vous voudrez peut-être également examiner la suppression de face arrière comme un moyen de supprimer les polygones qui ne devraient pas nécessairement être visibles
Roger Perkins
Roger Perkins a raison. Vous ne pourrez pas obtenir le z-sort correct de cette façon (ce qui signifie que vous aurez toujours des cas de bord), sauf si vous coupez les polygones. Cela peut cependant devenir assez lent.
bummzack
Je l'ai fait fonctionner! Ce que j'ai fait était une combinaison de tri et de tri de la face arrière: dans un cube solide, certaines faces ne sont pas visibles tandis que d'autres le sont (max 3). J'ai donc d'abord peint les parties non visibles et les parties visibles par-dessus. Cela fonctionne comme un charme, si je supprime un ou plusieurs côtés, ils se chevauchent mais sont toujours dessinés dans le bon ordre. Merci!
pimvdb
1
Cela ne fonctionnera que pour les formes convexes simples, comme les cubes. Je suis heureux que cela fonctionne actuellement pour vous, mais ce n'est pas une solution générale.
Richard Fabian
3

Ce que vous avez, c'est un problème de visibilité . Une solution utilise un z-buffer .

Bart van Heukelom
la source
Merci, mais la mise en mémoire tampon z nécessite un rendu par pixel si je ne me trompe pas. Je ne fais pas cela - je dessine des lignes droites entre les points projetés du cube. La mise en mémoire tampon z est-elle toujours possible?
pimvdb
Même si vous dessinez des lignes droites, à un moment donné avant que l'image atteigne l'écran (ou le fichier bitmap), elle sera au format pixel.
Bart van Heukelom
C'est correct, mais ma bibliothèque de dessins est trop lente pour effectuer un rendu pixel à 20 ips. Merci quand même.
pimvdb
2

Le tri des faces selon leur valeur z moyenne ne fonctionne pas, car la valeur z moyenne ne fournit aucune information sur la valeur z réelle des sommets ou même des pixels de surface.

Exemple (avertissement, art ASCII à venir):

          /
         /
cam     /
-->    / 
      /
     /--       <--B
    /
    ^--A

Il y a deux faces A et B. Du point de vue de la caméra, A est devant B. Pourtant, la valeur z moyenne de B est plus petite. Regardons les autres valeurs z:

  • la valeur z minimale de A est 4
  • la valeur z maximale de A est 11
  • par conséquent, la valeur z moyenne de A est de 7,5
  • la valeur z minimale de B est 6
  • la valeur z maximale de B est 8
  • donc la valeur z moyenne de B est 7

Vous pouvez essayer de les trier par leurs valeurs z minimales mais il y a des cas où cela ne fonctionnera pas trop. Il n'y a tout simplement aucun moyen de trier correctement les faces arbitraires en utilisant une seule valeur z.

Dans l'algorithme de Newell http://en.wikipedia.org/wiki/Newell's_algorithm ce que vous faites est de trier les plages min / max des valeurs z. Si les plages de deux faces ne se chevauchent pas, vous pouvez savoir avec certitude laquelle est en face. S'ils le font, parfois vous devez absolument diviser les visages. Parfois, il suffira de suivre tous les sommets pour l'occlusion ou une autre technique.

Jonas Bötel
la source
Ce diagramme est une vue de dessus de ce que j'allais deviner se passe dans sa capture d'écran.
jhocking
1

C'est bien que vous appreniez le rendu en faisant. Gloire. Dans ce cas, il n'y a pas de solution "d'algorithme de peintre", au lieu d'essayer de le réparer par tri, sur la PS1, nous essayions juste de garder les polygones autour de la même taille lorsqu'ils étaient côte à côte (ce que vous faites comme autant que je sache), et la suppression de face arrière (ce que vous ne faites pas)

L'abattage de la face arrière vérifie la normale de la surface dans l'espace d'écran pour sa direction (obtenez simplement le signe de l'élément de profondeur de l'espace d'écran transformé normal (dans notre cas, c'était le z de la normale), ou le produit croisé de deux vecteurs de la triangle ie croix (v1-v0, v2-v0))

Si vous implémentez l'abattage de face arrière, vous réduisez également la quantité de pixellisation que vous faites .. double gain.

Richard Fabian
la source
Merci pour votre réponse. J'ai lu sur l'abattage de face arrière, mais le fait est que j'aimerais pouvoir retirer un côté. Avec un cube solide, cela pourrait très bien fonctionner, mais si je retire un côté, il y a de l'occulision - je dois donc les trier, je suppose. Quoi qu'il en soit, j'ai eu l'idée de tirer un rayon de l'origine au milieu d'une surface. Si ce rayon traverse une autre surface par la suite, alors la première surface chevauche la seconde. Pourriez-vous me dire si cette idée est correcte? Merci!
pimvdb
Bien que votre idée fonctionne pour votre cas d'exemple, il existe de nombreux autres cas où cela ne fonctionnera pas. Par exemple, la même scène que vous avez là-bas, mais avec la caméra inclinée de sorte que le centre du quadrillage de rendu incorrect ne se chevauche pas. Je pense que vous allez devoir tesseler vos primitives en morceaux plus petits.
Richard Fabian