[Mode de rendu 3D] Ray-tracing (Lancer de Rayon)

Le problème exposé dans ce sujet a été résolu.

Bonjour à tous,

Le Lancer de Rayon, ou Ray Tracing/Casting, permet d’afficher en 2D une scène 3D.

Pour ce faire, on place logiquement une caméra en face de l’image 2D (qui au départ est vierge), laquelle est elle-même en face de la scène 3D. L’assertion suivante doit être vraie : chaque pixel de l’image 2D correspond à un pixel de la scène 3D.

Pour chaque pixel de l’image 2D, on envoie un rayon ayant pour origine la caméra et qui atteint son pixel correspondant (pixel de la scène 3D).

Si le rayon rencontre un objet 3D (donc un pixel colorié), c’est qu’il y a un objet. En tenant compte de ses propriétés physiques, et de s’il est éclairé par une source de lumière dans la scène 3D, on obtient sa couleur et on dessine alors le pixel dans l’image 2D à partir du pixel 3D : petit à petit cette dernière se complète.

Questions

  1. Que se passe-t-il si le rayon ne rencontre rien ?

  2. Peut-on réellement parler de "pixel dans la scène 3D" ? D’ailleurs est-ce que le Ray Tracing fonctionne vraiment de cette manière ?

  3. Les objets 3D ne doivent-ils pas être explicitement indiqués au Ray Tracer ? En effet, celui-ci doit savoir que telle ou telle propriété physique (rugosité, etc.) appartient à tel ou tel objet, et forcément que tel ou tel objet est situé à tel ou tel endroit de la scène 3D (puisqu’il y a correspondance entre : pixel_image_2D et pixel_scene_3D) ?

  4. J’ai lu que les ombres des objets, s’ils sont éclairés par une source lumineuse dans la scène 3D, sont également dessinées par le Ray Tracer/Ray Tracing. Or je ne comprends pas du tout comment c’est possible ?

  5. Enfin, j’ai lu sur un site qu’un rayon rencontrant un objet de la scène 3D (ou plus précisément, d’après moi, le pixel correspondant de ce dernier) ricocherait vers sa source lumineuse (ou vers un autre objet puis vers la source lumineuse), cf. cette image : https://www.scratchapixel.com/images/upload/introduction-to-ray-tracing/lightingnoshadow.gif .... A quoi ça sert ?

Merci d’avance, bonnes fêtes de fin d’année. :)

  1. Il est courant de définir une distance maximale à partir de laquelle on considère que le rayon ne rencontrera rien. Cette distance peut très bien se calculer à l’avance en fonction de la position des objets et de la caméra. Si le rayon ne rencontre rien, il faut simplement mettre la couleur de fond que tu souhaites.
  2. Dans le cadre du ray-tracing, je ne pense pas que l’on puisse parler de pixel 3D. Un pixel 2D correspond en fait à une surface, donc un pixel 3D correspond à un volume. Dans ce cas, on parle de voxel (par exemple, un cube dans minecraft). Dans le raytracing, ton rayon rencontre un point 3D, pas un volume.
  3. Le ray-tracer doit en effet avoir un moyen de savoir si un rayon rencontre un objet, mais il n’a pas forcément besoin de connaître explicitement tous les objets. Avec une fonction qui dit si un point est dans un objet, tu n’a pas explicitement la liste des objet, mais cela reste suffisant pour faire un ray-tracer.
  4. Tu as la réponse dans la question 5: lorsque tu rencontres un objet, tu lances un rayon depuis le point de rencontre vers la lumière. Si tu rencontres un objet sur le chemin, ton point n’est pas éclairé.

Bonjour,

Pour trouver réponse à tes différentes questions, il faut prendre le problème à l’envers. Le raytracing s’inspire de la réalité, en prenant le chemin inverse.

Dans la réalité, les sources lumineuses émettent des ondes (les rayons) qui se réverbèrent sur des objets. Ces objets absorbent une partie des rayons suivant leur longueur d’onde (ce qui détermine la couleur de l’objet), puis le rayon continue son chemin (suivant la réflexivité de l’objet)1.

Certains rayons finiront par atteindre ta rétine (ou autre dispositif de capture), et te faire apparaître sur un plan la couleur des objets rencontrés. Beaucoup d’autres rayons seront juste « perdus ».

Le raytracing cherche donc à reproduire ce phénomène, sans toutes ces pertes. Ainsi, les rayons sont lancés depuis l’écran vers la scène, et remontent jusqu’aux sources lumineuses.

  1. Un rayon qui ne rencontre rien, ça veut dire dans l’autre sens qu’aucun rayon lumineux n’atteint ce point du plan, c’est le vide, donc noir ;

  2. Pas vraiment. Les objets de la scène sont souvent identifiés par des formes géométriques plutôt que des pixels ;

  3. Ça dépend de la conception. Le raytracer doit d’une manière ou d’une autre référencer les objets de la scène, et savoir si ses rayons interceptent ces objets. Mais les propriétés de l’objet peuvent être gérés par l’objet lui-même lors de la détermination de la couleur.

  4. À chaque intersection avec un objet, un rayon est relancé (plutôt à destination des sources lumineuses, mais ça peut être différent en cas d’objets réfléchissants ou transparents). Ce sont les lumières qui éclairent l’objet et modulent sa couleur ; moins il trouve de lumière, plus il sera sombre, c’est ce qui fait apparaître les ombres ;

  5. À remonter jusqu’aux origines du rayon (les sources lumineuses).


  1. Dans l’idée, je suis pas super bien calé, désolé pour les approximations. 

Salut ! Merci d’avoir pris le temps de me répondre ! :)

Dans le cadre du ray-tracing, je ne pense pas que l’on puisse parler de pixel 3D. Un pixel 2D correspond en fait à une surface, donc un pixel 3D correspond à un volume. Dans ce cas, on parle de voxel (par exemple, un cube dans minecraft). Dans le raytracing, ton rayon rencontre un point 3D, pas un volume.

Quand tu dis qu’un pixel 2D correspond à une "surface", tu n’entends pas "la surface bien déterminée d’un cube", mais plutôt une portion ? (ie. : tout ou partie de la surface d’un cube) ?

Tu as la réponse dans la question 5: lorsque tu rencontres un objet, tu lances un rayon depuis le point de rencontre vers la lumière. Si tu rencontres un objet sur le chemin, ton point n’est pas éclairé.

Ah bah oui en fait c’est simple :euh:

heum juste, comment le ray tracer détermine-t-il la source de lumière vers laquelle envoyer son rayon une fois que ce dernier a ricoché sur l’objet vers lequel il était allé ?

@entwann :

moins il trouve de lumière, plus il sera sombre, c’est ce qui fait apparaître les ombres ;

Heum si je ne me trompe pas, Berdes explique que si un objet se situe entre le premier objet (celui qui est entré en collision avec le rayon d’origine - le tout premier quoi) et la source de lumière, c’est qu’il n’est pas éclairé, donc il y a une ombre.

Toi tu dis que moins il y a de sources de lumière, plus il sera sombre.

Je vois deux implications :

  1. Plusieurs rayons sont lancés depuis l’objet (un rayon par source de lumière) ;

  2. L’intensité de l’ombrage est assez finement calculée : moins il y a de source de lumières trouvées, plus l’objet est sombre, et si un objet barre la route au rayon qui allait vers l’une des sources de lumière, ce fait est également pris en compte (s’il n’y avait qu’une seule source de lumière/un seul rayon, alors l’objet ne serait pas du tout éclairé).

C’est correct ?

Edit

Que pensez-vous de cet algorithme que je viens d’écrire ? On colorie chaque pixel de l’image 2D (qui est le rendu de la scène 3D) de la manière suivante :

  1. Pour chaque pixel de l’image 2D (laquelle est le rendu de la scène 3D)

    1.1. La caméra envoie un rayon passant par ce pixel ;

    1.1.1. Si ce rayon parcourt une distance préalablement fixée sans n’avoir rien rencontré, alors la couleur de fond choisie préalablement est assignée à ce pixel ;

    1.1.2. Sinon (le rayon est entré en collision avec un objet) : un nouveau rayon ("rayon ricochet") est émis depuis le point de collision de l’objet avec le premier rayon vers une source lumineuse (on répète cette étape pour chaque source lumineuse différente de la scène) ;

    1.2.2.1. Pour chacun de ces rayons : si un autre objet entre en collision avec, c’est que le premier objet n’est pas éclairé par la source lumineuse correspondant au rayon ricochet et le pixel 2D est colorié en noir

    1.2.2.2. Sinon c’est qu’il est éclairé par la source lumineuse correspondant au rayon ricochet et le pixel 2D est dessiné avec la couleur de l’objet (dont la luminosité est calculée)

On notera que moins il y a de sources lumineuses atteintes par ces "rayons ricochets" ou présentes, plus le pixel 2D sera noir.

+0 -0

D’accord merci !

Dernière petite question : une fois que le rayon a atteint l’objet, on a dit que plusieurs nouveaux rayons partent du point d’impact du rayon originel et vont vers une source de lumière chacun (et il y a N nouveaux rayons, avec N = nombre de sources de lumière). Sais-tu s’il existe un ordre dans lequel ces rayons sont créés (par exemple, est-ce que le rayon allant vers la source lumineuse la plus proche du point d’impact du rayon originel est créé en premier et ainsi de suite ?)

Heum si je ne me trompe pas, Berdes explique que si un objet se situe entre le premier objet (celui qui est entré en collision avec le rayon d’origine - le tout premier quoi) et la source de lumière, c’est qu’il n’est pas éclairé, donc il y a une ombre.

Toi tu dis que moins il y a de sources de lumière, plus il sera sombre.

Je vois deux implications :

  1. Plusieurs rayons sont lancés depuis l’objet (un rayon par source de lumière) ;

  2. L’intensité de l’ombrage est assez finement calculée : moins il y a de source de lumières trouvées, plus l’objet est sombre, et si un objet barre la route au rayon qui allait vers l’une des sources de lumière, ce fait est également pris en compte (s’il n’y avait qu’une seule source de lumière/un seul rayon, alors l’objet ne serait pas du tout éclairé).

C’est correct ?

The-Aloha-Protoco

Oui, tu tenteras de raccorder l’objet à chaque source lumineuse, en ajoutant les différentes intensités. Un objet dans l’ombre sera simplement un objet non éclairé par une lumière (donc un autre objet se trouvant entre lui et la source de lumière).

**Que pensez-vous de cet algorithme que je viens d’écrire ?

The-Aloha-Protoco

Je me questionne sur ton 1.1.1., comment comptes-tu gérer les intersections avec les objets de la scène ?

@The-Aloha-Protoco Ta phrase donne l’impression que ton rayon va parcourir un chemin jusqu’à trouver un objet, ce n’est pas comme ça que ça fonctionnera en réalité.

Tu regarderas plutôt quelles sont les intersections entre ton rayon et un ensemble d’objet, et conservera l’objet le plus proche.

Il te serait très difficile d’itérer sur les objets dans l’ordre de découverte par le rayon, donc non.

Il faut que tu notes que le rayon n’a pas d’existence réelle, c’est juste une représentation. Tu ne te promènes pas le long d’un rayon pour trouver des objets. Tu cherches juste les intersections entre des objets et une demi-droite.

Il te serait très difficile d’itérer sur les objets dans l’ordre de découverte par le rayon, donc non.

entwanne

En fait, si les objets sont stockés dans un octree (l’équivalent d’un quadtree en 3D), tu as moyen d’itérer sur les objets dans un ordre proche de celui de découverte par le rayon et ainsi arrêter l’exécution assez rapidement lorsqu’un objet est trouvé.

Après, la méthode de tracé avec un rayon qui avance pas à pas est de loin la plus simple à implémenter puisque décider si un point appartient à un objet ou non est plus simple que de calculer l’intersection entre l’objet et une droite.

En fait, si les objets sont stockés dans un octree (l’équivalent d’un quadtree en 3D), tu as moyen d’itérer sur les objets dans un ordre proche de celui de découverte par le rayon et ainsi arrêter l’exécution assez rapidement lorsqu’un objet est trouvé.

Berdes

Oui, un ordre proche. Mais tu ne peux pas t’arrêter au premier objet rencontré (sauf si le sous-ensemble de l’octree ne contient qu’un objet).

Après, la méthode de tracé avec un rayon qui avance pas à pas est de loin la plus simple à implémenter puisque décider si un point appartient à un objet ou non est plus simple que de calculer l’intersection entre l’objet et une droite.

Berdes

Le problème avec ça, c’est le pas. Comment tu fais pour détecter un plan face à toi, si celui-ci n’a aucune épaisseur ? À moins de tester l’intersection avec un segment, je ne vois pas.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte