» Morphing de geometries GPU1
This site relies heavily on Javascript. You should enable it if you want the full experience. Learn more.

Morphing de geometries GPU1

English | Russian | Italian | Japanese

L'approche GPU simple

Préparation des modèles

Comme le titre de cet article l'indique, cette technique est basée sur un shader/effet. Nous allons jouer avec les données géométriques (les vertex) de meshes et ainsi écrire un simple vertexshader. Quand vous voulez écrire un effet dans vvvv, il est préférable de démarrer à partir de la node Template (EX9.Effect). En raison du manque de modèles cools dans vvvv, nous allons devoir encore utiliser 2 cylindres. Préparez un patch qui ressemble à ceci:

Là encore, notez que la combinaison AspectRatio/Caméra n'est pas essentielle ici mais qu'elle permet d'améliorer l'affichage. Le modèle d'effet est vraiment basique, c'est pourquoi vous ne verrez rien d'autre qu'un cylindre blanc.

Réunir Deux Meshes en Un

On vous a promis un miracle avec cet effet, donc les performances de cette approche enterreront celles de la précédente. Alors comment allons-nous connecter 2 meshes à un effet? C'est de cela dont il sera question ici. Mais le truc est que vous ne pourrez jamais avoir plus d'un mesh connecté à un effet. Vous allez devoir bricoler l'effet en construisant votre propre mesh contenant les données géométriques de vos 2 meshes.

Le patch ci-dessus montre comment arranger les composantes de position et de normale de 2 meshes dans un seul. Apportez une attention particulière à la node VertexBuffer (EX9.Geometry Join). Vous devez la sélectionner pour déverrouiller certains pins additionnels dans l'inspecteur: alors qu'un vertexbuffer ne peut contenir qu'une seule composante nommée "position" et une composante nommée "normal", il peut en revanche contenir plusieurs composantes appelées "texture coordinate" (jusqu'à 8). Vous n'en aurez pas besoin ici. Avec l'inspecteur, on va créer 2 pins additionnels sur VertexBuffer (EX9.Geometry Join) en sélectionnant "3D TexCoords" comme valeur par défaut pour les deux premiers pins "Enable Texture Coordinate". A présent nous pouvons injecter les positions et normales de notre second modèle dans le vertexbuffer.

Qu'on injecte des données de position ou de normale dans la composante du vertexbuffer appelée "3D TexCoords" n'a pas d'importance. Ce n'est que plus tard, en écrivant le vertexshader, que le type de donnée importera pour être capable de lire des données correctes du vertexbuffer. Dans un effet les termes "labels" ou "noms" sont appelés "sémantiques".

Notez que le pin "Apply" de VertexBuffer (EX9.Geometry Join) et Mesh (EX9.Geometry Join) n'a besoin que d'un "bang" (une impulsion, pas une pipe à eau) pour valider les modifications de meshes (par exemple, si vous changez le diamètre de l'un des cylindres). Tant que vous ne cliquez pas sur "Apply" sur ces nodes, les nouvelles valeurs entrantes seront perdues!

Le Vertex Shader

La suite du tour de magie se passera dans le vertexshader de l'effet. Ouvrez le Template (EX9.Effect) par clic-droit et cliquez sur TFixedFunction dans la colonne de gauche. Etant donné qu'il n'y aura pas de version fixedfunction de notre effet de morphing, nous pouvons effacer cette technique (c'est-à-dire toutes les lignes suivantes: technique TFixedFunction, etc) et sauvegarder (Ctrl+Maj+S) le modèle sous un nouveau nom (par exemple: MonPremierMorphing.fx).

Tout d'abord nous aurons besoin d'un pin "MorphFactor" sur l'effet et 2 pins de couleur. On les crées en ajoutant les lignes:

 float MorphFactor;
 float4 Color1: COLOR;
 float4 Color2: COLOR;

Juste en dessous des lignes existantes (au sommet de l'effet):

 //transformations
 float4x4 tW: WORLD;        //la matrice de l'environnement des modèles
 float4x4 tV: VIEW;         //la matrice de vue définie via le Renderer(EX9)
 float4x4 tP: PROJECTION;
 float4x4 tWVP: WORLDVIEWPROJECTION;
 float MorphFactor;
 float4 Color1: COLOR;
 float4 Color2: COLOR;

Remarquez que notre effet dans le patch gagne 3 nouveaux pins après avoir ajoutées ces lignes.
Maintenant localisez les lignes

 vs2ps VS(
    float4 PosO  : POSITION,
    float4 TexCd : TEXCOORD0)
 {

dans l'effet. Elles indiquent la fonction du vertex shader. La ligne suivante:

 Out.Pos = mul(PosO, tWVP);

est intéressante. Elle stipule que les données de position du premier cylindre (PosO) doit être transformée par la matrice worldviewprojection (tWVP) et renvoyée en tant que résultat de l'effet (Out.Pos). C'est ici que nous allons mélanger la position entrante du premier cylindre avec celle du second cylindre.

Comment sait-on que la variable entrante PosO fait référence aux données de position du premier cylindre? Parce que. La variable est marquée avec la sémantique POSITION. Donc si nous voulons accéder à la position du second cylindre, que nous avons injecté dans le vertexbuffer en tant que "TexCoord0", nous pouvons le faire en déclarant une variable et en lui assignant la sémantique TEXCOORD0. Ce qui a déjà été fait pour nous.

 float2 TexCd : TEXCOORD0;

Puisque nous n'avons pas besoin des coordonnées de texture dans notre effet, nous pouvons renommer cette variable en "PosO2" et en faire une float4!

 float4 PosO2: TEXCOORD0;

Maintenant que nous avons accès à nos deux modèles, nous pouvons faire le morphing. Chose quelque peu compliquée à faire (mais compréhensible malgré tout) en remplaçant la ligne:

 Out.Pos = mul(PosO, tWVP);

par:

 Out.Pos = mul(MorphFactor * PosO + (1-MorphFactor) * PosO2, tWVP);

ou simplement en utilisant la fonction HLSL intrinsèque "lerp" qui fait ceci:

 Out.Pos = mul(lerp(PosO, PosO2, MorphFactor), tWVP);

Maintenant vous devriez avoir une erreur mentionnant la variable "TexCd" que nous venons de remplacer par "PosO2". Effacez la ligne:

 Out.TexCd = mul(TexCd, tTex);

A présent, l'effet devrait compiler et quand vous changez la valeur du pin "MorphFactor" dans le patch, vous devriez déjà voir ce que vous venez de terminer.

Il nous manque toujours les couleurs... Mais, pas de panique, c'est très facile. Localisez la fonction pixelshader:

 float4 PS(vs2ps In): COLOR
 {
    float4 col = tex2D(Samp, In.TexCd);
    return col;
 }

et remplacez-la par:

 float4 PS(vs2ps In): COLOR
 {
    return lerp(Color1, Color2, MorphFactor);
 }

Et voilà le travail!

Cadeau Bonux

Maintenant vous voudriez peut-être voir les modèles autrement qu'en flat shaded. Prenez un GouraudDirectional (EX9.Effect), sauvegardez-le sous un nom différent et appliquez-lui les même modifications qu'à Template (EX9.Effect). Notez qu'à côté des données de position vous devez aussi morpher les normales!

anonymous user login

Shoutbox

~2d ago

joreg: Workshop on 02 05: Intro to the Stride 3D Engine. Signup here: https://thenodeinstitute.org/courses/ss24-vvvv-intro-to-the-stride-3d-engine-in-vvvv/

~3d ago

joreg: The new vvvv Show-Off-Reel is out: https://vimeo.com/930568091

~9d ago

joreg: The summer season of vvvv workshops at The NODE Institute is out: https://thenodeinstitute.org/ss24-vvvv-intermediates/

~9d ago

domj: If you happen to be in Prague, come join us at the Schema workshop on Thursday 25.4. :) https://www.facebook.com/events/395516526614988/?ti=ls

~21d ago

joreg: Postponed: Next vvvv beginner course starting April 29: https://thenodeinstitute.org/courses/vvvv-beginner-class-summer-2024/