Comment utiliser Matrix.frustumM ?

Fermé
quent217 Messages postés 421 Date d'inscription vendredi 25 septembre 2015 Statut Membre Dernière intervention 1 mars 2024 - 24 août 2017 à 14:44
quent217 Messages postés 421 Date d'inscription vendredi 25 septembre 2015 Statut Membre Dernière intervention 1 mars 2024 - 24 août 2017 à 20:46
Bonjour,

J'essaye depuis peu de temps d'apprendre à utiliser OpenGL ES 2.0 avec Android Studio. J'ai donc lu ce tutoriel :
https://developer.android.com/training/graphics/opengl
Dans la partie "Applying Projection and Camera Views", ils utilisent la fonction Matrix.frustumM qui servira ensuite à projeter le triangle. Ce que j'aimerais comprendre c'est déjà pourquoi cela n'a aucun effet si on applique pas une caméra comme c'est expliquer dans la suite du tuto ?
Ensuite j'aimerais comprendre ce que signifies les 6 derniers arguments (left, right, bottom, top, near et far) et plus spécifiquement near et far ?
Ce que je pense avoir compris c'est que les points (left, top, near) et (right, bottom, near) apparaitront dans les coins en haut à gauche et en bas à droite de l'écran du coup je vois à peu près ce que représente near mais je ne comprends pas du tout à quoi sert far.
Je ne comprends pas non plus pourquoi je ne peux pas afficher une forme avec une profondeur inférieur à near ou supérieur à far.
Et pour finir je ne comprends pas pourquoi je ne peux pas mettre near à 0. J'ai vu une explication avec une histoire de précision qui vaut far/near qui tend vers l'infini mais ce n'est pas très clair pour moi.

Voilà ça fais beaucoup de questions pour une simple ligne de code mais j'aime bien comprendre ce que je fais.

Je remercie d'avance toutes les personnes qui prendront le temps de me répondre.
A voir également:

2 réponses

ElementW Messages postés 4816 Date d'inscription dimanche 12 juin 2011 Statut Contributeur Dernière intervention 5 octobre 2021 1 225
Modifié le 24 août 2017 à 20:20
'lut,

Ce que j'aimerais comprendre c'est déjà pourquoi cela n'a aucun effet si on applique pas une caméra comme c'est expliquer dans la suite du tuto ?

Cela n'a aucun effet car OpenGL ne saura pas passer de 3D à 2D. Pour cause, il existe une infinité de manières de faire ça. Dans la vie de tous les jours, on voit quelque chose qui se rapproche d'une projection perspective (plus loin = plus petit). Mais il y aussi les projections orthographiques (plus loin = même taille), axonométriques (chaque axe est à un angle précis d'un autre sur la proj'), oblique, voire même perspective inverse (plus loin = plus gros).

Ensuite j'aimerais comprendre ce que signifies les 6 derniers arguments (left, right, bottom, top, near et far) et plus spécifiquement near et far ?


La définition d'une matrice de projection avec
frustumM()
,
perspectiveM()
ou
orthoM()
n'est qu'une histoire de ratios, en réalité.

top
,
left
,
right
et
bottom
servent à définir quelle forme ta projection doit prendre:

Comme il ne s'agit là que de ratios, on peut mettre n'importe quelles valeurs du moment qu'elles sont proportionnelles, ce qui explique que dans le tuto
top
et
bottom
soient fixés à
-1
et
1
respectivement, car on a déjà calculé un ratio (
float ratio
) dont on se sert pour l'axe horizontal avec
left
,
right
. Ce ratio est calculé à partir des dimensions de la surface d'affichage. Si on change ce ratio, le rendu se fera mais les objets affichés seront écrasés sur l'axe horizontal (si on diminue le ratio) ou vertical (si on l'augmente).

Maintenant, pour
near
et
far
, il faut passer à la dimension supérieure: la 3D. La matrice de projection définit en fait un volume dans lequel les coordonnées seront transformées pour être plaquées en 2D. Near et far définissent où commence et ou se finir ce volume, en distance par rapport à la caméra; visualisation avec une proj orthométrique:

Il est à noter que sur ce dessin on ne voit pas que la flèche de
far
va jusque la caméra; la "profondeur" du volume (partie visible de la flèche fuchsia) vaut en fait
far - near
.

Toute coordonnée se trouvant en dehors de ce volume n'est pas visible, ce qui confirme ton observation.

Et pour finir je ne comprends pas pourquoi je ne peux pas mettre near à 0.


near
ne peut pas valoir 0, ni
far
valoir l'infini. En effet, la position 2D d'un point 3D est calculée avec une division (bon, ok, la multiplication d'un inverse) dépendant de
near
et de
far
, ce qui fait que si
near = 0
, (de manière simplifiée) on divise tout par 0 (=l'infini), et si
far = +inf
, on divise tout par l'infini, autrement dit toutes les coordonnées valent zéro. C'est en lien avec la précision des nombres flottants car la précision n'est pas infinie, et les opérations avec de très petits ou très grands facteurs renforce cette perte de précision, par ex. mettre un
near
très petit va considérablement augmenter la marge d'erreur.
from human import idiocy
del idiocy
0
quent217 Messages postés 421 Date d'inscription vendredi 25 septembre 2015 Statut Membre Dernière intervention 1 mars 2024 344
24 août 2017 à 20:46
Merci beaucoup pour cette réponse très détaillée.
Cependant, il reste des choses que je n'ai pas totalement comprises.
Tu dis que left, right, bottom et top ne sont qu'une histoire de proportion et qu'on peut donc mettre n'importe quelle valeur mais ça va quand même influer sur les coordonnées des objets que l'on va créer par la suite non ? Par exemple si je multiplie toutes ces valeurs par 2, il faudra aussi que je multiplie toutes les coordonnées des points de mon objet par 2 pour obtenir le même rendu.
Ensuite tu dis que near et far servent à définir où commence et où fini le volume mais je ne comprends pas pour il doit absolument y avoir un début et une fin. Pourquoi je ne pourrais pas vouloir afficher tout ce qui est en face de moi sans qu'il n'y ai aucune limite ? Il doit bien y avoir une autre raison à leur existence autre que celle de nous limiter ?
Enfin pourquoi aurait-on besoins de diviser par near ou far ? Si je reprends l'exemple de la projection orthométrique il suffit en quelque sorte d'ignorer la coordonnée z et de garder les coordonnées x et y telles qu'elles sont pour projeter le point, je ne vois donc pas d'où vient la division par near ou far.
Certes, ce n'est surement pas une projection orthométrique qui est faite pas OpenGL mais en réfléchissant un peu on s’aperçoit que l'on peut faire les autres projections avec des équations mathématiques qui sont valide quelque soit la coordonnée z et qui ne font pas intervenir de division par near ou far.

Et malgré ces limitations, saurais tu m'expliquer comment font les développeurs dans la pratique pour être sûr que tous les objets dans le champs de vision soit bien affichés ?

Encore merci pour le temps que tu as pris pour me répondre avec des images :)
0