web-dev-qa-db-fra.com

Comment faire le lancer de rayons dans OpenGL moderne?

Je suis donc à un point où je devrais commencer à allumer mes modèles plats. L'application de test est un cas de test pour la mise en œuvre des méthodes les plus récentes, j'ai donc réalisé que, idéalement, elle devrait implémenter le lancer de rayons (car théoriquement, elle pourrait être idéale pour les graphiques en temps réel dans quelques années).

Mais par où commencer?

Supposons que je n'ai jamais fait d'éclairage dans l'ancien OpenGL, donc j'irais directement vers des méthodes non obsolètes.

L'application a actuellement correctement configuré les objets tampon de vertex, vertex, normal et color input et dessine et transforme correctement les modèles dans l'espace, dans une couleur plate.

Existe-t-il une source d'informations qui prendrait l'un des sommets plats pour tout ce qui est nécessaire pour un résultat final correct via GLSL? Idéalement avec toutes les autres méthodes d'éclairage supplémentaires qui pourraient être nécessaires pour le compléter.

30
j riv

Je ne conseillerais pas d'essayer le lancer de rayons réel dans OpenGL car vous avez besoin de beaucoup de hacks et d'astuces pour cela et, si vous me demandez, il n'y a plus aucun intérêt à le faire. Si vous voulez faire du ray tracing sur GPU, vous devriez aller avec n'importe quel langage GPGPU, comme CUDA ou OpenCL car cela rend les choses beaucoup plus faciles (mais toujours loin d'être triviales).

Pour illustrer le problème un peu plus loin: Pour le lancer de rayons, vous devez tracer les rayons secondaires et tester l'intersection avec la géométrie. Par conséquent, vous devez accéder à la géométrie de manière intelligente à l'intérieur de votre shader, mais à l'intérieur d'un shader de fragment, vous ne pouvez pas accéder à la géométrie, si vous ne la stockez pas "codée" dans une texture. Le vertex shader ne vous fournit pas non plus ces informations de géométrie en mode natif, et les geometry shaders ne connaissent que les voisins, donc ici le problème commence déjà. Ensuite, vous avez besoin de structures de données d'accélération pour obtenir des fréquences d'images raisonnables. Cependant, traverser par exemple un Kd-Tree à l'intérieur d'un shader est assez difficile et si je me souviens bien, il y a plusieurs articles uniquement sur ce problème. Si vous voulez vraiment emprunter cette voie, cependant, il y a beaucoup d'articles sur ce sujet, il ne devrait pas être trop difficile de les trouver.

Un traceur de rayons nécessite des modèles d'accès et une mise en cache extrêmement bien conçus pour atteindre de bonnes performances. Cependant, vous n'avez que peu de contrôle sur ceux-ci à l'intérieur de GLSL et l'optimisation des performances peut devenir très difficile.

Un autre point à noter est que, du moins à ma connaissance, le lancer de rayons en temps réel sur les GPU est principalement limité aux scènes statiques, car par exemple kd-trees ne fonctionne (bien) que pour les scènes statiques. Si vous voulez avoir des scènes dynamiques, vous avez besoin d'autres structures de données (par exemple BVH, iirc?) Mais vous devez constamment les maintenir. Si je n'ai rien oublié, il y a encore beaucoup de recherches en cours sur cette question.

28
zerm

Vous pouvez confondre certaines choses.

OpenGL est un rasterizer. Le forcer à faire du raytracing est possible, mais difficile. C'est pourquoi le raytracing n'est pas "idéal pour les graphiques en temps réel dans quelques années". Dans quelques années, seuls les systèmes hybrides seront viables.

Donc, vous avez trois possibilités.

  • Raytracing pur. Rendez uniquement un quadruple plein écran et, dans votre fragment shader, lisez la description de votre scène emballée dans un tampon (comme une texture), parcourez la hiérarchie et calculez les intersections de rayons et triangles.
  • Raytracing hybride. Pixellisez votre scène de façon normale et utilisez le lancer de rayons dans votre shader sur certaines parties de la scène qui en ont vraiment besoin (réfraction, ... mais cela peut être simultané en tramage)
  • Rastérisation pure. Le shader de fragments fait son travail normal.

Que voulez-vous exactement réaliser? Je peux améliorer la réponse en fonction de vos besoins.

Quoi qu'il en soit, cette SO question est très liée. Même si cette implémentation particulière a un bogue, c'est certainement la voie à suivre. Une autre possibilité est openCL, mais le concept est le même.

21
Calvin1602

En ce qui concerne 2019 Ray tracing est une option pour le rendu en temps réel, mais nécessite des GPU haut de gamme que la plupart des utilisateurs n'ont pas. Certains de ces GPU sont spécialement conçus pour le traçage de rayons. OpenGL ne prend actuellement pas en charge le traçage de Ray boosté par le matériel. DirectX 12 sur Windows a un support pour cela. Il est recommandé d'attendre quelques années de plus avant de créer un moteur de rendu Ray Tracing uniquement, bien qu'il soit possible d'utiliser DirectX 12 avec le matériel de bureau et d'ordinateur portable actuel. La prise en charge depuis le mobile peut prendre des décennies. Je ne vois pas openGL supportant le lancer de rayons mais vulkan pourrait à l'avenir le supporter.

0
tomer zeitune