Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
713 connectés 

 


 Mot :   Pseudo :  
 
 Page :   1  2  3  4  5  6  7  8  9  10
Auteur Sujet :

Article: un raytracer de base en C++

n°504122
Krueger
tout salaire demande dutravail
Posté le 01-09-2003 à 13:53:52  profilanswer
 

Reprise du message précédent :
Ah, ok. C'est comme utiliser du Phong au lieu du Gouraud, les variations sont plus mises en évidence dans le résultat.


---------------
"Colère et intolérance sont les ennemis d'une bonne compréhension." Gandhi
mood
Publicité
Posté le 01-09-2003 à 13:53:52  profilanswer
 

n°504649
LeGreg
Posté le 02-09-2003 à 07:56:07  profilanswer
 

Quelques mots sur le HDR (pas de code parce que c'est principalement du copier coller) desole c'etait un week-end de trois jours, le demenagement d'un copain, une sortie à Walnut Creek et beaucoup de boulots dans la semaine.
 
Update :  
Les articles ont été remis à jours et sont disponibles sur mon site web:
 
premiers pas:
http://www.massal.net/article/raytrace/page1.html
éclairage spéculaire (blinn-phong), post processing et antialiasing:
http://www.massal.net/article/raytrace/page2.html
textures (Perlin noise, cubic environment mapping, bump mapping)
http://www.massal.net/article/raytrace/page3.html
Flou (depth of field), Fresnel, blobs (isosurfaces):
http://www.massal.net/article/raytrace/page4.html
HDR, loi de beer, aberration chromatique:
http://www.massal.net/article/raytrace/page5.html
Global ilumination, photon mapping:
http://www.massal.net/article/raytrace/page6.html  
 
Le code et les commentaires y sont plus récents. Vous pouvez continuer à utiliser ce topic pour les questions
et commentaires.
 
Voilà, si vous voulez l'historique du sujet, vous pouvez continuer à lire la suite.
Fin de l'Update  
 
Les représentation de la lumière
 
Ce que vous voyez représentés sur vos écrans d'ordinateurs, sont des images calibrées, au contraste limité et altéré par la luminosité ambiante.
 
Bref ce sont de faibles représentations de la réalité.
Dans la réalité vous avez un système complexe qui perçoit des contrastes énormes, entre la lumière du jour en plein soleil, et la lumière d'une bougie. Votre oeil meme s'il ne pourrait percevoir simultanément des détails en pleine lumière et dans l'ombre d'une cave est capable de s'adapter, un bon appareil photographique également. Votre écran d'ordinateur ne peut représenter qu'une faible partie de ce spectre d'intensité. Un écran d'ordi ne peut pas vous aveugler (tant mieux) et ne peut afficher des détails qu'il faudrait voir toutes lumières éteintes (de toute façon la rémanence de votre moniteur CRT absorberait ces détails).
 
Dans ces conditions, on considére qu'il est inutile de stocker trop d'informations dans un fichier image, informations qui seraient inaffichables sur un écran d'ordinateur ou même sur papier imprimé (c'est en général pire). Un peu comme les MP3 qui mangent des détails du son qui de toute façon ne sont pas perçus par votre cerveau.
 
High dynamic range
 
Pour la synthèse d'image le problème est très différent. Les images qui suffisent pour représenter une représentation crédible de la réalité sur un écran d'ordinateur ne sont plus valides quand elles sont utilisées pour créer d'autres images.
Comme on l'a vu plus haut avec l'opérateur de saturation, si l'on contente de gommer les détails au dessus d'une certaine intensité, l'image résultat sera très moche. C'est la raison pour laquelle les jeux sont si peu crédibles en terme d'éclairage. Si l'on peut demander aux artistes de se restreindre à des niveaux compressibles dans des valeurs de 0 à 255, on va éliminer le risque de saturation. Mais on obtiendra des images fadasses avec peu d'audace dans les éclairages et les couleurs. de plus on est forcé de tricher pour faire des effets comme l'éblouissement à la sortie d'un tunnel ou l'aveuglement à l'entrèe d'une cave. pour restituer ces deux effets et faire en sorte que les détails dans le tunnel soient visibles et les détails à l'éxtérieur soient visibles également, on ne peut plus se restreindre à un intervalle de 0 à 255 couleurs.
Passer à un intervalle de 0 à 65535 est une étape possible mais cela ne fait que repousser le problème un peu plus loin.
 
De mon coté j'ai pris le parti dans ce programme de tout représenter sous forme de flottants codés sur 32 bits pour chaque canal représentable sur mon écran (Rouge vert et bleu). C'est à la fois énorme et beaucoup trop pour la plupart des calculs mais également trop peu (je reviendrai sur ce point si j'ai le temps, pour les exemples que j'utilise c'est juste "beaucoup trop" ).  
Le passage d'une forme HDR flottante à une forme représentable sur l'écran est appelée géneralement tone mapping. A chaque valeur flottante on fait correspondre un ton correspondant dans le triple intervalle [0,255][0,255][0,255]. Ma fonction est encore un peu naive puisqu'elle ne tient pas vraiment compte des différences de réponses de l'oeil et du moniteur sur certaines intensités mais je fais de la synthèse et non pas de la simulation. Mon idéal c'est d'avoir un résultat suffisamment proche de ce que pourrait prendre un appareil photo d'une scène qui n'existe pas.  
 
HDR cube env map
 
J'avais utilisé au début de cette série d'article une texture cubique mais à dynamique fixe et figée entre 0 et 255 (ramenée en [0,1]). Cette image a été précalculée dans un logiciel qui s'est basé sur un modèle physique simple pour calculer l'éclairement en chaque point de la texture. Cet éclairement avait à l'origine de fortes variations mais a été ramené à l'intervalle supporté par le format TGA et directement exploitable par les cartes graphiques 3D. Pour notre programme de synthèse on n'a pas de telles limitations, à vrai dire on aimerait au contraire pouvoir passer du logiciel qui a servi à calculer la cubemap à notre programme de raytracing sans perdre ces précieuses informations de luminosité.
 
Comme ce n'est pas possible avec Terragen, j'ai décidé d'aller chercher les cube map HDR les plus utilisés de par le monde, à savoir celle de Paul Debevec.  
http://www.debevec.org/Probes/
Debevec a mis au point une méthode pour extraire l'information dynamique de prises de vues réelles à la place d'utiliser des images de synthèse, je ne détaille pas ici, vous pouvez aller voir le site web.  
Il l'utilise aussi (et beaucoup d'autres personnes) pour faire de l'éclairage à base d'image. De mon côté ce ne sont que de simples environment maps, mais ça suffit pour l'instant.
 
Le format HDR
 
Il propose des cube map sous forme de fichiers HDR (format développé pour Radiance, un programme de calcul d'éclairage par radiosité).
Le fichier HDR utilisé est une forme plus compact des textures flottantes que j'utilise. Ils considérent les trois canaux RVB et leurs intensités relatives codées sur 8 bits, et ils rajoutent un exposant qui est partagé par les trois canaux.
Ca tient en 32 bits par pixel et ça s'appelle RGBE (rouge vert bleu exposant).
Le loader de fichiers HDR est une adaptation directe de cette version:
http://www.graphics.cornell.edu/online/formats/rgbe/
 
Le reste du code est identique donc pas la peine de s'étendre.
 
LeGreg


Message édité par LeGreg le 12-07-2008 à 00:02:51

---------------
voxel terrain render engine | animation mentor
n°504670
LeGreg
Posté le 02-09-2003 à 08:59:48  profilanswer
 

Voila un petit resumé des effets qu'on a vu depuis le début:
http://www.massal.net/article/raytrace/page5.html
 
blobs, cube env map, reflexions, refraction, bump map, perlin noise et generation de textures, tone mapping (via fonction d'exposition simple), importance sampling, high dynamic range, profondeur de champ, super sampling.
 
A+
LeGreg


Message édité par LeGreg le 29-02-2008 à 20:17:06

---------------
voxel terrain render engine | animation mentor
n°504789
tomlameche
Et pourquoi pas ?
Posté le 02-09-2003 à 10:41:17  profilanswer
 
n°504790
souk
Tourist
Posté le 02-09-2003 à 10:41:40  profilanswer
 

:love:  :love:

n°504814
LeGreg
Posté le 02-09-2003 à 10:49:44  profilanswer
 

La prochaine update sera sur beer's law (ou comment colorer les matériaux transparents):
 
http://www.massal.net/article/raytrace/page5.html
 
LeGreg


Message édité par LeGreg le 29-02-2008 à 20:17:23

---------------
voxel terrain render engine | animation mentor
n°505722
Krueger
tout salaire demande dutravail
Posté le 02-09-2003 à 20:24:39  profilanswer
 

De l'eau ! :love:


---------------
"Colère et intolérance sont les ennemis d'une bonne compréhension." Gandhi
n°506120
LeGreg
Posté le 03-09-2003 à 10:16:41  profilanswer
 

Les matériaux transparents
 
On a vu qu'il y avait des lois qui régissaient la trajectoire et l'intensité de la lumière dans un milieu totalement transparent (sans perte de luminosité et sans diffusion).
Ceci dit la plupart des milieux s'ils sont composés de molécules qui font transiter la lumière sans déperdition contiennent aussi ce que l'on appelle des impuretés ou des éléments qui eux ne sont pas transparents à la lumière.
Ces éléments s'ils sont en faible concentration, diffusent la lumière qui traverse le materiau selon une loi qui est connue sous le nom de "Beer's law". Ca n'a rien à voir avec la bière mais à celui qui l'a énoncée en premier.
 
Beer's law
 
L'idée intuitive est que l'intensité et la couleur changent en fonction de la distance parcourue dans un milieu coloré/absorbant. Mais comment changent-elles ?
En gros si I0 désigne l'intensité initiale, c la concentration "molaire" en produit colorant (pour un liquide), alors l'intensité après avoir parcouru la distance l sera de :  
I = I0 * exp(epsilon * c * l)
epsilon est une propriété d'absorption du produit dissous. Elle est indépendante de la concentration en ce produit (si la concentration elle-meme est suffisamment faible).
 
Notre implémentation
Bien entendu on se fiche de epsilon et de c. Notre but encore une fois n'est pas de faire de la simulation, mais un petit raytracer tout simple.
On caractérise le milieu coloré à l'aide de trois coéfficients: un par canaux et qui constituent la valeur relative de l'intensité de chaque canal rouge vert et bleu après avoir parcouru 1 unité de distance.
 
Ce qui nous amène à notre beer's law à nous:
I = I0 * (absorption) ^ l
 
 
le code
Bien entendu il faut modifier notre code précédent. Nous passions à chaque nouveau changement de direction de notre rayon, un coéfficient scalaire qui déterminait l'intensité relative de lumière qui arrivait jusqu'à l'observateur. Cette fois ci ce coefficient sera un tableau de flottant, un par canal.
 
Ceci remplace notre coéfficient de transmission scalaire dans le code de tracé du rayon lumineux:

Code :
  1. couleur coef = {1.0f,1.0f,1.0f};


 
La condition de sortie est modifiée en conséquence:

Code :
  1. } while ((coef.red > 0.0f) && (coef.green > 0.0f) && (coef.blue > 0.0f) &&(level < 10));


 
Juste après le code d'intersection, on détermine quelle distance on a parcouru à l'intérieur du matériau coloré. Peu importe que ce soit après une reflexion ou une refraction.
 

Code :
  1. if (bInside)
  2.     // la lumière transmise dans le médium transparent
  3.     // est affectée par la diffusion due aux impuretés
  4.     // la beer's law s'applique pour les faibles concentrations
  5.     if (currentMat.absorption.red != 1.0f)
  6.     {
  7.         coef.red = coef.red * powf(currentMat.absorption.red, t);
  8.     }
  9.     if (currentMat.absorption.green != 1.0f)
  10.     {
  11.         coef.green = coef.green * powf(currentMat.absorption.green, t);
  12.     }
  13.     if (currentMat.absorption.blue != 1.0f)
  14.     {
  15.         coef.blue = coef.blue * powf(currentMat.absorption.blue, t);
  16.     }
  17. }


 
Il faut que t corresponde exactement à la distance parcourue. Ce sera utile de s'en souvenir pour plus tard.
 
Voila c'est tout pour cette nuit.
 
A+
LeGreg

n°507090
LeGreg
Posté le 04-09-2003 à 10:32:36  profilanswer
 

Quelques chiffres:
 
- indices de réfraction du verre "flint"
dans le rouge: 1.596
dans le vert : 1.640
dans le bleu : 1.680
 
- nombres de rayons tracés pour cette image
au total    : 49 115 200
par seconde : 105 476
 
http://www.massal.net/article/raytrace/page5.html
 
LeGreg


Message édité par LeGreg le 29-02-2008 à 20:17:40

---------------
voxel terrain render engine | animation mentor
n°507118
chrisbk
-
Posté le 04-09-2003 à 11:03:55  profilanswer
 

legreg a écrit :

Quelques chiffres:
 
- indices de réfraction du verre "flint"
dans le rouge: 1.596
dans le vert : 1.640
dans le bleu : 1.680
 
- nombres de rayons tracés pour cette image
au total    : 49 115 200
par seconde : 105 476
 
http://small.massal.net/prisme.png
 
LeGreg


 
Comment ca s'apelle deja ca ? Chromaticity aberation ? Enfin bref j'en avait vu une implementation en VS, c'etait pas trop mal (cf site de nvidia pour les curieux)

mood
Publicité
Posté le 04-09-2003 à 11:03:55  profilanswer
 

n°507921
LeGreg
Posté le 04-09-2003 à 22:21:25  profilanswer
 

chrisbk a écrit :


Comment ca s'apelle deja ca ? Chromaticity aberation ? Enfin bref j'en avait vu une implementation en VS, c'etait pas trop mal (cf site de nvidia pour les curieux)


 
je n'ai pas de nom spécial pour ça..
euh "indice de réfraction variant avec la longueur d'onde"?
 
Chromatic aberation. ou aberration chromatique en français?
 
oui pourquoi pas, sauf que là c'est spotté comme un défaut (pour le système optique d'une caméra) et que dans mon exemple c'est un effet voulu ;).
 
et c'est aussi différent de l'irisation (qu'on peut observer dans la démo Dawn de nvidia aussi) qui est un phénomène d'interférence (les termes de phase que j'ai négligemment négligé).
 
A+
LeGreg

n°507939
chrisbk
-
Posté le 04-09-2003 à 22:40:11  profilanswer
 

legreg a écrit :


 
je n'ai pas de nom spécial pour ça..
euh "indice de réfraction variant avec la longueur d'onde"?
 
Chromatic aberation. ou aberration chromatique en français?
 
oui pourquoi pas, sauf que là c'est spotté comme un défaut (pour le système optique d'une caméra) et que dans mon exemple c'est un effet voulu ;).
 
et c'est aussi différent de l'irisation (qu'on peut observer dans la démo Dawn de nvidia aussi) qui est un phénomène d'interférence (les termes de phase que j'ai négligemment négligé).
 
A+
LeGreg


 
Vala c'est ca le terme de recherche a balancer sur Nvidia pour ceux que ca interesse :D
(je trouve ca tres chouette comme défaut)

n°508284
LeGreg
Posté le 05-09-2003 à 10:39:43  profilanswer
 

Les explications suivent..
 
Aberration chromatique
 
Oui c'est comme cela que ça s'appelle, en général toute forme d'aberration est un défaut pour un système optique (comme l'aberration en barillet ou encore l'astigmatisme).
 
La chromaticité définit un comportement différent d'un matériau suivant la longueur de l'onde électromagnétique qui le heurte, le traverse.
Comme on a expliqué plus tôt que les lois de la réfraction découlaient des principes électromagnétiques et étaient une conséquence du caractère ondulatoire de la lumière, il n'est donc pas très surprenant d'apprendre que la plupart des matériaux transparents ont aussi une réponse différente suivant la longueur d'onde.
 
Je ne rentre pas dans trop de détail, tout ce qu'il y a à retenir c'est que en deuxième approximation, l'indice de réfraction cité plus haut varie en plus en fonction de la longueur d'onde.
 
Pour le verre "flint" c'est par exemple:
pour une onde rouge : 1.596  
pour une onde verte : 1.640  
pour une onde bleue : 1.680  
 
Pour la réflection ca ne va pas changer grand chose. La teinte de la lumière réfléchie va légèrement changer (si l'on ne fait pas intervenir de phénomènes d'interférences). Par contre le rayon réfracté va suivre des chemins très différents dans le matériau et donc on va avoir une séparation "en arc en ciel" de l'image réfractée.
 
C'est ainsi que fonctionne un prisme par exemple.  
 
Implémentation
 
On va changer plusieurs choses dans notre raytracer.
La premiere c'est que le matériel décrit tout au long de cette série d'articles va désormais être découplé en trois séries de paramètres. Ca veut dire trois indices de réfraction mais on pourrait jouer aussi sur les autres paramètres (c'est déjà le cas pour la diffusion, et l'absorption).  
 
On se limite à trois mais on pourrait avoir autant de paramètres que de couleurs dans l'arc en ciel. Pour l'instant l'intérêt est limité.
 
Le deuxième changement est le code du raytracer. A la place de travailler sur des couleurs à trois canaux, notre code de raytracing va s'appliquer à un canal à la fois.  
Il risque d'y avoir énormément de redondance mais j'assume, vu que c'est à peu près l'un des seuls moyens d'avoir trois chemins totalement différent par canal. (et depuis le début je ne sais pas si vous avez remarqué qu'on se limitait à un seul chemin par rayon).
 
Donc le prototype de la fonction addRay est changé en:

Code :
  1. float addRay(ray viewRay, scene &myScene, context myContext);


 
De même toutes les valeurs qui étaient des couleurs sur trois canaux dans le code de cette fonction sont désormais des scalaires flottants.
 
Le canal courant est passé comme argument dans le paramètre context sous forme d'offset. On associe une couleur à un offset via un enum.
 

Code :
  1. for (int y = 0; y < myScene.sizey; ++y) {
  2. for (int x = 0 ; x < myScene.sizex; ++x) {
  3.     couleur output;
  4.     for(int offset = 0; offset < 3; offset++ )
  5.     {
  6.         myContext.offset = COLOROFFSET(offset);
  7.         int nbSamples = 0;
  8.         float channelOutput = 0.0f;
  9.         for(float fragmentx = float(x); fragmentx < x + 1.0f; fragmentx += incrementx)
  10.         for(float fragmenty = float(y); fragmenty < y + 1.0f; fragmenty += incrementy)
  11.         {
  12.             for (int i = 0 ; i < myScene.channelImportance[offset] ; i++)
  13.             {


voici le début du code de la fonction draw.
 
On voit l'apparition d'un nouveau paramètre de la scène qui est le "channelImportance". En gros ça définit l'importance que l'on attache à chaque canal en terme de rayons à envoyer.
 
Par exemple, on peut dire que l'importance du vert sur la couleur finale est de 6, tandis que celle du rouge n'est que de 3 et celle du bleu est de 1.  
Ce qui veut dire que pour 6 rayons verts envoyés on n'enverra que trois rayons rouges et un rayon bleu cette dernière couleur comptant moins dans notre perception visuelle.
 
Le reste du code ne change pas.
 
Voilá c'est tout pour aujourd'hui.
 
A+
LeGreg


Message édité par LeGreg le 05-09-2003 à 11:00:11
n°508390
LeGreg
Posté le 05-09-2003 à 11:29:08  profilanswer
 

Je pense que la prochaine update sera un nettoyage du code,
rajout de commentaire et mise à disposition du snapshot actuel.
 
A+
LeGreg

n°508429
LeGreg
Posté le 05-09-2003 à 11:53:14  profilanswer
 

Après je pensais faire un article en plusieurs séries sur le photon mapping.
(un algo d'illumination qui peut s'appuyer sur le code du raytracer puisque ca traite du probleme inverse -> le suivi de rayon depuis les sources de lumière).
 
Dites moi si ca vous branche sinon je reflechirai a autre chose (CSG, post processing et j'en passe).
 
LeGreg

n°508437
chrisbk
-
Posté le 05-09-2003 à 11:58:54  profilanswer
 

legreg a écrit :

Après je pensais faire un article en plusieurs séries sur le photon mapping.
(un algo d'illumination qui peut s'appuyer sur le code du raytracer puisque ca traite du probleme inverse -> le suivi de rayon depuis les sources de lumière).
 
Dites moi si ca vous branche sinon je reflechirai a autre chose (CSG, post processing et j'en passe).
 
LeGreg


 
Le degagage de tri post-CSG serait interessant. Ceci dit, pour la CSG, vu que quand t'as un BSP c'est in ze pocket et que je sais pas si le BSP c'est le plus motivant, mieux vaut la laisser tber (et s'en remettre a la bsp faq + le tutot d'aggrav8d (ou un truc du genre))
 
Photon mapping, tres bien ! (avec caustique et tout :D)

n°509080
LeGreg
Posté le 05-09-2003 à 23:07:17  profilanswer
 

chrisbk a écrit :


Le degagage de tri post-CSG serait interessant. Ceci dit, pour la CSG, vu que quand t'as un BSP c'est in ze pocket et que je sais pas si le BSP c'est le plus motivant, mieux vaut la laisser tber (et s'en remettre a la bsp faq + le tutot d'aggrav8d (ou un truc du genre))
 
Photon mapping, tres bien ! (avec caustique et tout :D)


 
Ah mon dieu y'a tellement de choses à savoir ;)
 
ceci dit si jamais je fais du CSG ce sera certainement pas state of the art. Vu le (peu de) temps que je dévoue à ce projet d'articles et le rythme des updates.
 
Eh sinon j'ai vu que tu avais des problemes avec la CSG et la generation de textures coordinates.
Heureusement il ne va pas y avoir ce probleme ici tant que j'utilise des textures procédurales 3d ;)
 
LeGreg

n°509789
chrisbk
-
Posté le 07-09-2003 à 22:50:30  profilanswer
 

legreg a écrit :


 
Ah mon dieu y'a tellement de choses à savoir ;)
 
ceci dit si jamais je fais du CSG ce sera certainement pas state of the art. Vu le (peu de) temps que je dévoue à ce projet d'articles et le rythme des updates.
 
Eh sinon j'ai vu que tu avais des problemes avec la CSG et la generation de textures coordinates.
Heureusement il ne va pas y avoir ce probleme ici tant que j'utilise des textures procédurales 3d ;)
 
LeGreg
 


 
Bah c'etait meme plutot du pb en general. En attendant j'ai laissé de coté ce pb vu que j'avais des trucs sur le feu...Mais c vrai qu'une bonne texture 3D et hop, au chiotte les pb !
 
au fait, pas de nouvelles de support de texture 4d sur les CG ? :D

n°509909
LeGreg
Posté le 08-09-2003 à 03:34:41  profilanswer
 

chrisbk a écrit :


au fait, pas de nouvelles de support de texture 4d sur les CG ? :D


 
texture 3d mipmappee = 4d
 
LeGreg

n°509969
chrisbk
-
Posté le 08-09-2003 à 10:02:26  profilanswer
 

legreg a écrit :


 
texture 3d mipmappee = 4d
 
LeGreg


 
j'aurais tendance a dire non, parce que tu ne peux pas indexe directement un texel au coordonnee (a,c,b,d)

n°509984
LeGreg
Posté le 08-09-2003 à 10:23:58  profilanswer
 

chrisbk a écrit :


j'aurais tendance a dire non, parce que tu ne peux pas indexe directement un texel au coordonnee (a,c,b,d)


 
Eh t'as pas précisé les conditions d'application
et techniquement la texture est bien adressée sur quatre  
coordonnées.
(d'ailleurs la version 3 des pixel shaders permet d'alterer directement cette quatrieme coordonnée).
 
Sinon texture procedurale quadri dimensionnelle calculée
dans le pixel shader.
 
LeGreg

n°509989
chrisbk
-
Posté le 08-09-2003 à 10:31:58  profilanswer
 

legreg a écrit :


 
(d'ailleurs la version 3 des pixel shaders permet d'alterer directement cette quatrieme coordonnée).


 
merde les gars pas si vite quoi ! Je commence a peine les 1.1-1.4 !

n°510780
LeGreg
Posté le 09-09-2003 à 11:11:03  profilanswer
 

Voilà j'ai remis les nouveaux sources.
 
Testé avec Vc++ dotnet et Gcc, à part les #pragma once ce dernier ne se plaint pas trop.
 
Je n'ai pas eu le temps de faire autant de cleanup et de commentaires que j'aurais voulu faute de temps (on approche de la release au boulot.. enfin comme d'hab quoi). Donc il y a encore des choses inconsistantes, veuillez m'en excuser (notamment sur les matériaux, la cohabitation des blobs et des spheres etc.. que des choses que je reglerai dans une prochaine update).
 
les sources c'est ici :
http://www.massal.net/article/raytrace/page5.html
 
si vous voulez l'utiliser à son plein potentiel vous aurez probablement des cube maps hdr, c'est là:
http://www.massal.net/article/raytrace/page5.html
 
Encore une fois si vous avez des questions sur le code qui n'est pas clair n'hésitez pas. (Et encore une fois évitez les flames du genre "les classes ont un nom commençant par une lettre majuscule X dans la norme bidule truc" ou "c'est pas la bonne façon d'inclure de fichiers header".. j'en appelle à votre sens civique.)
 
La prochaine étape c'est (si tout va bien) un algo de photon map simple.
 
A+
LeGreg


Message édité par LeGreg le 29-02-2008 à 20:18:29

---------------
voxel terrain render engine | animation mentor
n°510802
LeGreg
Posté le 09-09-2003 à 11:32:56  profilanswer
 

C'est en colorant le verre que l'on se rend le mieux
compte de la différence entre refraction et reflexion.
 
http://www.massal.net/article/raytrace/page5.html
 
LeGreg


Message édité par LeGreg le 29-02-2008 à 20:18:06

---------------
voxel terrain render engine | animation mentor
n°511311
LeGreg
Posté le 09-09-2003 à 22:37:43  profilanswer
 

Ben ça y est,  
 
je suis tout seul sur ce topic..
 
écho, écho.. cho.. oo
 
LeGreg

n°511326
*syl*
--&gt; []
Posté le 09-09-2003 à 22:48:18  profilanswer
 

legreg a écrit :

Ben ça y est,  
 
je suis tout seul sur ce topic..
 
écho, écho.. cho.. oo
 
LeGreg

Y'en a pas bcp qui parlent, c'est vrai mais y'en a pas mal qui le lisent, + de 2300 lectures, c'est pas mal :)

n°511426
Profil sup​primé
Posté le 10-09-2003 à 01:26:12  answer
 

En effet legreg, continue ce super topic même si pas mal comme moi suivent sans poster (par manque de compétences pour ma part), car c'est tout de même super interessant, et du beau boulot  :hello:

n°511675
Krueger
tout salaire demande dutravail
Posté le 10-09-2003 à 13:33:06  profilanswer
 

billyboy78 a écrit :

En effet legreg, continue ce super topic même si pas mal comme moi suivent sans poster (par manque de compétences pour ma part), car c'est tout de même super interessant, et du beau boulot  :hello:  

Idem. ;)


---------------
"Colère et intolérance sont les ennemis d'une bonne compréhension." Gandhi
n°511677
HelloWorld
Salut tout le monde!
Posté le 10-09-2003 à 13:36:25  profilanswer
 

Oui, je confirme.
Perso, je compte pas laisser ton travail s'évaporer comme ça...

n°511685
Harkonnen
Modérateur
Un modo pour les bannir tous
Posté le 10-09-2003 à 13:47:11  profilanswer
 

J'ai rajouté ce topic dans les liens utiles, section "Topics divers de programmation" ;)


---------------
J'ai un string dans l'array (Paris Hilton)
n°513877
LeGreg
Posté le 13-09-2003 à 11:14:07  profilanswer
 

Je sais ça traine, mais j'ai encore du sommeil en retard et pas mal de boulot.
 
Je ferai si j'ai le temps une petite update ce week-end.
 
A+
LeGreg

n°515539
LeGreg
Posté le 16-09-2003 à 11:30:24  profilanswer
 

Le photon mapping
 
Tout d'abord qu'est-ce que c'est ?
C'est une technique d'illumination globale accélèrée qui consiste à envoyer des photons dans la scène afin de simuler l'éclairage. C'est le procédé inverse de celui que l'on a appliqué jusqu'à présent puisque l'on partait du point d'observation jusqu'à la source de lumière. Maintenant on fait moitié/moitié.
 
Pourquoi parle-t- on de photon map (carte des photons) ? tout simplement parce que l'on va créer une structure spéciale qui va stocker les photons émis et qui ont rencontré une surface active.  
 
Cette carte est le coeur du photon mapping. à partir de celle-ci, on peut ensuite raytracer notre scène et extraire les infos d'illumination de notre photon map.
 
On procède donc en trois étapes :
Photon Tracing
Premièrement pour chaque source lumineuse (directe) de la scène on envoie des photons dans la scène. On traite ces photons de la même façon que l'on traitait les rayons transmis par raytracing, d`où le nom de photon tracing.
La différence c'est qu'à la place de calculer la contribution de chaque surface rencontrée, à chaque nouvelle surface qui n'est pas parfaitement réfléchissante ou réfractante, on stocke un photon dans la photon map.  
Il existe plusieurs variantes mais avec ce photon on va stocker par exemple la position où l'on a heurté la surface, la direction d'incidence sur cette surface, l'intensité du photon incident (on ne stocke pas la réponse de la surface que l'on traitera ensuite) et la normale à la surface (pour plus tard).
On a ensuite la possibilité de réémettre le photon depuis le point d'incidence qui agirait en quelque sorte comme une source de lumière secondaire ou indirecte. C'est indispensable si l'on veut rendre compte d'une lumìère réfléchie par un miroir (ce que le raytracing classique ne rend pas naturellement) C'est aussi indispensable pour rendre compte de l'interreflection, ou des caustiques.
 
Je traiterai cette partie plus en détail dans une autre update.
 
La création de la photon map
Cette liste de photons n'est pas très exploitable telle quelle.
On veut pouvoir localiser très rapidement quels sont les photons les plus proches d'un point donné de manière arbitraire.
Cette spatialisation de la carte des photons est un élément important et de l'éfficacité de laquelle dépendra la rapidité de l'étape suivante.  
 
On a plusieurs choix pour la localisation, en général les photons sont stockés de manière non homogène dans la scène donc une structure aux mailles adaptatives est préférable.
L'inventeur du photon mapping propose un KD tree. Qui est une sorte d'arbre binaire (BSP) mais dont les plans de séparation alternent les trois plans principaux de l'espace.
une telle structure a l'avantage d'etre compacte ce qui est sans doute la raison de son choix par Jensen.
 
Le rendu
 
Le choix pour le rendu est large. On ne va pas trop s'éloigner du raytracing pour cette série d'articles mais on peut imaginer utiliser la photon map dans d'autres circonstances.
 
Ce que l'on va faire sera de lancer des rayons mais lorsqu'on va heurter une surface non reflexive/refractive  
on va évaluer la radiance dans la direction du rayon vue incident, à partir des informations stockées dans la photon map.
On va complètement oublier combien de lumières on avait au début dans notre scene. On ne cherche pas spécialement non plus à savoir si l'on est dans l'ombre ou dans la pénombre, ce sont les informations stockées dans le prétraitement qui vont nous le dire.
 
L'évaluation de la radiance est une somme discrete sur la totalité des photons incidents de l'évaluation de la BRDF de cette surface.
 
Pour rappel, la BRDF = bidirectional reflectance distribution function. C'est à dire une évaluation de la lumière transmise dans une direction à partir de l'angle que font le rayon vue incident et le rayon lumineux incident. Les photons se prétent bien à une telle évaluation. Et plus on a de photons plus le modèle est précis.
 
Le modèle de Lambert par exemple est un exemple ultra simple de BRDF. Ce modèle ne dépend que de l'angle d'incidence de la lumière.  
 
Comment choisir les photons pour évaluer la radiance dans ce cas ? Il faut interroger notre photon map, qui grace a son pretraitement va nous donner les m photons les plus proches du point dont on cherche à évaluer l'illumination.
 
Bien évidemment tous les photons ne sont pas satisfaisant. Il faut les classer en fonction de la surface pour laquelle ils ont été stockés pour éviter de prendre des photons qui contribuent à l'éclairement d'une autre surface. il y a des raffinements divers et varies que je ne détaillerai pas.
 
Une fois nos m photons réunis. On évalue la radiance en fonction de l'intensité du photon incident, de l'angle de ce photon avec la surface et celui du rayon vue, puis on fait la somme de toutes ces contributions. Puis pour équilibrer un peu tout ça, on divise la somme par l'aire couverte par les photons pris en compte. On considère que localement la surface est plane et que les photons les plus proches sont tous issus de ce plan.
 
Bientot plus de détails sur chaque étape, des images et du code.
 
A+
LeGreg


Message édité par LeGreg le 16-09-2003 à 11:31:03
n°515547
LeGreg
Posté le 16-09-2003 à 11:48:16  profilanswer
 

Voici un exemple d'image obtenu par photon mapping.
 
Elle n'est pas représentative de ce que donnera le programme final parce qu'il y a très peu de photons envoyés et aucune mesure adaptative.
On constate notamment que les ombres sont floues. C'est l'un des inconvénient du photon mapping (c'est un défaut ici puisque la lumière est ponctuelle). Par mesure adaptative on entendrait dans ce cas, envoyer plus de photons aux endroits où il y a des ombres "dures" pour rendre mieux compte de la séparation. Toute chose égale par ailleurs, si l'on en envoie plus dans une direction il faut également baisser leur intensité.
 
http://www.massal.net/article/raytrace/page6.html
 
LeGreg


Message édité par LeGreg le 29-02-2008 à 20:19:18

---------------
voxel terrain render engine | animation mentor
n°515549
chrisbk
-
Posté le 16-09-2003 à 11:49:49  profilanswer
 


Hum y'a des trucs que je me demande :O
 

Citation :

Premièrement pour chaque source lumineuse (directe) de la scène on envoie des photons dans la scène. On traite ces photons de la même façon que l'on traitait les rayons transmis par raytracing, d`où le nom de photon tracing


 
 
-cbien de photons par source ?
 
 

Citation :

Comment choisir les photons pour évaluer la radiance dans ce cas ? Il faut interroger notre photon map, qui grace a son pretraitement va nous donner les m photons les plus proches du point dont on cherche à évaluer l'illumination


 
Pareil, comment tu decides qu'un photon et suffisament proche du point a evaluer ? un ptit peu au pif (genre un Epsilon finement choisi)  ou bien ?  

n°515553
LeGreg
Posté le 16-09-2003 à 11:56:43  profilanswer
 

chrisbk a écrit :


Hum y'a des trucs que je me demande :O
 
-cbien de photons par source ?


 
Tu te poses de mauvaises questions :D
 
Si tu augmentes le nombre de photons, leur importance
relative diminue d'autant.
 

chrisbk a écrit :


Pareil, comment tu decides qu'un photon et suffisament proche du point a evaluer ? un ptit peu au pif (genre un Epsilon finement choisi)  ou bien ?  


 
Je crois que je détaillerai plus tard, en gros
il n'y a pas de notion de "suffisamment proche", l'important c'est d'avoir les m les plus proches avec m fixe sinon les calculs d'intensité varient trop d'un point à l'autre.
 
A+
LeGreg
 
 
 

n°515555
chrisbk
-
Posté le 16-09-2003 à 12:01:53  profilanswer
 

legreg a écrit :


 
Tu te poses de mauvaises questions :D
 
Si tu augmentes le nombre de photons, leur importance
relative diminue d'autant.
 
 
 


 
disons que je me place dans le cas d'une omni. fo que t'envoies de la lumiere dans toutes les directions. Pour etre un tant soit peu precis (eg ne pas avoir qu'un photon tous les 5m) ca doit commencer a faire un sacré paquet de photons non ? Et au bout d'un moment surajouter des photons n'apportera plus rien. Vu qu'on est tous concernés par les temps de calcul, j'imagine que le choix du nombre de photons emis par source doit etre choisi finement pour avoir le meilleur compromis qualité/temps ?


Message édité par chrisbk le 16-09-2003 à 12:02:00
n°515566
LeGreg
Posté le 16-09-2003 à 12:19:44  profilanswer
 

chrisbk a écrit :


disons que je me place dans le cas d'une omni. fo que t'envoies de la lumiere dans toutes les directions. Pour etre un tant soit peu precis (eg ne pas avoir qu'un photon tous les 5m) ca doit commencer a faire un sacré paquet de photons non ? Et au bout d'un moment surajouter des photons n'apportera plus rien. Vu qu'on est tous concernés par les temps de calcul, j'imagine que le choix du nombre de photons emis par source doit etre choisi finement pour avoir le meilleur compromis qualité/temps ?


 
Oui et malheureusement ça dépendra de ta scène. Donc soit tu fais une estimation à la louche et tu te fiches du temps de rendu (de toute façon si ton moteur est aussi efficace que les meilleures implémentations de photon mapping, la qualité de rendu sera toujours incomparable à d'autres méthodes d'illumination globale rapporté au temps de calcul) soit tu essaies de fine tuner mais le temps que tu perds à ça serait aussi bien utilisé en rendu :).
 
La création du contenu à tracer aura aussi un impact, plus le fait que tu veuilles utiliser les interreflexions, les caustiques etc.. En general tu voudras concentrer tes photons la ou il risque d'y avoir du détail (caustiques), ce qui devra se faire à la main (indiquer quelle surface peut recevoir les caustiques et quel objet doit en etre la source).
 
LeGreg

n°518108
LeGreg
Posté le 19-09-2003 à 11:52:36  profilanswer
 

Noisy et Blurry sont dans un bateau (et sont les mammelles du photon mapping ;) )
 
http://www.massal.net/article/raytrace/page6.html
 
http://www.massal.net/article/raytrace/page6.html
 
L'avantage de Noisy c'est que les détails sont bien délimités  
en particulier l'image de la lumière principale par réfraction.
Il est aussi beaucoup plus rapide à calculer puisqu'on prend en compte moins de photons par element de surface.
 
L'avantage de blurry c'est qu'il est beaucoup plus doux à l'oeil et l'on oublierait presque que l'on a affaire a une source ponctuelle.
 
Quel est l'avantage par rapport au raytracing qui donnait de bien plus belles images jusqu'à maintenant ?
 
En fait à part l'image réfractée par la sphère transparente (caustique) on n'en voit pas pour l'instant surtout que les éclairages indirects sont limités aux photons réfléchis et réfractés.  
Le meilleur des mondes serait de combiner les deux:
éclairage direct avec la méthode du raytracer et éclairage indirect (caustique, interreflexion) avec la méthode du photon mapping.  
 
Plus de blabla avec du code bientot..
 
Grégory
ps: l'éspece de fumée grisatre dans la sphere transparente sont en fait des reflets spéculaires. La lumière en passant dans la sphère y laisse quelques photons.


Message édité par LeGreg le 29-02-2008 à 20:19:41

---------------
voxel terrain render engine | animation mentor
n°518772
LeGreg
Posté le 20-09-2003 à 12:40:41  profilanswer
 

l'envoi de photons
 
Pour envoyer des photons on part de chaque source lumineuse et l'on envoie dans toutes les directions possibles pour cette source en particulier.
C'est à dire, on se dit au départ que l'on va envoyer x photons. On veut avoir une intensité constante pour chaque photon pour éviter les problèmes plus tard donc on va pour chaque photon (à intensité fixe) déterminer de quelle source il va partir et dans quelle direction il va aller. Cela revient à faire la somme des intensités des lumières de la scène, tirer un nombre aléatoire rapporté à cette somme et choisir la lumìère de départ en fonction de ce nombre.  
 
Ex: 2 lumières d'intensité 60 et 20.
La somme est égale a 80. On tire un nombre entre 0 et 80 et si ce nombre est entre 0 et 60 on choisit la première lumière et si le nombre est entre 60 et 80 on choisit la seconde. Aussi simple que ça. C'est toujours le même principe de roulette russe que l'on a appliqué jusque là.
 
Le cas de la source ponctuelle
 
Pour l'instant on se limite aux sources ponctuelles. Donc une fois que l'on a choisi la source lumineuse d'où partira le photon, il faut déterminer dans quelle direction il faut le faire partir.  
Joie, la probabilité est identique dans toutes les directions. Par contre pas de bol, il faut raisonner équiprobabilité en terme d'angles sur la sphère.
La solution c'est de rapporter notre tirage aléatoire à la sphère unité en utilisant un truc.
Le premier truc c'est de tirer un vecteur de trois nombres aléatoires indépendants compris dans un volume cubique comprenant la sphère unité. Tirer ce vecteur est facile, chaque coordonnée est un nombre aléatoire entre [-1,1].
Ensuite on détermine si ce vecteur est inclu dans la sphère unité. c'est à dire que sa norme au carré est inférieure à 1.
Si il ne l'est pas, ce n'est pas grave, on jette ce nombre et on en prend un autre jusqu'à ce que ça marche.
 
Bien évidemment avant d'en faire la direction de notre rayon, on normalise derrière. On a ainsi la garantie d'un tirage équiprobable (isotrope) en terme d'angle sur la sphère unité.
 
Voici le code correspondant :
 

Code :
  1. ray viewRay;       
  2. do
  3. {
  4.     viewRay.dir.x = (2.0f / RAND_MAX) * rand() - 1.0f;
  5.     viewRay.dir.y = (2.0f / RAND_MAX) * rand() - 1.0f;
  6.     viewRay.dir.z = (2.0f / RAND_MAX) * rand() - 1.0f;
  7. }
  8. while  (viewRay.dir.x *viewRay.dir.x + viewRay.dir.y * viewRay.dir.y + viewRay.dir.z * viewRay.dir.z > 1.0f );
  9. float temp = viewRay.dir * viewRay.dir;
  10. if (temp == 0.0f)
  11.     continue;
  12. viewRay.dir = invsqrtf(temp) * viewRay.dir;
  13. viewRay.start = myScene.lgtTab[lightNumber].pos;
  14. if (!addPhotonRay(viewRay, myScene, myContext, channelPhotonMap[offset], coef))
  15. {
  16.     break;
  17. };


 
La représentation d'un photon
 
Voici la struct représentant un photon en mémoire :

Code :
  1. struct photon
  2. {
  3.     point pos;
  4.     vecteur dir ;
  5.     float wattage;
  6.     // DWORD flag;  
  7. };


 
La position c'est l'endroit où le rayon lumineux a rencontré un objet qui intéragit avec la lumière de manière non limité à un simple transfert (non limité à une simple réflexion ou réfraction).
La direction c'est le vecteur d'incidence du photon sur cet objet. Le wattage est l'intensité du photon juste avant d'arriver à ce point. Ce point est important puisque c'est ce qui permet de garantir l'indépendance des calculs d'illumination.
Un wattage bas va en fait avoir un effet négatif sur l'intensité sur une surface donnée. Dans l'idéal on voudrait que l'intensité incidente dépende uniquement du nombre de photons arrivés par unité de surface.
 
Le flag optionnel c'est pour plus tard, au cas où l'on veut savoir si un photon est actuellement passé par une réflexion, réfraction, s'il est marqué comme "photon d'ombre" (une aide au calcul d'ombre et de pénombre) etc...
 
Le cache à photons
 
Les photons quand ils arrivent sont stockés dans un container spécialisé.  
J'appelle ça un cache à photon. Qui comprend trois composants:
- le container à photon lui-même, un simple vector<photon>.
- Le container à normales qui permet de ne pas rapprocher des photons qui seraient arrivés sur des surfaces perpendiculaires (exemple sur un mur à angle droit, les photons qui heurtent le premier mur ne doivent pas être comptés comme ceux qui heurtent le deuxieme mur). C'est de même un simple vector<vecteur>.
- Enfin, un arbre. Cet arbre est issu de l'équilibrage sur place du container à photons initial. C'est la structure qu'on appelle un KD-Tree. C'est à dire que c'est un arbre avec des noeuds et chaque noeud représente une partition de l'ensemble des photons selon un plan médian auquel appartient systématiquement l'un des photons. Les plans sont dirigés selon les axes, donc on a juste à stocker quel dimension a été divisisée en deux puis quelle coordonée est considérée comme médiane dans cette direction.
 
cela se fait avec un noeud du type :

Code :
  1. struct kdnode{
  2.         enum {
  3.             dimensionX = 0,
  4.             dimensionY = 1,
  5.             dimensionZ = 2
  6.         } dimensionPlane;
  7.         // float fCoordinatePlane;
  8.         int nPhotonMedian;
  9.     };


 
L'information fCoordinatePlane est déjà comprise dans l'information nPhotonMedian donc on peut s'en débarrasser.
 
nPhotonMedian est un index qui pointe dans le conteneur à photons sur l'élement dont la coordonnée divise notre ensemble en deux. Bien entendu après avoir équilibré l'arbre on ne touche plus au container à photons.
 
Voici le cache dans toute sa splendeur.. Simplicité avant tout.
 

Code :
  1. class photoncache
  2. {
  3. public:
  4.     vector<photon> photonTab;
  5.     vector<vecteur> normalTab;
  6.     vector<kdnode> nodeTab;
  7.     void balance(vector<int>& tab, int p);
  8.     bool bBalanced;
  9. };


 
Je reviendrai sur la fonction balance..
 
Pendant le tracé de photons, à chaque fois que l'on veut balancer un photon on se contente d'appeler addPhoton sur la photon Map.
 
Voici la fonction addPhoton:

Code :
  1. bool photonmap::addPhoton (const photon & newPhoton, const vecteur & normal)
  2. {
  3.     if (!container)
  4.         return false;
  5.     if (int(container->photonTab.size()) >= number )
  6.         return false;
  7.     container->photonTab.push_back(newPhoton);
  8.     container->normalTab.push_back(normal);
  9.     return true;
  10. }


 
Le seul truc à retenir c'est qu'il renvoie false quand il n'y a plus de place dans le container à photons.
 
La fonction photon trace
 
Le tracé de photons est une version simplifiée
du tracé de rayons vue. La principale différence c'est qu'on
zappe la partie calcul d'éclairement. On ne calcule plus ici le coefficient de transfert explicitement; on se contente de tirer à la roulette russe si le photon est transmis ou absorbé et selon quelle méthode il est transmis.
 

Code :
  1. bool addPhotonRay(ray viewRay, scene &myScene, context myContext, photonmap& myPhotonMap)
  2. {
  3.     int level = 0;
  4.     do {
  5.         point ptHitPoint;
  6.         float t = 20000.0f;
  7.         int currentSphere=-1;
  8.         {
  9.             for (unsigned int i = 0; i < myScene.sphTab.size() ; ++i) {
  10.                 if (isSphereIntersected(viewRay, myScene.sphTab[i], t)) {
  11.                     currentSphere = i;
  12.                 }
  13.             }
  14.             if (currentSphere == -1)
  15.             {
  16.                 break; // Le photon s'est perdu dans l'espace infini, arretons de stocker des photons;
  17.             }
  18.             ptHitPoint  = viewRay.start + t * viewRay.dir;
  19.         }
  20.         // la normale au point d'intersection  
  21.         vecteur vNormal = ptHitPoint - myScene.sphTab[currentSphere].pos;
  22.         float temp = vNormal * vNormal;
  23.         if (temp == 0.0f)
  24.             break;
  25.         vNormal = invsqrtf(temp) * vNormal;
  26.         materialChannel currentMat = myScene.matTab[myScene.sphTab[currentSphere].material].tab[myContext.offset];
  27.         float bInside;
  28.         if (vNormal * viewRay.dir > 0.0f)
  29.         {
  30.             vNormal = -1.0f * vNormal;
  31.             bInside = true;
  32.         }
  33.         else
  34.         {
  35.             bInside = false;
  36.         }
  37.         if (myScene.sphTab[currentSphere].size < 0.0f)
  38.         {
  39.             bInside = !bInside;
  40.         }
  41.         if (myContext.fTransmittance != 1.0f)
  42.         { 
  43.             // la lumière transmise dans le médium transparent
  44.             // est affectée par la diffusion due aux impuretés
  45.             // la beer's law s'applique pour les faibles concentrations
  46.             float coef = powf(myContext.fTransmittance, t);
  47.             float fRoulette = (1.0f / RAND_MAX) * rand();
  48.             if (fRoulette > coef )
  49.             {
  50.                 // Le photon s'est retrouvé absorbé avant d'arriver au point d'intersection.
  51.                 // On peut juste s'arreter de stocker des photons
  52.                 break;
  53.             }
  54.         }
  55.         float fViewProjection = viewRay.dir * vNormal;
  56.         float fReflectance, fTransmittance;
  57.         float fCosThetaI, fSinThetaI, fCosThetaT, fSinThetaT;
  58.         // ici je zappe pour le forum mais on calcule la reflectance et la transmittance
  59.         // comme avant..
  60.         fTransmittance = currentMat.refraction * (1.0f - fReflectance);
  61.         fReflectance = currentMat.reflection * fReflectance;
  62.         float fTotalWeight = fReflectance + fTransmittance;
  63.         if (fTotalWeight < 0.99f)
  64.         {
  65.             // La surface n'est pas totalement transitive, on peut stocker le photon incident
  66.             photon currentPhoton; // {ptHitPoint, viewRay.dir, coef};  
  67.             currentPhoton.pos = ptHitPoint;
  68.             currentPhoton.dir = viewRay.dir;
  69.             if (!myPhotonMap.addPhoton(currentPhoton, vNormal))
  70.             {
  71.                 // Le container a photon a atteint ses limites.
  72.                 // On peut juste s'arreter de stocker des photons
  73.                 return false
  74.             };
  75.         }
  76.         // ça devrait être la réfractance totale de la BRDF locale  
  77.         // plutot que ce parametre diffuse1 qui ne correspond à rien.
  78.         fTotalWeight = fTotalWeight + currentMat.diffuse1; 
  79.         float fRoulette = ( fTotalWeight / RAND_MAX) * rand();
  80.         if (fRoulette <= fReflectance)
  81.         {
  82.             // Le rayon viewRay est réflechi par la normale.
  83.             // Pour calculer le rayon refléchi on fait la projection
  84.             // du vecteur direction du rayon vue
  85.             // sur la direction de la normale.
  86.             // Pour avoir le vecteur tangent il faudrait retrancher
  87.             // cette projection au vecteur direction
  88.             // mais ici on veut la reflexion et donc il faut retrancher
  89.             // la projection deux fois au vecteur direction.
  90.             float fReflection = 2.0f * fViewProjection;
  91.             // on fait partir le nouveau rayon du point d'intersection avec la sphère courante
  92.             // et on le dirige selon le vecteur reflexion que l'on vient de calculer
  93.             viewRay.start = ptHitPoint;
  94.             viewRay.dir += fReflection * vNormal;
  95.         }
  96.         else if(fRoulette <= fReflectance + fTransmittance)
  97.         {
  98.             float fOldRefractionCoef = myContext.fRefractionCoef;
  99.             if (bInside)
  100.             {
  101.                 myContext.fRefractionCoef = context::getDefaultAir().fRefractionCoef;
  102.                 myContext.fTransmittance = context::getDefaultAir().fTransmittance;
  103.             }
  104.             else
  105.             {
  106.                 myContext.fRefractionCoef = currentMat.density;
  107.                 myContext.fTransmittance = currentMat.absorption;
  108.             }
  109.             // ici on calcule le rayon transmis avec la formule de Snell-Descartes
  110.             viewRay.start = ptHitPoint;
  111.             viewRay.dir += fCosThetaI * vNormal;
  112.             viewRay.dir = (fOldRefractionCoef / myContext.fRefractionCoef) * viewRay.dir;
  113.             viewRay.dir += (-fCosThetaT) * vNormal;
  114.         }
  115.         // else .. utiliser la brdf pour déterminer dans quelle direction renvoyer le photon
  116.         else
  117.         {
  118.             // notre BRDF nous dit que le photon est soit réflechi soit réfracté
  119.             // soit absorbé.. Pas de color bleeding dû à la diffusion.. pour l'instant
  120.             break;
  121.         }
  122.         level++;
  123.     } while (level < 10); 
  124.     return true;
  125. }


 
Le code devrait être assez explicit surtout qu'il reprend beaucoup du code du raytracer précédent.
 
Tout pour cette nuit,
la suite bientôt.
 
A+
LeGreg

n°519245
LeGreg
Posté le 20-09-2003 à 22:39:13  profilanswer
 

http://www.massal.net/article/raytrace/page6.html
 
On arrive à faire deux types d'effets actuellement avec notre méthode de photon mapping.
 
La première est illustrée par la sphère bleue transparente. Elle transmet la lumière qui la traverse mais en la colorant en bleu et en la concentrant (c'est une lentille sphérique).
Question subsidiaire : pourquoi les bords de la tache bleue issue de la réfraction sont plus lumineux que son centre ?  
Tout simplement parce que la lumière a parcouru plus de médium absorbant en passant par le centre de la sphère qu'en passant sur les bords. Les photons qui sont passés par le centre ont été décimés (grâce à la formule de Beer que j'ai expliqué ici même).
 
La deuxième est illustrée par la sphère rouge totalement réflexive. Elle ne réfléchit que les photons rouges. Elle envoie donc dans le décor tous les photons rouges qui la heurtent et l'effet secondaire c'est que les matériaux environnants sont légèrement teintés de rouge (mais c'est très subtil sur cette image). Ce serait plus visible si comme la lentille bleue, l'objet réflechissant concentrait la lumière à la place de la disperser encore plus.
 
A+
LeGreg


Message édité par LeGreg le 29-02-2008 à 20:20:04

---------------
voxel terrain render engine | animation mentor
n°520355
Krueger
tout salaire demande dutravail
Posté le 22-09-2003 à 13:54:18  profilanswer
 

Très intéressant, sauf qu'il faudrait corriger les problèmes de saturation et d'effet bruité de la boule bleue.


---------------
"Colère et intolérance sont les ennemis d'une bonne compréhension." Gandhi
mood
Publicité
Posté le   profilanswer
 

 Page :   1  2  3  4  5  6  7  8  9  10

Aller à :
Ajouter une réponse
 

Sujets relatifs
c koi un nombre entier en base octale ou hexadécimale ??Phpbb et base de données
Formulaire de modification d'une base mysqlTransformer/Intégrer un XLS dans une base SQL/mySQL
[PHP] question de base sur la structure du if...then...else ?[SGBD] Base de données sans serveur ?
ResourceBundle basé sur un fichier situé à une url spécifiqueformulaire --> direction email à la place de la base mySQL
Temps de transfert Base Access ...SQL serveurplacé un element sous plusieurs catégorie dans une base de donnéés
Plus de sujets relatifs à : Article: un raytracer de base en C++


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR