J'ai besoin de décaler tous les triangles (bleus), chacun indépendamment des autres, en utilisant le vertex-shader. Afin de manipuler le triangle dans son ensemble, j'ai créé des attributs personnalisés (vec3) pour chaque sommet (rouge) représentant les sommets voisins gauche (violet) et droit (vert). De cela, je dois dériver le point orange, équidistant (dans l'espace d'écran ) des deux bords adjacents. Avec trois de ces points orange dérivés de chaque triangle, le triangle traité (orange) est transmis au shader de fragment.
Idéalement, le triangle sera éliminé (comme dans le dos / non rendu) si les décalages annulent tout espace disponible dans le triangle, comme dans le deuxième triangle de la deuxième image.
J'utilise THREE.BufferGeometry () comme structure de données.
Voici une capture d'écran de l'effet que je vise:
Réponses:
Étant donné le triangle ▲ ABC, nous divisons l'angle ∠BAC avec la droite AD, dérivé du théorème de l' angle bissecteur :
BA / BD = CA / CD Le point E représente notre position raffinée objective sur le triangle incrusté résultant souhaité. Comme il repose sur la bissectrice d'angle AD, il est équidistant des côtés BA & CA, formant des triangles rectangles identiques ▲ AFE & ▲ AGE. Nous pouvons maintenant utiliser Sine for Right Triangles pour trouver la longueur de AE:
AE = EG / Sin (∠EAG)
C'est tout le calcul dont nous avons besoin, alors préparons du GLSL!
Nous commençons avec tous les attributs typiques: les matrices de position, normale et de transformation, mais comme le vertex shader ne fonctionne que sur un seul sommet, nous devons ajouter les sommets voisins comme attributs supplémentaires. De cette façon, chaque sommet trouvera son propre "point E", créant le triangle incrusté résultant. (Remarque: je ne les appelle pas "B" et "C" ici, car ils ne sont pas encore dans l'espace écran .)
En parlant d'espace d'écran, j'inclus également le rapport d'aspect de l'affichage (et en le rendant uniforme, au cas où la fenêtre serait redimensionnée.)
Après avoir préparé différentes normales pour le fragment shader et transformé le visage en espace de détourage, nous pouvons passer à l'application des mathématiques ci-dessus:
Ce code nous donne les résultats ci-dessous.
Remarque, il y a quelques cas de bord liés à des triangles presque triés sur la face arrière qui sont retournés par ce processus, et j'ai commencé à traiter cela dans le code, mais j'ai décidé de simplement éviter ces cas pour l'instant. Je vais peut-être y revenir lorsque j'aurai terminé ce projet.
la source
Ceci peut être réalisé sans fonctions trigonométriques en réduisant l' échelle du triangle.
incircle()
calcule le cercle du triangle formé par les sommetsA,B,C
, il renvoie le centre et le rayon commevec4
. Les sommetsX=A,B,C
sont ensuite déplacés vers l'intérieur par la fraction de leur distance au centre incircle (Q-X
) qui est égal au rapport de la marge souhaitée au rayon incircle (m/Q.w
).la source