Aller au menu - Aller au contenu

Icône Les isosurfaces (1/2)

Mise à jour : 01/07/2010
Difficulté : Intermédiaire Intermédiaire Creative Commons BY-NC-SA
525 visites depuis 7 jours, dont 18 sur ce chapitre classé 218/786
Bon, ça y est, vous vous êtes reposés ? Parce que maintenant, ça devient compliqué ! :p
Nous allons voir L'OBJET LE PLUS PUISSANT de POV-Ray (rien que ça...) qui est aussi, grâce à la loi de l'équilibre universel, le PLUS COMPLIQUÉ à utiliser...
Je vous ai fait peur ? Nooon, ne partez pas !! C'est bien pire que ce que vous pensez... :diable:
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Iso-quoi ?

Qu'est-ce qu'une isosurface ?
La définition est en réalité relativement simple : imaginez une fonction qui donne à chaque point de l'espace une valeur ; puis choisissez une de ces valeurs. Tous les points dont la valeur est inférieure au seuil que vous avez choisi sont à l'intérieur de la surface, et vice-versa.
C'est bon, vous avez suivi ? Non ? :p Voici un exemple en deux dimensions, avec la fonction f(x, y) = x + y et un seuil de 9 :
Exemple d'isosurface en deux dimensions
Comme vous le voyez, l'intérieur de la surface est ici représenté en bleu.
Bien entendu, cette surface continue sur les x et y négatifs, vous l'aurez deviné ! :p

En trois dimensions, cela donne à peu près la même chose... Avec un peu d'imagination, vous devriez pouvoir vous représenter ce que cela donne. ^^

Vous voyez donc qu'avec la bonne fonction, on peut faire pas mal de choses...
Par exemple, si j'avais pris f(x, y) = x² + y², qu'est-ce que ça aurait donné ?...
Secret (cliquez pour afficher)
Un disque :p Ahhh, les maths...

Une fonction et un seuil.

Notre isosurface n'aurait donc besoin que d'une fonction et d'un seuil pour être parfaitement définie...
Ha ha :lol: , si ce n'était que ça !... Mais nous nous égarons...

Commençons par le seuil.
En principe, vous pouvez mettre n'importe quelle valeur. Cependant, pour plus de clarté, je vous conseille de TOUJOURS METTRE 0 ici (c'est d'ailleurs la valeur par défaut : facile ! :p ).
Mais ?!? Ça veut dire que je ne peux pas contrôler ma surface comme je veux ??

Non, pas du tout ! :) Cela veut juste dire qu'il va falloir adapter la fonction.
En effet, f(x, y) = 9 est strictement équivalent à f(x, y) - 9 = 0.
Donc en modifiant la fonction, on peut toujours revenir à un seuil de 0.

Ainsi, votre isosurface sera entièrement définie par votre fonction. De plus en plus simple, n'est-ce pas ?... :lol:

La fonction utilisée dans l'exemple là-haut sera donc :
Code : Autre
1
f(x, y) = x + y - 9


A partir de là, vous pouvez imaginer des fonctions toutes plus loufoques les unes que les autres...

Pour information, l'équation d'une sphère est la suivante :
Code : Autre
1
f(x, y, z) = x² + y² + z² - rayon² = 0


Des notions de mathématiques seront très utiles ici, si vous comptez réaliser des formes un peu plus complexes...

Alors ? Vous pensez avoir tout compris des isosurface ? Vous êtes enfin un génie de POV-Ray ? :-°
Que nenni ! Voyons maintenant les difficultés... :D

Le contenant et le contenu

Le problème de notre isosurface, c'est que POV-Ray n'a absolument aucune idée d'où se trouve approximativement votre surface.
En effet, il ne peut pas simplement calculer la valeur correspondant à chaque point de l'espace infini, ça ferait beaucoup. :o

On va donc commencer par le limiter : lui dire où, précisément, il va calculer. On va ainsi déclarer un contenant, dans lequel sera notre isosurface. Le résultat sera en fait l'intersection de l'isosurface globale (calculée sur tout l'espace) et du contenant. Le but est donc de faire un contenant suffisamment grand pour que notre surface soit dedans, mais suffisamment petit pour que POV-Ray ne passe pas des heures à faire des calculs pour rien...

Il y a deux types de contenant possibles : une boîte ou une sphère. Choisissez celui qui permet le mieux d'encapsuler votre surface.


Le contenant, avec la fonction de définition, sont les seuls paramètres indispensables à POV-Ray pour faire une isosurface.
Pourtant, vous le verrez bien assez vite, vous n'arriverez à rien sans utiliser quelques autres paramètres...

En réalité, le contenant n'est même pas vraiment nécessaire : la valeur par défaut est une boîte, de <-1, -1, -1> à <1, 1, 1>. Mais mieux vaut le spécifier quand même, pour la clarté, et au cas où cette valeur change.


Pour commencer, voici le code simple d'un cylindre dans un cube :
Code : C
1
2
3
4
5
6
7
isosurface {
  function { x*x + y*y - 1 }
  contained_by { box { -1, 1 } }
  threshold 0

  pigment { rgb 1 }
}


Commençons par expliquer un peu ce code...
function { } définit la fonction à utiliser. Vous avez le droit d'utiliser dedans les variables x, y et z.
contained_by { } donne le conteneur. Ici, c'est une simple boîte (la valeur par défaut), mais j'aurais aussi bien pu utiliser une sphère.
threshold spécifie le seuil : je vous l'ai dit, ici on met 0. Puisque c'est la valeur par défaut, j'aurais pu enlever cette ligne, mais elle améliore la lisibilité en montrant facilement que le seuil est 0.

Waaah ! Ca marche !! Mais... Pourquoi ne pas avoir utilisé un vrai cylinder pour ça ?...

Tsss, jeune insolent ! :lol:
Dans cet exemple, on aurait bien pu utiliser un cylindre classique...
Voici donc un deuxième exemple, un tout petit peu plus intéressant :
Code : C
1
2
3
4
5
6
7
isosurface {
  function { x*x + y*y - z }
  contained_by { box { -1, 1 } }
  threshold 0

  pigment { rgb 1 }
}


Et voilà ce que ça donne chez moi :
Isosurface... étrange.

Mais ?? C'est tout pas beau !! :(

Je vous l'avais dit ! :D Il manque quelques paramètres pour être certain que POV-Ray dessine bien notre surface...

Une histoire de précision

Si POV-Ray a lamentablement échoué lors du rendu de notre dernière isosurface, c'est (forcément notre faute ! :p ) parce que nous avions *oublié* de lui donner la précision à utiliser pour effectuer ses calculs... :-°
En effet, même si l'on réduit l'espace infini à une boîte, en théorie, il y a une infinité de points dedans, et donc on n'est pas tiré d'affaire...
Pour résoudre ce problème, POV-Ray ne va regarder que certains de ces points. (Ah, le gros fainéant !)
Bien sûr, en fonction de la complexité de votre surface, il va falloir en regarder plus ou moins...

Deux paramètres permettent de contrôler efficacement le rendu :
  • max_gradient : il définit la valeur maximale de la dérivée de la fonction. POV-Ray a besoin de savoir cela pour calculer efficacement où votre fonction s'annule. La valeur par défaut est de 1.1, ce qui est souvent peu, très peu. Je vous conseille de la monter à 4, voire 10 ou 20 si votre fonction est très "agitée". C'est la cause des grosses cases vides qui apparaissent dans le rendu de la surface. Pour l'exemple précédent, essayer une valeur de 4, ce sera déjà suffisant.
    Voici ce que l'on obtient alors :
    Isosurface avec max_gradient 4
    L'objet est déjà mieux, mais il y a encore un problème : l'ombre sur la surface n'est pas très belle !
  • Le deuxième paramètre permet de corriger ce problème. Il s'agit de accuracy, qui spécifie la précision avec laquelle POV-Ray doit effectuer ses calculs. Plus cette valeur sera faible, plus les calculs seront précis.
    La valeur par défaut est de 0.001, mais c'est parfois trop. Essayez 0.000001 ou moins, cela devrait donner de meilleurs résultats (bien entendu, cela signifie aussi des rendus plus longs :lol: )
    Voici le résultat final avec accuracy 0.000001 :
    Isosurface complète


Et voilà ! Nous avons finalement réussi à faire une isosurface acceptable. En jouant avec les équations, vous devriez pouvoir obtenir des résultats intéressants... Expérimentez ;)

Sortir la fonction

Ecrire la fonction dans l'isosurface, c'est un peu pratique quand notre fonction est simple, mais ça devient vite illisible quand elle est plus compliquée...
Heureusement, il y a moyen d'écrire la fonction en dehors de l'isosurface...
Regardez ce code :
Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
#declare f = function { x*x + y*y - z*z + 0.1 }                       
                       
isosurface {
  function { f(x,y,z) }
  contained_by { box { -1, 1 } }
  threshold 0    
  max_gradient 4 
  accuracy 0.000001

  pigment { rgb 1 }
}


Ici, on a d'abord déclaré notre fonction, pour ensuite l'utiliser dans l'isosurface !
Mieux encore, il est possible d'utiliser des fonctions dans d'autres fonctions :
Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
#declare square = function(x) { x * x }
#declare f = function { square(x) + square(y) - square(z) + 0.1 }                       
                       
isosurface {
  function { f(x,y,z) }
  contained_by { box { -1, 1 } }
  threshold 0    
  max_gradient 4 
  accuracy 0.000001

  pigment { rgb 1 }
}


Si l'on ne met rien après function dans la déclaration, POV-Ray considère par défaut que la fonction prend trois paramètres : x, y et z. Si l'on veut en utiliser d'autres, il faut le préciser, comme dans Code : C
1
#declare square = function(x) { x * x }

On dit ici que l'on veut une fonction de x uniquement.
Il existe un équivalent entre x et u : partout où vous pouvez mettre x, vous pouvez mettre u, même si vous n'avez défini que x en paramètre. D'ailleurs, il est interdit de définir comme paramètre x et u. Le même type d'équivalent existe entre y et v.


En utilisant ainsi les fonctions, vous pouvez arriver à des résultats encore plus impressionnants !
Voici un exemple :
Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#declare square = function(x) { x * x }
#declare g = function { square(x) + square(y) - square(z) + 0.1 }
#declare f = function { square( g(x, y, z) + 0.1 ) - 0.1 }                       
                       
isosurface {
  function { f(x,y,z) }
  contained_by { box { -1, 1 } }
  threshold 0    
  max_gradient 10 
  accuracy 0.000001

  pigment { rgb 1 }
}

Des intersections

Par défaut, POV-Ray arrête de chercher une intersection avec votre isosurface dès qu'il en a trouvé une. De cette manière, on ne perd pas de temps à calculer les faces que l'on ne voit pas.
Pourtant, parfois, c'est très gênant : dans une différence par exemple, ou quand l'objet est transparent, on a besoin de toutes les intersections.
Pour corriger cela, il suffit d'ajouter all_intersections à l'isosurface. Facile ! ;)

Q.C.M.

Quelles sont les options indispensable de l'isosurface ?
Ma surface est pas belle du tout ! Il y a des trous partout, c'est pas normal !

Qu'est-ce qui ne va pas ?
Si je ne précise pas le nombre de paramètres d'une fonction, combien en a-t-elle ?

Statistiques de réponses au QCM

Toujours vivants ? Ne vous inquiétez pas, ça ne fait que commencer. :lol:
La suite vous montrera enfin la véritable utilité des isosurfaces...
Chapitre précédent Sommaire Chapitre suivant

Partager

2 commentaires pour "Les isosurfaces (1/2)"
Note moyenne : 3.96 / 4 (24 votes)
Pseudo Commentaire
Hors ligne iansus # Posté le 10/07/2009 à 11:57:02
Google is your friend
Avatar

Études : Télécom ParisTech

Citation
Par exemple, si j'avais pris f(x) = x² + y², qu'est-ce que ça aurait donné ?...


A remplacer par :

Citation
Par exemple, si j'avais pris f(x,y) = x² + y², qu'est-ce que ça aurait donné ?...

Image utilisateur
 
Hors ligne Gyscos # Posté le 10/07/2009 à 12:02:18
Better burn out than fade away
Avatar

Ville : Palaiseau
Pays : France métropolitaine
Études : Polytechnique

Oops :-°
Merci d'avoir remarqué ! Ce sera rapidement corrigé...

Three Wise Droids
Currently working on Spirits Of Heaven, a T-RPG for Android (check the git page) :
http://www.spirits-of-heaven.com
 

Voir tous les commentaires