Comment dois-je gérer les sommets d’écrêtage plus proches de l’œil que le plan d’écrêtage proche?

13

Je roule mon propre moteur 3D, en JavaScript, et n'utilise que du dessin sur toile, pas de WebGL. Ceci est un autre clone de Minecraft; J'adore les boîtes, ne me jugez pas.

Jusqu'à présent, tout fonctionne à merveille, sauf une chose: en 3D, lorsque certains sommets passent derrière le plan de détourage proche, leur projection sur l'écran est étrange (en supposant que d'autres sommets utilisés pour tracer un plan soient devant).

J'ai essayé d'écraser ces points mais je peux ensuite voir à travers les surfaces qui utilisent ces sommets. Dans WebGL / OpenGL, la carte graphique prend en charge ces points et le plan est rendu correctement, mais je n'ai pas accès au matériel, je dois donc le coder moi-même.

Je ne sais pas trop quoi en penser, actuellement la dernière chose qui m'est venue à l'esprit est d'inverser la projection des points derrière le plan de détourage proche du joueur, ce qui semble logique car je dois projeter un point sur un écran qui se trouve devant du sommet.

Voici mes pensées:

entrez la description de l'image ici

Voici quelques images pour illustrer ce qui se passe:

entrez la description de l'image ici

De loin, la boîte bleue se rend parfaitement bien.

entrez la description de l'image ici

Lorsque certains des sommets passent derrière le plan de détourage proche du lecteur, je fais une projection inverse, mais cela ne semble pas correct:

focalLength *= -1;
2d.x = x*focalLength/z;
2d.y = y*focalLength/z;

Notez que la case grise derrière est complètement supprimée car tous les sommets utilisés pour dessiner ses faces sont derrière le joueur.

entrez la description de l'image ici

C'est ce qui se produit lorsque vous regardez vers le haut ou vers le bas.

Je ne sais pas quoi faire des calculs derrière cela, j'espère que quelqu'un a déjà rencontré le même problème et peut m'aider.

Solénoïde
la source
1
Si les points sont plus proches de l'œil que le plan de clip proche, ils doivent être coupés - et cela pourrait en effet vous permettre de voir "à travers" un objet. C'est le comportement typique; la collision empêche normalement cet artefact visuel particulier. Est-ce que c'était la seule chose qui clochait avec votre solution de détourage?
@JoshPetrie: Je comprends que les points doivent être coupés, mais si je le fais, tout le carré disparaîtra car un ou deux des sommets par lesquels la routine de dessin doit passer sont manquants (en 2d) et le joueur pourra voir à travers cette place. Je voudrais qu'ils soient "à l'extérieur" de la toile (sur la projection) pour que le carré puisse toujours être dessiné. Je ne sais pas si je suis assez clair.
Solénoïde
Vous - je veux dire , c'est un comportement normal et que vous voulez éviter que cela se produise en empêchant le joueur de faire que près d'un des cubes. Si vous vouliez vraiment faire cela, vous devriez couper mais reconstruire les triangles (éventuellement). Cela aura toujours l'air inhabituel, surtout si vous avez des textures. Si ce que je dis n'a pas de sens, vous pouvez nous rejoindre dans le chat afin de ne pas créer de fil de commentaires vraiment bavard.
Ce que vous dites est logique, la reconstruction prend trop de temps, donc ce n'est pas la solution. J'espérais qu'il y avait un moyen de dessiner encore ce sommet sur le plan 2D qui était derrière le joueur pour que la lineTo(x,y)fonction puisse toujours être appelée, seulement je ne sais pas comment elle se comporte ... c'est une dimension bizarre, je suis d'accord.
Solénoïde

Réponses:

1

Le plan de détourage proche a pour but d'être un plan de détourage . Les triangles qui sont à l'extérieur d'un plan de détourage sont coupés : coupés en morceaux de sorte que chaque morceau restant se trouve dans la zone de coupure.

Vous pouvez essayer d'ignorer le clip proche si vous le souhaitez. En effet, OpenGL et D3D ont des moyens de désactiver complètement l'écrêtage près du plan (bien que le tampon de profondeur ait toujours une valeur proche minimale). Le problème n'est pas le clip proche.

Le problème vient des sommets qui se trouvent derrière la caméra.

Vous ne pouvez pas rendre des triangles situés derrière la caméra. Pas avec une projection en perspective. De tels triangles n'ont pas de sens dans les calculs mathématiques derrière les projections en perspective. De plus, ils sont également en dehors du tronc.

La désactivation près de l'écrêtage transforme un tronc en pyramide. La raison pour laquelle la pyramide s'arrête au point est parce que les points au-dessus de la pyramide sont derrière les quatre côtés de la pyramide. Donc, tout point derrière la caméra (la pointe de la pyramide) est au-dessus, en dessous, à gauche et à droite de la zone visible de l'écran. Tout en même temps.

Comme je l'ai dit: les sommets sous une projection en perspective derrière la caméra n'ont pas de sens.

Vous devez implémenter l'écrêtage. Vous devez détecter quand un sommet d'un triangle, dans l'espace clip ( avant la division en perspective) se trouve derrière la caméra. Si c'est le cas, vous devez couper ce triangle, en ne générant que des triangles devant la caméra.

Ce n'est pas un processus simple. Cela impliquera des mathématiques qui n'ont de sens que si vous avez une compréhension complète des systèmes de coordonnées homogènes. Alternativement, vous pouvez simplement supprimer n'importe quel triangle si l'un de ses sommets se trouve derrière la caméra.

Nicol Bolas
la source
Jusqu'à présent, j'ai abattu tout le triangle, mais j'ai ensuite vu à travers l'avion (voir photos ci-dessus). J'avais vraiment besoin d'une image pour comprendre pourquoi cela n'avait pas de sens géométriquement. La seule solution consiste à calculer l'intersection plan-ligne lorsque l'un des sommets est derrière le plan de détourage et à utiliser cette intersection pour tracer la ligne à partir du sommet qui se trouve devant, malheureusement, cela coûte cher.
Solénoïde
0

Si une partie du triangle derrière le plan proche pouvait-on alors faire une vérification par pixel pour voir si la position du pixel est derrière le plan de détourage?

Vous pouvez traiter le plan proche comme n'importe quel autre plan de détourage. Par exemple, les plans de détourage sont utilisés pour des choses comme les plans d'eau (pour les réflexions et les réfractions). Je pense que ce plan d'écrêtage fonctionnerait exactement comme le plan d'écrêtage proche et se clipserait par pixel.

Je sais comment gérer les plans de détourage en HLSL avec DirectX, mais leur implémentation pourrait être propriétaire. Si vous pouviez mettre la main sur les informations pour cela, cela pourrait être utile.

De plus, voici un lien qui pourrait vous aider: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter42.html

Nic Foster
la source
Le test par pixel est extrêmement coûteux dans un langage interprété comme Javascript, je reçois maintenant des fps à peine acceptables tels quels.
Solénoïde