Il est probablement plus facile à comprendre par contraste avec le lancer de rayons.
Pour rendre une primitive avec le lancer de rayons, vous avez besoin d'une fonction qui, en fonction de la primitive et du rayon d'entrée, vous indique exactement où ce rayon frappe la primitive. Ensuite, vous pouvez tester le rayon contre toutes les primitives pertinentes et choisir l'intersection la plus proche. Les processeurs sont bons à cela.
Avec Raymarching, vous n'avez pas une fonction aussi simple d'intersection de rayon. À partir d’un point du rayon, vous pouvez estimer la distance qui le sépare de la surface, mais vous ne savez pas exactement dans quelle mesure vous avez besoin d’étendre ce rayon pour atteindre la surface.
Alors, vous "marchez" pas à pas:
Commencez par le "début" du rayon - le plan rapproché pour le rendu de la scène ou l'intersection avec le volume de contour s'il ne s'agit que d'un objet de la scène. (P0 dans le diagramme ci-dessous)
Évaluez votre fonction de distance pour obtenir une estimation de votre distance à la surface. (Le plus grand cercle dans le diagramme)
Avancez le long du rayon en fonction de votre estimation. Le mouvement doit être court, de manière conservatrice, afin que vous soyez sûr de ne creuser aucun tunnel à travers la surface.
Vous avez maintenant un nouveau point (P1 ci-dessous) - obtenez une nouvelle estimation et recommencez.
Continuez à obtenir des estimations et avancez jusqu'à ce que vous vous trouviez à une distance minimale de la surface ou que vous atteigniez votre nombre maximal de pas. (P4 ci-dessous)
Maintenant, vous avez la profondeur de la surface et pouvez déduire des choses comme l'occlusion normale / ambiante à partir d'échantillons à proximité, et utilisez ces données pour éclairer et colorer le pixel.
Exemple de diagramme tiré de GPU Gems 2, chapitre 8
Chaque rayon étant indépendant et n'utilisant (généralement) que des informations locales à chaque étape, il est temps de mettre en parallèle des GPU. Souvent, seuls deux triangles seront dessinés à l'écran. Après avoir rastérisé ces derniers, chaque pixel transmis au fragment shader représente un seul rayon. Le fragment shader défile jusqu'à ce qu'il atteigne la surface, renvoyant le résultat (il ne s'agit souvent que de la valeur de profondeur pour le texturage et l'ombrage dans une passe en plein écran séparée).
Les étapes exactes dépendent beaucoup de l’effet particulier que vous essayez d’obtenir. Les techniques de Raymarching sont utilisées avec ...
- heightfields pour simuler le déplacement de surface sur une géométrie rastérisée traditionnelle (cartographie d'occlusion de parallaxe)
- des tampons de profondeur de scène pour des choses comme les réflexions dans l'espace d'écran
- textures de volume pour la visualisation de jeux de données échantillonnés en 3D (souvent scientifiques / médicaux)
- fonctions implicites pour rendre des choses comme des fractales
- champs de distance procéduraux comme dans le travail d'Iñigo Quilez (liens intéressants de msell dans les commentaires ci-dessus).
Le raymarching est également utilisé avec le mélange à chaque étape (souvent en utilisant des étapes fixes au lieu d'estimer une distance à chaque fois) pour le rendu de la translucidité volumétrique, comme dans cet exemple de Wikipedia .
Cela est devenu un moyen populaire de rendre des nuages détaillés en temps réel .
Même la cartographie intérieure , une manière de simuler les détails d'une pièce derrière les fenêtres d'un bâtiment, pourrait être considérée comme une forme de raymarching, selon laquelle le rayon est découpé du point où il entre dans la fenêtre jusqu'au mur, au sol / au plafond ou au plan du meuble le plus proche.
Si un type spécifique d'effet de raymarching vous intéresse, vous pouvez probablement obtenir des réponses plus détaillées en posant une nouvelle question avec des exemples spécifiques. En tant que famille, la technique est trop diverse pour tout couvrir en une seule réponse. ;) J'espère que cela vous donne un cadre pour comprendre ce qui se passe sous le capot de ces shaders.