4 votes

Three.js - geometry.faceVertexUvs[0][0][index] n'est pas la même que geometry.vertices[index]

Autant que je le comprends, vous pouvez accéder aux coordonnées uv ("texels") de chaque sommet d'un maillage en utilisant :

geometry.faceVertexUvs[ materialIndex ][ faceIndex ][ vertexIndex ]

Ce que je trouve difficile, c'est que l'index du vertexIndex semble suivre un ordre de mappage différent de

geometry.vertices[ vertexIndex ]

J'ai créé un exemple démontrant ce problème : http://andrewray.me/stuff/test-uv2.html

Source : http://andrewray.me/stuff/uv2.js

Le code ci-dessus fait ce qui suit :

  • Crée un plan

  • Dessine une sphère à l'emplacement du sommet du plan d'index 1 en utilisant une fonction utilitaire dot :

    dot( floor.localToWorld( floor.geometry.vertices[1].clone() ) );

  • Modifie le texel à faceVertexUvs[0][0][1] pour que nous puissions voir où se trouve le texel 1

    floor.geometry.faceVertexUvs[0][0][1].add( new THREE.Vector2( 0.4, 0 ) );

Vous pouvez voir sur la page d'exemple que la sphère est dessinée en haut à droite du plan (emplacement du sommet 1), tandis que le texel modifié se trouve en bas à gauche du plan. Les indices des sommets ne correspondent pas ! S'agit-il d'un bug de three.js, ou est-ce que je manque quelque chose à propos des texels ?

J'ai constaté que les sommets semblent se mapper comme suit :

index du texel | index du sommet
0              | 3
1              | 1
2              | 0
3              | 2

Cependant, je constate d'autres comportements inattendus en essayant d'accomplir une tâche de mappage uv connexe, donc je ne sais pas si le mappage est la source de mon erreur.

4voto

Andy Ray Points 4600

Je ne sais pas s'il y a une meilleure manière, mais le mapping semble fonctionner comme suit :

geometry.faceVertexUvs[ 0 ][ faceIndex ][ vertexIndex ]

vertexIndex correspond au l'index du sommet du face, pas du tableau de sommets de la géométrie. Présenté comme un nombre de 0 à 3 (pour un quad), le face définit en réalité les valeurs comme a-d (de docs de Face4) :

Face4( a, b, c, d ... )

geometry.faces[0] // en supposant que faceIndex est 0
THREE.Face4 {a: 0, b: 2, c: 3, d: 1, normal: THREE.Vector3…}

Regardez, voici notre mapping!

Donc, pour faire le mapping entre eux, nous devons trouver le face à cet index, et mapper 0 vers a, 1 vers b, etc., puis chercher cela dans le tableau de geometry.vertices. Voici une façon simple mais fonctionnelle :

geometry.vertices[
    geometry.faces[faceIndex][ String.fromCharCode(97 + vertexIndex) ]
];

Où vertexIndex est celui fourni par faceVertexUvs[0][faceIndex][vertexIndex]. La fonction fromCharCode mappe a vers 0 et ainsi de suite. Maintenant nous avons le sommet (et sa position) pour chaque texel uv ! Hourra!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X