papydall
Nombre de messages : 7017 Age : 74 Localisation : Moknine (Tunisie) Entre la chaise et le clavier Date d'inscription : 03/03/2012
| Sujet: Le bruit de Perlin Dim 19 Fév 2023 - 0:08 | |
| Salut tout le monde! On va faire du bruit, mais pas n'importe quel bruit ! Tout d'abord, un peu de thé au riz théorie Un bon générateur de nombres aléatoires produit des nombres n'ayant pas de liens les uns avec les autres et ne laisse pas entrevoir de schéma répétitif. Le hasard peut être utile pour simuler certains phénomèmes, cependant il n'est pas nécessairement représentatif de ce qu'est la nature. Il existe un algorithme connu sous le nom de "bruit de Perlin", du nom de son inventeur Ken Perlin, qui tient compte de cette réalité. Perlin a développé la fonction de bruit alors qu'il travaillait sur le film Tron, durant les années 1980. Il devait créer des textures procédurales pour des effets générés par ordinateurs. Le Bruit de Perlin peut être utilisé pour générer des effets variés, possédant des qualités naturelles, comme les nuages, des paysages ou des textures à motifs. Assez de thé au riz, et passons à la pratique. - Code:
-
rem ============================================================================ rem Bruit de Perlin rem Par papydall rem Le 18 / 02 / 2023 rem ============================================================================ rem Le bruit de Perlin est une sorte de bruit de gradient inventé par Ken Perlin rem vers la fin du XXe siècle et encore actuellement très utilisé en infographie, rem notamment pour générer de manière procédurale des textures ou des heightmaps. rem ============================================================================ rem Le bruit de Perlin est essentiellement une cartographie pseudo-aléatoire de rem R^d dans R avec un entier d qui peut être arbitrairement grand mais qui vaut rem généralement 2, 3 ou 4. rem ============================================================================ ' Variables globales dim x,y,valeur,resolution dim gradient2(8,2) dim perm(512) rem ============================================================================ ' Table de permutation ' Le seul critère ici est que la table soit assez bien mélangée. ' En voici une toute prête
data 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225 data 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148 data 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32 data 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175 data 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122 data 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54 data 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169 data 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64 data 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212 data 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213 data 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9 data 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104 data 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241 data 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157 data 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93 data 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 rem ============================================================================
resolution = 100 : ' C'est la résolution du bruit, plus cette valeur du bruit ' sera petite, plus le zoom sera faible, et inversement picture 10 : width 10,400 : height 10,400 : 2d_target_is 10 top 10, (height_client(0) - height_client(10)) / 2 left 10,(width_client(0) - width_client(10)) / 2 caption 0,"Traitement en cours ... <ESC> pour arrêter ..."
Init_Gradient() Init_Perm() Afficher_Image() caption 0,"Terminé" end rem ============================================================================ SUB Init_Gradient() dim_local unit unit = 1/sqr(2) gradient2(0,0) = unit : gradient2(0,1) = unit gradient2(1,0) = 0-unit : gradient2(1,1) = unit gradient2(2,0) = unit : gradient2(2,1) = 0-unit gradient2(3,0) = 0-unit : gradient2(3,1) = 0-unit gradient2(4,0) = 1 : gradient2(4,1) = 0 gradient2(5,0) = -1 : gradient2(5,1) = 0 gradient2(6,0) = 0 : gradient2(6,1) = 1 gradient2(7,0) = 0 : gradient2(7,1) = -1 END_SUB rem ============================================================================ SUB Init_Perm() dim_local i,v for i = 0 to 255 : read v : perm(i) = v : perm(256+i) = v : next i END_SUB rem ============================================================================ SUB Afficher_Image() for y = 0 to height(10)-1 for x = 0 to width(10)-1 ' Transformer la valeur de bruit qui est comprise entre [-1,+1] ' en une valeur comprise entre [0,255] pour colorer en gris ' le pixel (x,y) valeur = (Perlin_Noise(x,y,resolution)+1)*0.5*255 2d_pen_color valeur,valeur,valeur : 2d_point x,y next x display if scancode = 27 then terminate next y END_SUB rem ============================================================================ ' Fonction de bruit de Perlin ' Renvoie une valeur comprise dans l'intervalle fermé [-1 , +1] FNC Perlin_Noise(x, y, resolution) dim_local x0,y0,ii,jj,gi0,gi1,gi2,gi3 dim_local tempX,tempY dim_local tmp,s,t,u,v,cx,cy,li1,li2 ' Adapter pour la résolution x = x / resolution : y = y / resolution ' On récupère les positions de la grille associée à (x,y) x0 = int(x) : y0 = int(y) ' Masquage ii = mod(x0,255) : jj = mod(y0,255) ' Pour récupérer les vecteurs gi0 = mod(perm(ii + perm(jj)),8) gi1 = mod(perm(ii + 1 + perm(jj)),8) gi2 = mod(perm(ii + perm(jj + 1)),8) gi3 = mod(perm(ii + 1 + perm(jj + 1)),8) ' Pour récupérer les vecteurs et on pondère tempX = x-x0 : tempY = y-y0 s = gradient2(gi0,0) * tempX + gradient2(gi0,1) * tempY tempX = x -(x0+1) : tempY = y-y0 t = gradient2(gi1,0) * tempX + gradient2(gi1,1) * tempY tempX = x-x0 : tempY = y-(y0+1) u = gradient2(gi2,0) * tempX + gradient2(gi2,1) * tempY tempX = x-(x0+1) : tempY = y-(y0+1) v = gradient2(gi3,0) * tempX + gradient2(gi3,1) * tempY ' Lissage tmp = x-x0 cx = 3*tmp*tmp - 2*tmp*tmp*tmp li1 = s + cx*(t-s) li2 = u + cx*(v-u) tmp = y-y0 cy = 3*tmp*tmp - 2*tmp*tmp*tmp result li1 + cy*(li2-li1) END_FNC rem ============================================================================
Maintenent un terrain généré par le bruit de Perlin. - Code:
-
rem ============================================================================ rem Bruit de Perlin rem Par papydall rem Le 18 / 02 / 2023 rem ============================================================================ rem Le bruit de Perlin est une sorte de bruit de gradient inventé par Ken Perlin rem vers la fin du XXe siècle et encore actuellement très utilisé en infographie, rem notamment pour générer de manière procédurale des textures ou des heightmaps. rem ============================================================================ rem Le bruit de Perlin est essentiellement une cartographie pseudo-aléatoire de rem R^d dans R avec un entier d qui peut être arbitrairement grand mais qui vaut rem généralement 2, 3 ou 4. rem ============================================================================ ' Variables globales dim x,y,valeur,resolution dim gradient2(8,2) dim perm(512) rem ============================================================================ ' Table de permutation ' Le seul critère ici est que la table soit assez bien mélangée. ' En voici une toute prête
data 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225 data 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148 data 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32 data 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175 data 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122 data 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54 data 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169 data 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64 data 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212 data 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213 data 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9 data 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104 data 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241 data 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157 data 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93 data 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180 rem ============================================================================ width 0,700 : height 0,600 resolution = 100/4 : ' C'est la résolution du bruit, plus cette valeur du bruit ' sera petite, plus le zoom sera faible, et inversement picture 10 : width 10,600 : height 10,500 : 2d_target_is 10 top 10, (height_client(0) - height_client(10)) / 2 left 10,(width_client(0) - width_client(10)) / 2 caption 0,"Traitement en cours ... <ESC> pour arrêter ..."
Init_Gradient() Init_Perm() ' Afficher_Image() Afficher_Terrain() caption 0,"Terminé" end rem ============================================================================ SUB Init_Gradient() dim_local unit unit = 1/sqr(2) gradient2(0,0) = unit : gradient2(0,1) = unit gradient2(1,0) = 0-unit : gradient2(1,1) = unit gradient2(2,0) = unit : gradient2(2,1) = 0-unit gradient2(3,0) = 0-unit : gradient2(3,1) = 0-unit gradient2(4,0) = 1 : gradient2(4,1) = 0 gradient2(5,0) = -1 : gradient2(5,1) = 0 gradient2(6,0) = 0 : gradient2(6,1) = 1 gradient2(7,0) = 0 : gradient2(7,1) = -1 END_SUB rem ============================================================================ SUB Init_Perm() dim_local i,v for i = 0 to 255 : read v : perm(i) = v : perm(256+i) = v : next i END_SUB rem ============================================================================ SUB Afficher_Image() for y = 0 to height(10)-1 for x = 0 to width(10)-1 ' Transformer la valeur de bruit qui est comprise entre [-1,+1] ' en une valeur comprise entre [0,255] pour colorer en gris ' le pixel (x,y) valeur = (Perlin_Noise(x,y,resolution)+1)*0.5*255 2d_pen_color valeur,valeur,valeur : 2d_point x,y next x display if scancode = 27 then terminate next y END_SUB rem ============================================================================ ' Fonction de bruit de Perlin ' Renvoie une valeur comprise dans l'intervalle fermé [-1 , +1] FNC Perlin_Noise(x, y, resolution) dim_local x0,y0,ii,jj,gi0,gi1,gi2,gi3 dim_local tempX,tempY dim_local tmp,s,t,u,v,cx,cy,li1,li2 ' Adapter pour la résolution x = x / resolution : y = y / resolution ' On récupère les positions de la grille associée à (x,y) x0 = int(x) : y0 = int(y) ' Masquage ii = mod(x0,255) : jj = mod(y0,255) ' Pour récupérer les vecteurs gi0 = mod(perm(ii + perm(jj)),8) gi1 = mod(perm(ii + 1 + perm(jj)),8) gi2 = mod(perm(ii + perm(jj + 1)),8) gi3 = mod(perm(ii + 1 + perm(jj + 1)),8) ' Pour récupérer les vecteurs et on pondère tempX = x-x0 : tempY = y-y0 s = gradient2(gi0,0) * tempX + gradient2(gi0,1) * tempY tempX = x -(x0+1) : tempY = y-y0 t = gradient2(gi1,0) * tempX + gradient2(gi1,1) * tempY tempX = x-x0 : tempY = y-(y0+1) u = gradient2(gi2,0) * tempX + gradient2(gi2,1) * tempY tempX = x-(x0+1) : tempY = y-(y0+1) v = gradient2(gi3,0) * tempX + gradient2(gi3,1) * tempY ' Lissage tmp = x-x0 cx = 3*tmp*tmp - 2*tmp*tmp*tmp li1 = s + cx*(t-s) li2 = u + cx*(v-u) tmp = y-y0 cy = 3*tmp*tmp - 2*tmp*tmp*tmp result li1 + cy*(li2-li1) END_FNC rem ============================================================================ SUB Afficher_Terrain() for y = 0 to height(10)-1 for x = 0 to width(10)-1 valeur = Perlin_Noise(x,y,resolution) : ' valeur comprise dans l'intervalle fermé [-1 , +1] if valeur < -0.05 2d_pen_color 65,105,225 : ' bleu else if valeur >= -0.05 and valeur < 0 2d_pen_color 238,214,175 : ' plage else if valeur >= 0 and valeur < 0.35 2d_pen_color 34,139,34 : ' vert else if valeur >= 0.35 and valeur < 0.65 2d_pen_color 139,137,137 : ' montagne else if valeur >= 0.65 and valeur < 1 2d_pen_color 255,250,250 : ' neige end_if end_if end_if end_if end_if 2d_point x,y next x display if scancode = 27 then terminate next y END_SUB rem ============================================================================
| |
|