website logo
Auteur
avatar
Crisot

Forum » » Création-Développement » » Oui on peut faire du bump mapping avec Warp3D/Os4


Posté : 25-11-2012 20:56 icone du post

En fait c'est assez compliqué, il faut créer un repère pour chaque polygone. On l'appelle le repère Tangent.

Exemple tout simple. Tu es face à un mur, ton R sert de bump horizontal, et ton G de bump vertical. Maintenant imagine que, sans bouger ta camera ni ta light, tu réutilises ce mur en le tournant de 90? autour de l'axe Z, ou tout bêtement que tu le texture dans l'autre sens: Il est toujours face à toi, sauf que cette fois ci, ton R sert de bump vertical, et ton G sert de bump horizontal. D'où la création d'un repère "tangent" pour chaque polygone, basé non pas sur la géométrie de l'objet mais sur les UV du polygone.

Bref, après 2 jours sur google "repère tangent normal map", un pote m'a dépanné en me filant son code. Résultat:

6_n.jpg>

Pour les matrices, rien de bien compliqué. Copier/coller brut... (repère main droite: X à droite, Y en haut, Z vers l'utilisateur).

Entité:

matrix[0][0]=1; matrix[0][1]=0; matrix[0][2]=0; matrix[0][3]=0;
matrix[1][0]=0; matrix[1][1]=1; matrix[1][2]=0; matrix[1][3]=0;
matrix[2][0]=0; matrix[2][1]=0; matrix[2][2]=1; matrix[2][3]=0;
matrix[3][0]=0; matrix[3][1]=0; matrix[3][2]=0; matrix[3][3]=1;

Rotation axe X:

matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; matrixB[0][3]=0;
matrixB[1][0]=0; matrixB[1][1]=cos(ang); matrixB[1][2]=-sin(ang); matrixB[1][3]=0;
matrixB[2][0]=0; matrixB[2][1]=sin(ang); matrixB[2][2]=cos(ang); matrixB[2][3]=0;
matrixB[3][0]=0; matrixB[3][1]=0; matrixB[3][2]=0; matrixB[3][3]=1;

Rotation axe Y:

matrixB[0][0]=cos(ang); matrixB[0][1]=0; matrixB[0][2]=sin(ang); matrixB[0][3]=0;
matrixB[1][0]=0; matrixB[1][1]=1; matrixB[1][2]=0; matrixB[1][3]=0;
matrixB[2][0]=-sin(ang); matrixB[2][1]=0; matrixB[2][2]=cos(ang); matrixB[2][3]=0;
matrixB[3][0]=0; matrixB[3][1]=0; matrixB[3][2]=0; matrixB[3][3]=1;

Rotation axe Z:

matrixB[0][0]=cos(ang); matrixB[0][1]=-sin(ang); matrixB[0][2]=0; matrixB[0][3]=0;
matrixB[1][0]=sin(ang); matrixB[1][1]=cos(ang); matrixB[1][2]=0; matrixB[1][3]=0;
matrixB[2][0]=0; matrixB[2][1]=0; matrixB[2][2]=1; matrixB[2][3]=0;
matrixB[3][0]=0; matrixB[3][1]=0; matrixB[3][2]=0; matrixB[3][3]=1;

Translation:

matrixB[0][0]=1; matrixB[0][1]=0; matrixB[0][2]=0; matrixB[0][3]=x;
matrixB[1][0]=0; matrixB[1][1]=1; matrixB[1][2]=0; matrixB[1][3]=y;
matrixB[2][0]=0; matrixB[2][1]=0; matrixB[2][2]=1; matrixB[2][3]=z;
matrixB[3][0]=0; matrixB[3][1]=0; matrixB[3][2]=0; matrixB[3][3]=1;

Et la multiplication des matrices

void PXS_MatrixMultiply(float matrixA[4][4], float matrixB[4][4])
{
int i;
float matrixC[4];
for (i=0; i<4; i++)
{
matrixC[0] = matrixA[i][0] * matrixB[0][0] + matrixA[i][1] * matrixB[1][0] + matrixA[i][2] * matrixB[2][0] + matrixA[i][3] * matrixB[3][0];
matrixC[1] = matrixA[i][0] * matrixB[0][1] + matrixA[i][1] * matrixB[1][1] + matrixA[i][2] * matrixB[2][1] + matrixA[i][3] * matrixB[3][1];
matrixC[2] = matrixA[i][0] * matrixB[0][2] + matrixA[i][1] * matrixB[1][2] + matrixA[i][2] * matrixB[2][2] + matrixA[i][3] * matrixB[3][2];
matrixC[3] = matrixA[i][0] * matrixB[0][3] + matrixA[i][1] * matrixB[1][3] + matrixA[i][2] * matrixB[2][3] + matrixA[i][3] * matrixB[3][3];
matrixA[i][0]=matrixC[0]; matrixA[i][1]=matrixC[1]; matrixA[i][2]=matrixC[2]; matrixA[i][3]=matrixC[3];
}

J'admet que ma multplication est très crade. Tu donnes une matrice A en B en entrée, la A est écrasée en étant multipliée par la B... Faudra que je fasse un truc plus propre à l'occase...

Attention à l'ordre de multiplication de 2 matrices. Si tu as une matrice A de translation et une matrice B de rotation et que tu fais A*B, tu va avoir l'objet translaté PUIS tourné. Si tu fais B*A, l'objet sera tourné PUIS translaté (à moins que ce ne soit l'inverse).
--
AmigaOne X1000 - 2 Go DDR2 - Sapphire R9 280x Toxic - Crucial MX200 500 Go - Alim/Cooling BeQuiet

Cet article provient de Le site des utilisateurs francophones actuels et futurs d'AmigaOS 4.x
https://amiga-ng.org/viewtopic.php?topic=1414&forum=14