Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
672 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°520355
Krueger
tout salaire demande dutravail
Posté le 22-09-2003 à 13:54:18  profilanswer
 

Reprise du message précédent :
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 22-09-2003 à 13:54:18  profilanswer
 

n°520582
LeGreg
Posté le 22-09-2003 à 19:35:31  profilanswer
 

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  
 
Voici une scene similaire avec uniquement du raytracing :
http://www.massal.net/article/raytrace/page6.html
 
et la meme scene en combinant raytracing pour les lumieres directes et photontracing pour les lumieres indirectes:
http://www.massal.net/article/raytrace/page6.html
 
A+
LeGreg


Message édité par LeGreg le 12-07-2008 à 00:03:18

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

Krueger a écrit :

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


 
Salut
 
de quelle saturation parles-tu ?
a ma connaissance il n'y a pas (trop) de saturation dans ces images cf explication sur le tone mapping plus haut, le fond est censé être blanc, c'est sa vraie couleur.
 
Pour ce qui est de l'effet bruité de la boule bleue j'ai expliqué comment réduire le bruit causé par l'importance sampling ici meme. Mais je n'ai pas appliqué la méthode pour que le temps de rendu soit raisonnable (et ce n'était pas le point de l'image sur lequel je voulais insister).
 
D'autres questions ou ce que j'ai dit n'était pas clair ?
 
LeGreg

n°521174
LeGreg
Posté le 23-09-2003 à 12:38:56  profilanswer
 

Pour ceux qui se demandent, le fond blanc est une sphère vue de
l'intérieur :)
et oui comme je suis très paresseux je n'ai toujours pas implémenté l'intersection rayon/plan (une ligne de code !).
Philosophiquement je me dédouane en disant que l'on suppporte les plans puisque l'on supporte les sphères de rayon très très grand :). (et une sphère très très grande est localement assimilable à son plan tangent).  
 
Plus sur la fonction balance
 
Que se passe-t-il une fois que l'on a rajouté les photons dans le cache à photon ?  
Il faut les ranger, de manière à ce qu'ils soient directement accessibles ensuite par le raytracer.  
 
Comment les range-t-on ? j'ai déja évoqué le principe du KD tree. C'est un arbre tel que pour chaque noeud on a une dimension de subdivision et un plan qui coupe l'espace en deux et qui est orthogonal à cette direction.
 
Ainsi, suivant l'endroit où l'on se trouve par rapport à ce plan, on sait si l'on est plus proche des photons stockés à droite ou les photons stockés à gauche (en haut, en bas, en avant ou en arrière).
 
Il ne suffit pas d'avoir autant de plans que nécessaires pour n'avoir plus qu'un seul photon par feuille de l'arbre. Il faut aussi que l'arbre soit équilibré pour que son parcours soit optimal.
 
Comment équilibrer l'arbre ? c'est simple, on le fait à la construction. Soit l'ensemble de n photons qui définit un parallélépipède rectangle parallèle aux axes. On détermine quelle est la plus grande dimension de ce parallélépipède. Ce sera la dimension de notre subdivision. Ensuite on trie les photons de cet ensemble selon la ieme coordonnée correspondant à la dimension de subdivision. Une fois qu'ils sont triès on prend le photon médian (correspondant à n/2 dans l'ordre défini plus haut). Ce photon définira le plan médian et les photons d'un coté et de l'autre de ce photon iront dans la première branche ou la deuxième branche de l'arbre.
 
Comme on a expliqué, un kd tree est très compact. Il n'y a pas besoin de pointeurs vers les branches de l'arbre. les noeuds sont rangés dans un vecteur de manière simple. Le noeud p a deux fils 2 * p et 2 * p + 1. On commence le noeud racine pour p = 1.
Un noeud contient juste la dimension de subdivision du noeud et l'index du photon médian. C'est l'un des formats d'arbre les plus compacts que l'on puisse avoir. si l'on voulait quelque chose de plus compact encore on pourrait stocker la dimension de subdivision de manière implicite (en alternant x, y et z).  
 
Voici le code de la fonction balance.
 

Code :
  1. template<int n> struct sortingCriterion
  2. {
  3.     photon *photonTab;
  4.     bool operator() (int p1, int p2)
  5.     {
  6.         if (n == kdnode::dimensionX)
  7.         {
  8.             return photonTab[p1].pos.x < photonTab[p2].pos.x;
  9.         }
  10.        
  11.         if (n == kdnode::dimensionY)
  12.         {
  13.             return photonTab[p1].pos.y < photonTab[p2].pos.y;
  14.         }
  15.        
  16.         if (n == kdnode::dimensionZ)
  17.         {
  18.             return photonTab[p1].pos.z < photonTab[p2].pos.z;
  19.         }
  20.     }
  21. };
  22. void photoncache::balance(vector<int>& tab, int p)
  23. {
  24.     // il n'y a plus rien à équilibrer
  25.     if (tab.size() == 0)
  26.         return;
  27.     vector<int> tabLess;
  28.     vector<int> tabMore;
  29.     // tant que l'on n'atteint pas la taille d'un arbre déraisonnable
  30.     if (2 * p + 1 < 100 * int(photonTab.size()))
  31.     {
  32.         kdnode node;
  33.         node.nPhotonMedian = -1;
  34.         if (tab.size() == 1)
  35.         {
  36.             node.nPhotonMedian = tab[0];
  37.         }
  38.         else
  39.         {
  40.             float minX, minY, minZ;
  41.             float maxX, maxY, maxZ;
  42.             minX = minY = minZ = numeric_limits<float>::max();
  43.             maxX = maxY = maxZ = - numeric_limits<float>::max();
  44.             tabLess.reserve(tab.size());
  45.             tabMore.reserve(tab.size());
  46.             for (int i = 0; i < int(tab.size()); ++i)
  47.             {
  48.                // calcul d'un parallélépipède rectangle
  49.                 minX = min(minX, photonTab[tab[i]].pos.x);
  50.                 minY = min(minY, photonTab[tab[i]].pos.y);
  51.                 minZ = min(minZ, photonTab[tab[i]].pos.z);
  52.                 maxX = max(maxX, photonTab[tab[i]].pos.x);
  53.                 maxY = max(maxY, photonTab[tab[i]].pos.y);
  54.                 maxZ = max(maxZ, photonTab[tab[i]].pos.z);
  55.             }
  56.             if ( maxX - minX >= maxY - minY )
  57.             {
  58.                 if (maxX - minX >= maxZ - minZ)
  59.                 {
  60.                     node.dimensionPlane = kdnode::dimensionX;
  61.                     sortingCriterion<kdnode::dimensionX> pred = {&photonTab[0]};
  62.                     // on trie  
  63.                     sort(tab.begin(), tab.end(), pred);
  64.                     node.nPhotonMedian = tab[int(tab.size()) / 2];
  65.                     // puis on distribue.. à droite puis à gauche
  66.                     for (int i = 0; i< int(tab.size()) / 2; ++i)
  67.                     {
  68.                             tabLess.push_back(tab[i]);
  69.                     }
  70.                     for (int i = int(tab.size()) / 2 + 1; i< int(tab.size()); ++i)
  71.                     {
  72.                             tabMore.push_back(tab[i]);
  73.                     }
  74.                 }
  75.                 else
  76.                 {
  77.                     node.dimensionPlane = kdnode::dimensionZ;
  78.                     sortingCriterion<kdnode::dimensionZ> pred = {&photonTab[0]};
  79.                     sort(tab.begin(), tab.end(), pred);
  80.                     node.nPhotonMedian = tab[int(tab.size()) / 2];
  81.                     for (int i = 0; i< int(tab.size()) / 2; ++i)
  82.                     {
  83.                             tabLess.push_back(tab[i]);
  84.                     }
  85.                     for (int i = int(tab.size()) / 2 + 1; i< int(tab.size()); ++i)
  86.                     {
  87.                             tabMore.push_back(tab[i]);
  88.                     }
  89.                 }
  90.             }
  91.             else
  92.             {
  93.                 if (maxY - minY >= maxZ - minZ)
  94.                 {
  95.                     node.dimensionPlane = kdnode::dimensionY;
  96.                     sortingCriterion<kdnode::dimensionY> pred = {&photonTab[0]};
  97.                     sort(tab.begin(), tab.end(), pred);
  98.                     node.nPhotonMedian = tab[int(tab.size()) / 2];
  99.                     for (int i = 0; i< int(tab.size()) / 2; ++i)
  100.                     {
  101.                             tabLess.push_back(tab[i]);
  102.                     }
  103.                     for (int i = int(tab.size()) / 2 + 1; i< int(tab.size()); ++i)
  104.                     {
  105.                             tabMore.push_back(tab[i]);
  106.                     }
  107.                 }
  108.                 else
  109.                 {
  110.                     node.dimensionPlane = kdnode::dimensionZ;
  111.                     sortingCriterion<kdnode::dimensionZ> pred = {&photonTab[0]};
  112.                     sort(tab.begin(), tab.end(), pred);
  113.                     node.nPhotonMedian = tab[int(tab.size()) / 2];
  114.                     for (int i = 0; i< int(tab.size()) / 2; ++i)
  115.                     {
  116.                             tabLess.push_back(tab[i]);
  117.                     }
  118.                     for (int i = int(tab.size()) / 2 + 1; i< int(tab.size()); ++i)
  119.                     {
  120.                             tabMore.push_back(tab[i]);
  121.                     }
  122.                 }
  123.             }
  124.         }
  125.         if (p >= int(nodeTab.size()) )
  126.             nodeTab.resize(p + 1);
  127.         nodeTab[p] = node;
  128.     }
  129.     // continue à équilibrer dans la premiere branche
  130.     balance(tabLess, 2 * p);
  131.     // continue à équilibrer dans la deuxième branche
  132.     balance(tabMore, 2 * p + 1);
  133. }


 
Elle n'est pas optimisée en consommation mémoire on pourrait ne pas allouer les vecteur intermédiaire et limiter la recursion. Mais à ce stade on s'en fiche ce n'est pas ce qui coute le plus cher dans notre programme de photon/raytracing.
J'utilise le tri standard de la STL, avec un critère template dépendant de la dimension. Rien de bien folichon.
 
La localisation des photons les plus proches
 
On doit trouver les m photons les plus proches de notre point d'intersection. Comment obtenir ça à partir de notre KD tree?
 
C'est simple. Pour chaque branche que l'on parcourt on ajoute le photon médian dans une liste triée selon la distance à notre point de départ. On s'assure constamment que la taille de la liste soit inférieure à m. Une fois que l'on a m éléments on ne s'arrete pas mais on continue notre parcours de l'arbre.
Bien entendu on ne parcourt pas la totalité de l'arbre ce qui serait malvenu vu que ça nous couterait plus cher que de parcourir la liste des photons en entier. Une fois que l'on a m éléments on peut déjà savoir quelle est la distance (au carré) maximale qu'un photon doit avoir pour etre pris.
Il ne sert donc à rien de parcourir les branches dont le plan médian indique qu'elles sont plus loin que la distance maximale de notre point de départ. C'est ce qu'on appelle du pruning (élagage) et qui nous garantit que l'algo de recherche sera optimal.
Bien entendu tant que l'on n'a pas trouvé m photons il y a un risque que l'on parcourt trop de branches de photons dont on n'aura pas besoin, on va donc limiter notre distance de recherche de départ (à 10000.0f ici mais on pourrait calculer une valeur adaptée à chaque ensemble de photons).
 
Voici le code de locate photons:
 

Code :
  1. void photonmap::locatePhotons (const point& pos, int nPhotons, std::map<float,int> &priorityHeap, int firstNode)
  2. {
  3.     photon * photonTab = &container->photonTab[0];
  4.     kdnode * nodeTab = &container->nodeTab[0];
  5.     // si l'on a pas dépassé la taille de notre arbre
  6.     if (2 * firstNode + 1 < int(container->nodeTab.size())) 
  7.     {
  8.             // il y a parfois des noeuds vides en fin de branche
  9.             // dans ce cas le photon médian est marqué à -1
  10.             if (nodeTab[firstNode].nPhotonMedian >= 0)
  11.             {
  12.             int currentPhoton = nodeTab[firstNode].nPhotonMedian;
  13.             point ptPhotonPos = photonTab[currentPhoton].pos;
  14.             vecteur vDistToPhoton = pos - ptPhotonPos;
  15.             float fDistSquare = vDistToPhoton * vDistToPhoton;
  16.             if (int(priorityHeap.size()) == nPhotons )
  17.             {
  18.                 if ( (*priorityHeap.rbegin()).first > fDistSquare)
  19.                 {
  20.                     priorityHeap.erase((*priorityHeap.rbegin()).first);
  21.                     priorityHeap[fDistSquare] = currentPhoton;
  22.                 }
  23.             }
  24.             else
  25.             {
  26.                 priorityHeap[fDistSquare] = currentPhoton;
  27.             }
  28.             float fDist = 0.0f;
  29.             switch (nodeTab[firstNode].dimensionPlane)
  30.             {
  31.             case kdnode::dimensionX:
  32.                 fDist = pos.x - ptPhotonPos.x;
  33.                 break;
  34.             case kdnode::dimensionY:
  35.                 fDist = pos.y - ptPhotonPos.y;
  36.                 break;
  37.             case kdnode::dimensionZ:
  38.                 fDist = pos.z - ptPhotonPos.z;
  39.                 break;
  40.             }
  41.             if (fDist <= 0.0f)
  42.             {
  43.                 float fDistSquare = fDist * fDist;
  44.                 locatePhotons(pos, nPhotons, priorityHeap, 2 * firstNode);
  45.                 if ( 10000.0f >= fDistSquare && (!(int(priorityHeap.size()) == nPhotons ) || ((*priorityHeap.rbegin()).first >= fDistSquare)))
  46.                 {
  47.                     locatePhotons(pos, nPhotons, priorityHeap, 2 * firstNode + 1);
  48.                 }
  49.             }
  50.             else
  51.             {
  52.                 float fDistSquare = fDist * fDist;
  53.                 locatePhotons(pos, nPhotons, priorityHeap, 2 * firstNode + 1);
  54.                 if ( 10000.0f >= fDistSquare && (!(int(priorityHeap.size()) == nPhotons ) || ((*priorityHeap.rbegin()).first >= fDistSquare)))
  55.                 {
  56.                     locatePhotons(pos, nPhotons, priorityHeap, 2 * firstNode);
  57.                 }
  58.             }
  59.         }
  60.     }
  61. }


 
La pour garantir que notre liste de photons déjà trouvés est triee on utilise encore un map<float, int>. (il n'y a pas obligation de garantir qu'elle soit triee, on peut se contenter de pouvoir localiser rapidement l'objet le plus distant et le remplacer par un moins distant).
 
Voici enfin le code de la fonction find nearest photons :
 

Code :
  1. int photonmap::findNearestPhotons (const point& pos, const vecteur & normal, float maxAngle, int nPhotons, photon * resultTab )
  2. {
  3.     float fMinCos = fabsf(cosf(maxAngle));
  4.     map<float, int> priorityHeap;
  5.     locatePhotons(pos, nPhotons, priorityHeap, 1);
  6.     int i = 0;
  7.     photon * photonTab = &container->photonTab[0];
  8.     vecteur * normalTab = &container->normalTab[0];
  9.     for (map<float, int>::const_iterator it =priorityHeap.begin(); it != priorityHeap.end(); ++it)
  10.     {
  11.         if ((normalTab[(*it).second] * normal > fMinCos) && (photonTab[(*it).second].dir * normal < 0.0f) )
  12.         {
  13.             resultTab[i] = container->photonTab[(*it).second];
  14.             ++i;
  15.         }
  16.         if (i >= nPhotons)
  17.             break;
  18.     }
  19.     return i;
  20. }


 
La boucle à la fin remplit notre résultat container à photon. Il ne retourne pas tous les photons à l'envoyeur, seuls ceux qui sont considérés comme "compatibles" sont renvoyés (ceux qui ne donneront pas une luminosité de zéro ou ceux qui ont été stockés pour une surface similaire à celle que l'on cherche à évaluer).
 
Any questions ?
 
LeGreg


Message édité par LeGreg le 23-09-2003 à 12:39:57
n°522232
e-TE
Posté le 24-09-2003 à 15:13:20  profilanswer
 

drapo pour quand j'aurais le temps de tout lire ^^

n°522481
LeGreg
Posté le 24-09-2003 à 19:18:24  profilanswer
 

bon après cet interméde sur le photon mapping
(pour ceux qui veulent creuser il y a le bouquin de Jensen, plus d'autres articles sur le Net).
 
je pensais brancher vers la modélisation à base d'opérations binaires sur les ensembles aussi appelé Constructive solid geometry (CSG).
 
A+
LeGreg

n°522546
Tetedeienc​h
Head Of God
Posté le 24-09-2003 à 20:10:52  profilanswer
 

a quand la version temps réel vendue des miyons a Nvidia :whistle:


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°523589
LeGreg
Posté le 25-09-2003 à 22:17:57  profilanswer
 

http://graphics.ucsd.edu/papers/photongfx/
 
C'est en partie financé par Nvidia
mais ils sont pas encore millionaires
(les auteurs du papier)
 
LeGreg

n°523690
Tetedeienc​h
Head Of God
Posté le 26-09-2003 à 07:22:20  profilanswer
 

C'était un compliment... rooooh.


---------------
L'ingénieur chipset nortiaux : Une iFricandelle svp ! "Spa du pâté, hin!" ©®Janfynette | "La plus grosse collec vivante de bans abusifs sur pattes" | OCCT v12 OUT !
n°523707
LeGreg
Posté le 26-09-2003 à 08:45:40  profilanswer
 

No offense :)
mais c'est pas demain que je serai milliardaire :D
 
LeGreg

mood
Publicité
Posté le 26-09-2003 à 08:45:40  profilanswer
 

n°527716
LeGreg
Posté le 01-10-2003 à 11:57:58  profilanswer
 

Bon désolé pour le manque d'update
le CSG arrive bientot promis
 
Je n'ai pas trop eu encore le temps d'y penser
bcoz quelques coups de bourres à la boite et puis j'ai aussi une vie en dehors de la prog ;) .
 
Cependant j'espere que vous avez digéré les morceaux précédents..
(pas eu de questions techniques bizarre..)
 
LeGreg

n°527747
HelloWorld
Salut tout le monde!
Posté le 01-10-2003 à 13:11:46  profilanswer
 

J'ai commencé à tout reprendre depuis le début perso... En ce moment j'ai pas trop de temps libre alors je vais doucement.


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°754906
HelloWorld
Salut tout le monde!
Posté le 07-06-2004 à 15:01:35  profilanswer
 

J'avais commencé à l'écrire en .Net...
http://www.codeproject.com/netcf/cfrt_article.asp


---------------
FAQ fclc++ - FAQ C++ - C++ FAQ Lite
n°758699
LeGreg
Posté le 10-06-2004 à 05:29:34  profilanswer
 

ahem..
 
ce topic est mort.
 
Mais que fait son auteur ?

n°759890
Dion
Acceuil
Posté le 10-06-2004 à 23:22:31  profilanswer
 

LeGreg a écrit :

ahem..
 
ce topic est mort.
 
Mais que fait son auteur ?


 
on se le demande :whistle:


---------------
When it comes to business/legal topics, just assume almost everyone commenting has no idea what they’re taking about and have no background in these subjects because that’s how it really is. Harkonnen 8-> Elmoricq 8====>
n°761297
Yttrium
Furtif
Posté le 12-06-2004 à 16:48:26  profilanswer
 

Wouaww !! C'est du caviar en tranches, ce topic !!
 
:D

n°762393
cedricbrun
Posté le 14-06-2004 à 08:06:50  profilanswer
 

Super topic, bravo !


---------------
<Chipo> Tortoose : je te garanti que ça marche <naf> vi ça marche c une solution merci <Chipo> Tortoose : de rien ;)
n°765219
fel
Posté le 16-06-2004 à 01:42:52  profilanswer
 

LeGreg: Il serait possible d'avoir ton e-mail afin de discuter Raytracing plus en profondeur ? Sinon bravo, super topic !

n°765255
cedricbrun
Posté le 16-06-2004 à 08:57:32  profilanswer
 

fel a écrit :

LeGreg: Il serait possible d'avoir ton e-mail afin de discuter Raytracing plus en profondeur ? Sinon bravo, super topic !


Il pourrait être intéressant pour tout le monde que vous discutiez ici non ?


---------------
<Chipo> Tortoose : je te garanti que ça marche <naf> vi ça marche c une solution merci <Chipo> Tortoose : de rien ;)
n°769959
Mulot
Posté le 19-06-2004 à 16:25:42  profilanswer
 

on a qu'a faire un channel IRC "#legreg" ? :)

n°770101
farib
Posté le 19-06-2004 à 23:32:05  profilanswer
 

ouin, j'ai un pb d'initialisation  
 
23:29 farib@farib /mnt/donnees/raytracer% ./a.out scene.txt output.tga
cubemap foireux
Error : Could not open scene file.
 
c'est le cubemap qui veut pas construire l'exemple :(
 
c'est avec le zip de base, en prenant l'exemple, doit y'avoir une couille au niveau du parsage peut etre
 
arf, doit y'avoir un truc que j'ai pas capté avec le tga


Message édité par farib le 19-06-2004 à 23:35:46

---------------
Bitcoin, Magical Thinking, and Political Ideology
n°770104
farib
Posté le 19-06-2004 à 23:43:36  profilanswer
 

ah bein c'est qu'il faut que le fichier de sortie existe  :o
 
 
très très impressionnant. ce topic a presque un an, et on se sent toujours  autant petite crotte :D


Message édité par farib le 19-06-2004 à 23:44:58

---------------
Bitcoin, Magical Thinking, and Political Ideology
n°770155
LeGreg
Posté le 20-06-2004 à 03:50:59  profilanswer
 

farib: le cubemap de base est dans un fichier séparé dans la première page : c'est ça ton probleme ou autre chose ?
 
Fel: si tu as une question sur le raytracing ou sur un probleme de compilation tu peux ouvrir un deuxieme topic ?
 
De toute façon je suis jamais très loin meme si je participe plus beaucoup.

n°770235
farib
Posté le 20-06-2004 à 12:17:16  profilanswer
 

LeGreg a écrit :

farib: le cubemap de base est dans un fichier séparé dans la première page : c'est ça ton probleme ou autre chose ?
 
Fel: si tu as une question sur le raytracing ou sur un probleme de compilation tu peux ouvrir un deuxieme topic ?
 
De toute façon je suis jamais très loin meme si je participe plus beaucoup.


 
non, c'était tout con, fallait juste que je fasse un 'touch output.tga' sinon le programme faisait une erreur  ;)


---------------
Bitcoin, Magical Thinking, and Political Ideology
n°770449
farib
Posté le 20-06-2004 à 20:04:59  profilanswer
 

j'ai commencé à lire, j'ai compris jusque là
 

Code :
  1. // balayage
  2.       for (int y = 0; y < myScene.sizey; ++y) {
  3.           for (int x = 0 ; x < myScene.sizex; ++x) {
  4.               float red = 0, green = 0, blue = 0; 
  5.               float coef = 1.0f;
  6.               int level = 0;
  7.        
  8.               // lancer de rayon
  9.               ray viewRay = { {float(x), float(y), -10000.0f}, { 0.0f, 0.0f, 1.0f}};
  10.               do {
  11.                   // recherche de l'intersection la plus proche
  12.                   float t = 20000.0f;
  13.                   int currentSphere=-1;
  14.                   for (unsigned int i = 0; i < myScene.sphTab.size() ; ++i) {
  15.                       if (hitSphere(viewRay, myScene.sphTab[i], t)) {
  16.                           currentSphere = i;
  17.                       }
  18.                   }
  19.                   if (currentSphere == -1)
  20.                       break;
  21.                   point newStart  = viewRay.start + t * viewRay.dir;


si j'ai bien compris, t, c'est la profondeur du point d'intersection du rayon avec la sphère dont on a le point d'intersection en (x,y,t)
 
je comprend pas ce qu'est ce "newStart"
 
on part de notre point de départ original, et on avance un petit peu, de  t,  dans la direction  :heink:  
 
je dois comprendre de travers, t c'est quoi ?


---------------
Bitcoin, Magical Thinking, and Political Ideology
n°770464
red factio​n
Posté le 20-06-2004 à 20:25:23  profilanswer
 

ce serait bien si qqn pouvait reduire ce code au max de facon a avoir qqch de compilable sur lequel on pourrait debuter

n°770473
Dion
Acceuil
Posté le 20-06-2004 à 20:33:10  profilanswer
 

red faction a écrit :

ce serait bien si qqn pouvait reduire ce code au max de facon a avoir qqch de compilable sur lequel on pourrait debuter


 
ce code compile
(enfin sous gcc 3.4.0 il compile :O)

n°770481
red factio​n
Posté le 20-06-2004 à 20:44:28  profilanswer
 

Dion a écrit :

ce code compile
(enfin sous gcc 3.4.0 il compile :O)


 
heu y manque qq classes et autre .h il me semble  :whistle:

n°770483
Dion
Acceuil
Posté le 20-06-2004 à 20:46:27  profilanswer
 

red faction a écrit :

heu y manque qq classes et autre .h il me semble  :whistle:


 
j'ai genere des images avec...  :p

n°770518
WhatDe
Posté le 20-06-2004 à 21:55:27  profilanswer
 

LeGreg tu déchires :jap:


---------------
[:whatde]
n°770542
bjone
Insert booze to continue
Posté le 20-06-2004 à 22:44:02  profilanswer
 

farib a écrit :

j'ai commencé à lire, j'ai compris jusque là
 

Code :
  1. // balayage
  2.       for (int y = 0; y < myScene.sizey; ++y) {
  3.           for (int x = 0 ; x < myScene.sizex; ++x) {
  4.               float red = 0, green = 0, blue = 0; 
  5.               float coef = 1.0f;
  6.               int level = 0;
  7.        
  8.               // lancer de rayon
  9.               ray viewRay = { {float(x), float(y), -10000.0f}, { 0.0f, 0.0f, 1.0f}};
  10.               do {
  11.                   // recherche de l'intersection la plus proche
  12.                   float t = 20000.0f;
  13.                   int currentSphere=-1;
  14.                   for (unsigned int i = 0; i < myScene.sphTab.size() ; ++i) {
  15.                       if (hitSphere(viewRay, myScene.sphTab[i], t)) {
  16.                           currentSphere = i;
  17.                       }
  18.                   }
  19.                   if (currentSphere == -1)
  20.                       break;
  21.                   point newStart  = viewRay.start + t * viewRay.dir;


si j'ai bien compris, t, c'est la profondeur du point d'intersection du rayon avec la sphère dont on a le point d'intersection en (x,y,t)
 
je comprend pas ce qu'est ce "newStart"
 
on part de notre point de départ original, et on avance un petit peu, de  t,  dans la direction  :heink:  
 
je dois comprendre de travers, t c'est quoi ?


 
si je glisses pas:
 
t représente dans la longueur du rayon de vue au contact matière.
 
comme tu recherches la sphère la plus proche, tu commence avec T très grand, et hitsphere() t'actualises T à la nouvelle distance (et retourne vrai) si y'a contact et distance plus courte.
 
ce qui fait que après avoir balayé toutes les sphères, tu te retrouves avec le contact le plus proche sur le vecteur de vue.
 
après pour la réflection, tu reparts tes à partir du point de contact, qui est:  
 
nouveau point de départ = point de départ + distance*vecteur de vue (unitaire)
 
tu calcules la normales de la sphère au point de contact  
 
tu calcules le "vecteur réfléchi" du vecteur de vue par rapport à cette normale.
 
et tu refais le tout à en testant à avec comme vecteur, le vecteur qui part du "nouveau point de départ" avec l'orientation "vecteur réfléchi"
 
entre tout ça, tu calcules l'éclairage.  
qui implique les tests récursifs nécessitant des nouveaux points de départ & vecteur, pour la réflection/réfraction.....

n°770558
farib
Posté le 20-06-2004 à 22:53:00  profilanswer
 

question con, dans 0.1f, f pour quoi ?


---------------
Bitcoin, Magical Thinking, and Political Ideology
n°770567
bjone
Insert booze to continue
Posté le 20-06-2004 à 23:03:03  profilanswer
 

float.  
 
sinon le type par des défauts des flottants est le double, et quand tu mets un double dans un float, le compilo émets un warning comme quoi une perte de précision est possible.

n°770569
farib
Posté le 20-06-2004 à 23:04:23  profilanswer
 

hitSphere(const ray &r, const sphere& s, float &t)
 
il a beau dire que les maths sont pas intéressantes, le LeGreg, il balance son code, et c'est bien difficile de trouver l'explication géométrique


---------------
Bitcoin, Magical Thinking, and Political Ideology
n°770575
Dion
Acceuil
Posté le 20-06-2004 à 23:08:56  profilanswer
 

kan tu maitrises ce n'est pas interessant, quand tu nages comme moi ca l'est :D
 
 
 
On pourrait enlever le "de base", il me fait mal au coeur :D

n°770599
farib
Posté le 20-06-2004 à 23:31:18  profilanswer
 

http://f.desoras.free.fr/geometrie.JPG
 
c tro cho....
 
comme ça, je vois pas
 
je pense que mécaniquement, pour le faire, faut que j'écrive
 
1) l'équation de la droite rayon, aka 2 équations de plans
 
2) l'équation de ma sphère
 
je résoud le système.


Message édité par farib le 20-06-2004 à 23:33:51

---------------
Bitcoin, Magical Thinking, and Political Ideology
n°770605
Dion
Acceuil
Posté le 20-06-2004 à 23:33:34  profilanswer
 


 
moi je suis a la transparence :D

n°770608
farib
Posté le 20-06-2004 à 23:36:13  profilanswer
 

Dion a écrit :

moi je suis a la transparence :D


 
fais pas style t'as compris comment on calcule l'intersection avec la sphère.  :kaola:


---------------
Bitcoin, Magical Thinking, and Political Ideology
n°770614
Dion
Acceuil
Posté le 20-06-2004 à 23:41:51  profilanswer
 

farib a écrit :

fais pas style t'as compris comment on calcule l'intersection avec la sphère.  :kaola:


 
j'ai code un truc qui fait des spheres, bon, mon algo differe peut etre kk peu :D

n°770621
Dion
Acceuil
Posté le 20-06-2004 à 23:47:21  profilanswer
 

yen a un qu'a fait l'X et pas les autres, spa pour rien :D

n°770628
bjone
Insert booze to continue
Posté le 21-06-2004 à 00:00:02  profilanswer
 

farib a écrit :

hitSphere(const ray &r, const sphere& s, float &t)
 
il a beau dire que les maths sont pas intéressantes, le LeGreg, il balance son code, et c'est bien difficile de trouver l'explication géométrique


 
ray est une classe/structure (pas regardé les headers) qui embarque les attributs d'un rayon:  
position (point de départ)
et vecteur de direction
 
sphere embarque la position et le rayon d'une sphère
 
t est la dernière distance de connue, et sert à retourner la distance de contact si elle est plus courte.
 
 
à froid:
 
http://site.voila.fr/bjone/hitsphere.png
 
pour un rayon de point initial P de vecteur directeur V
une sphere S de centre C et de rayon R
 
soit "dist" le vecteur de P->C
 
soit B la distance de "dist" projeté sur le vecteur unitaire V
avec C projeté en C'
 
// vecteur dist = s.pos - r.start;
// float B = r.dir * dist;  
 
soit I l'intersection recherchée, positionné tel que I=P+V*(B-D)
soit L la distance |C C'|
la distance |I C| c'est R
 
on a deux triangles rectangles P C C' (rectangle en C')
et I C C' (rectangle en C')
 
dans I C C':
R² = D² + L²
D est recherché
 
D² = R² - L²
 
L fait chier
 
dans P C C'
 
dist² = B² + L²
L² = dist² - B²
 
on regroupe
 
D² = R² - dist² + B²
 
// float D = B*B - dist * dist + s.size * s.size;
 
 
je te up le shéma


Message édité par bjone le 30-06-2004 à 19:24:13
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