Libre adaptation du lexique de...
Goxel un générateur de Voxels Open Source by Guillaume Chereau qui a la particularité d'avoir un mini-langage intégré pour la génération de ses objets! (n'est pas obligatoire c'est juste une facilité! ;)
|
|
Syntaxe de Base
shape main {
cube[s 9] } |
ici le 9 indique au programme de faire le cube 9 fois plus grand (s est pour "l'échelle" (scale)). Si nous voulions une échelle différente du cube en x, y et z on aurait pu utiliser le réglage du s avec trois arguments: cube [s 3 4 5]. Comme il est commun à une seule échelle le long d'un axe unique, on peut donc utiliser sx, sy et sz.
|
shape main {
cube[s 9] cube[s 9 x 2] } |
Pour le second cube, nous utilisons deux réglages appliqués l'un après l'autre: s 9 pour l'échelle du cube, suivi par x 2 pour le déplacer à 2 fois sa taille.
Les arguments sont appliqués dans l'ordre, et sont non commutatifs, donc [s 9 x 2] est différent de [x 2 s 9], dans le premier cas, le cube est translaté par 9 voxels, dans le second cas que par 1! |
Notez la syntaxe des arguments: toutes valeurs suivant l'argument sont opérationnelles jusqu'à ce que l'opération suivante soit un argument de cette opération.
Création de Formes
// Rendre un cube avec une sphere au sommet.
shape ma_forme { cube[] sphere[z 0.5] } shape main { ma_forme[s 20] } |
Nous rendons une nouvelle forme comme nous l'avons fait pour un cube. Les arguments que nous utilisons dans l'appel sont appliqués avant que la forme soit rendue :ici nous avons rendu la nouvelle forme mise à l'échelle 20 fois. La façon de le comprendre est que l'exécution du code est lié à un contexte. Le contexte définit la position, la taille et la couleur que nous utilisons. Lorsque nous appelons une nouvelle forme, nous reproduisons la valeur du contexte actuel et appliquons les arguments avant de rendre la forme. Il n'affecte pas le reste du rendu de l'appelant.
|
Formes Récursives
Boucles
Expressions
// Idem l'exemple precedent,
//mais la sphere a une taille //aleatoire comprise //entre 4 & 16. shape main { loop 8 [rz 45] { sphere[x 20 s 10+-6] } } |
Nous pouvons utiliser des expressions mathématique pour exprimer les arguments de réglage. Les opérations de base sont +, -, *, /, et +-
Les opérateurs x +- y retournent une valeur aléatoire prise entre x - y et x + y. Cela peut être utilisé pour ajouter un peu de hasard à vos formes. |
Règles de Forme
shape ma_forme
rule 4 { sphere[] } rule 1 { cube[] } shape main { loop 8 [rz 45] { ma_forme[x 20 s 8] } } |
Il est possible de donner plusieurs Implémentations de la même forme, et laisser le programme en choisir une au hasard.
Pour ce faire, nous utilisons les rule (règles) de forme Dans cet exemple, ma_forme est la plupart du temps une Sphère, mais parfois un cube. Le "poids" donne les probabilités relatives d'utiliser une règle donnée, ici 4/5 de chance d'utiliser la première règle, et 1/5 de chance d'utiliser la seconde. |
shape main {
[antialiased 1 seed 4] test[s 16 life 40] } shape test rule 5 { cube[] test[s 0.95 z 1] } rule 1 { test[] test[rz 0+-180 rx 90] } |
Ceci peut être utilisé pour les effets de branchement:
Donc, nous voyons ici quelque chose de nouveau:
[antialiased 1 seed 4] applique un certain ajustement au contexte actuel: 1 améliore l'anti-crénelage du rendu avec l'algorithme "marching cube" et une graines de 4 mis comme semence initiale pour la fonction interne aléatoire. Dans cet exemple, nous pourrions avoir ces arguments dans l'appel du test. L'argument life (vie) : life 40 est là pour arrêter la récursivité après 40 itérations. |
Couleurs
Jusqu'à présent, tous les exemples utilisaient la couleur blanche. Voyons comment changer cela.
La couleur peut être modifiée à l'aide des trois réglages: la lumière, la teinte et la saturation, suivant le mode de couleur HSL. La teinte varie de 0 à 360, la saturation et de la lumière de 0 à 1.
La couleur blanche initiale correspond à une valeur de HSL (0, 0, 1).
Il y a trois opérations d'ajustement pour changer la couleur: hue (teinte), sat (saturation) et light (lumière). Chacun peut prendre un ou deux arguments.
hue x: ajoute la valeur x à la teinte actuelle. Si la valeur obtient plus de 360 ou est inférieure à 0 un modulo est appliqué pour le remettre dans la gamme (0, 360).
light x: x dans l'intervalle [-1 1]. Si x < 0, modifiez la valeur de la lumière x % vers 0. Si x > 0, modifiez la valeur de lumière x % vers 1.
sat x: x dans l'intervalle [-1 1]. Si x < 0, modifiez la valeur de saturation x % vers 0. Si x > 0, modifiez la valeur de saturation x % vers1.
hue x h modifie la teinte courante vers x % h.
light x t modifie la valeur de lumière vers x % t.
sat x t modifie la valeur de saturation vers x % t.
La couleur peut être modifiée à l'aide des trois réglages: la lumière, la teinte et la saturation, suivant le mode de couleur HSL. La teinte varie de 0 à 360, la saturation et de la lumière de 0 à 1.
La couleur blanche initiale correspond à une valeur de HSL (0, 0, 1).
Il y a trois opérations d'ajustement pour changer la couleur: hue (teinte), sat (saturation) et light (lumière). Chacun peut prendre un ou deux arguments.
hue x: ajoute la valeur x à la teinte actuelle. Si la valeur obtient plus de 360 ou est inférieure à 0 un modulo est appliqué pour le remettre dans la gamme (0, 360).
light x: x dans l'intervalle [-1 1]. Si x < 0, modifiez la valeur de la lumière x % vers 0. Si x > 0, modifiez la valeur de lumière x % vers 1.
sat x: x dans l'intervalle [-1 1]. Si x < 0, modifiez la valeur de saturation x % vers 0. Si x > 0, modifiez la valeur de saturation x % vers1.
hue x h modifie la teinte courante vers x % h.
light x t modifie la valeur de lumière vers x % t.
sat x t modifie la valeur de saturation vers x % t.
shape main {
[antialiased 1 sat 1 light -0.5] loop 12 [hue 30 rz 30] { sphere [s 4 x 4] } } |
Voici un petit programme d'un rendu de 12 sphères avec des valeurs de teinte différentes:
La première ligne donne au rendu un anti-crénelage de 1 et à la saturation initiale et de la lumière une valeur de 1 et 0,5.
|
Les Variables
shape main {
[hue 180 sat 0.5] loop $x = 10 [] { cube [x $x light $x / -10] } } |
Nous pouvons ajouter des variables au code. Tous les noms de variables commencent par un $, pour ne pas les confondre avec les arguments d'opérations.
La première façon d'utiliser la variable est par exemple l'expression de la boucle. |
Note : les accents ne seront pas affichés dans les commentaires du code!
// pas d'accents!
// pas d'accents!
Ses formats d'export permettent de basculer vers d'autres programmes 3D!
N'introduire dans l'éditeur que la partie anglaise!!!
// The 'main' shape is always the entry point of the program.
shape main { // Initial random seed of 2. // Remove this line to use different seed each time. [seed 2] // Improves marching cube rendering. [antialiased 1] // Render a single white voxel. cube [] // Put an other cube next to it. // 'x' applies a translation of 1 along x. // Those transformation are only applied // to this cube. cube [x 1] // Now render a bigger grey sphere. // light -0.5 move the light value to half // the current value of 1 and the target sphere [s 10 x 1 light -0.5] // We can also render cylinders: cylinder [s 10 x -1 light -0.9] // This time we use a user defined shape. // And we increase the saturation to give it a color. my_shape [z 20 light -0.5 sat 0.5] } // A user defined shape shape my_shape { // s 8 8 1 scales with different values // for each axis. // rx A applies a rotation along z of // 45 deg. // Note that the color is red, because we set the // Saturation when we called my_shape. cube [s 8 8 1 z 1 rz 45] // Loop 16 time, each time increasing the x // translation and the hue. loop 16 [x 2 hue 10] { cube [] } // The loop transformations only affect // the loop block, after it we return to // the previous context. sphere [s 6 z 1] // Let's try a recursive shape: tree [x -10 s 4] // And an other one with a bit or randomness: tree2 [x 10 s 4 rz 180 hue 180] // A shape with several rules: my_other_shape [y 10 rz 90 hue -60 s 3] } // Tree render a cylinder and then call itself. // Since we scale down the shape at each iteration // at some point it becomes too small, and is // then automatically stopped. shape tree { cylinder [] tree [z 1 s 0.99 ry -6] } shape tree2 { cylinder [] // 'A +- B' means that we use a random value in the range // A - B, A + B. this make the second spiral a bit // messy. tree2 [z 1 s 0.99 ry -6+-6] } // Here 'my_other_shape' defines several rules. //The rule used is picked randomly using the weight. shape my_other_shape // Most of the time, just keep growing in z. rule 15 { cube [] my_other_shape [z 1] } // Sometime split into two rule 1 { my_other_shape [rx 45 s 0.9] my_other_shape [rx -45 s 0.9] } // Some other times render a shpere and stop rule 0.5 { // 'hue 1 70' means that we immediatly //set the hue to 70 (yellow). sphere [s 3 hue 1 70] } |
// Le "shape main" est le point d'entrée du programme.
shape main { // Graine aléatoire donnée à 2. // Retirer cette ligne pour utiliser différente graine //à chaque fois. [seed 2] // Rendu du cube avec le mode "marching". [antialiased 1] // Rendre un cube seul blanc (un Voxel). cube [] // mettre un autre cube à côté de celui-ci. // 'x' applique une translation de 1 le long des x. //Ces transformations ne sont appliquées qu'à // à ce cube cube [x 1] // Maintenant, une plus grande sphère grise est //créée. light -0,5 déplace la valeur de la lumière à la //moitié de la valeur actuelle de 1 et de la cible. sphere [s 10 x 1 light -0.5] // Nous pouvons rendre aussi les cylindres: cylinder [s 10 x -1 light -0.9] // Cette fois, nous utilisons une forme définie // par l'utilisateur. Et nous augmentons la saturation pour lui donner une couleur. my_shape [z 20 light -0.5 sat 0.5] } // L'utilisateur définit une forme shape ma_forme { // s 8 8 1 valeurs des différentes tailles // pour chaque axe. // rx applique une rotation le long des z de 45°. // Notez que la couleur est rouge, parce que nous //définissons la Saturation en appelant ma_forme. cube [s 8 8 1 z 1 rz 45] // Boucle 16 fois, en augmentant à chaque fois //la translation des x et hue. (teinte) loop 16 [x 2 hue 10] { cube [] } // Les transformations de la boucle ne touchent // que le bloc de la boucle, après le retour au //contexte précédent. sphere [s 6 z 1] // Essayons une forme récursive: tree [x -10 s 4] // Et une autre avec un peu d'aléa : tree2 [x 10 s 4 rz 180 hue 180] // Une forme avec plusieurs règles: mon autre_forme [y 10 rz 90 hue -60 s 3] } // L'arbre fait un cylindre puis s'appelle lui-même. // Puisque nous réduisons la forme à chaque //itération à un moment donné elle devient trop //petite et s'arrête automatiquement. shape tree { cylinder [] tree [z 1 s 0.99 ry -6] } shape tree2 { cylinder [] // 'A + - B' signifie que nous utilisons une valeur aléatoire // dans la gamme A - B, A + B. // Cela rend la seconde spirale un peu désordonnée. tree2 [z 1 s 0.99 ry -6+-6] } // Ici 'mon_autre_forme' définit plusieurs règles. // La règle utilisée est choisie au hasard en utilisant le poids. shape mon_autre_forme // La plupart du temps, continue de grandir en z. rule 15 { cube [] mon_autre_forme [z 1] } // Quelques fois coupée en deux. rule 1 { mon_autre_forme [rx 45 s 0.9] mon_autre_forme [rx -45 s 0.9] } // Quelques fois s'arrête et dessine une sphère rule 0.5 { // 'hue 1 70' signifie que hue est directement mis // mis à to 70 (jaune). sphere [s 3 hue 1 70] } |