CafzoneWare: le raytracer C#

Hopla :pleure:
Puisque plusieurs thread parlaient de cours et/ou d’introductions a des langages je me suis dit que le petit raytracer que j’ecrivais pourrait tres bien devenir le premier logiciel en CafzoneWare. Pour l’instant ca raytrace, la scene est hardcodee dans le main() du programme et ca va pas super vite. Le resultat produit pout l’instant c’est des trucs comme ca:

<img src=’ http://www.3deurope.com/cafzone/output.jpg’ border=0>

ca casse pas des briques mais les reflections marchent :pleure:

La suite, refractions, acceleration, anti aliasing, caustics etc ne sont pas la pour l’instant et n’attendent que votre bonne volontee et/ou plus de temps de ma part…

Le code est la :
http://www.3deurope.com/cafzone/GloPRender.zip

Il est malheuresement peu commente (mais ca va changer) et il faut etre un peu familier avec l’algorithme de raytrace et un mini (pas bcp) de math vectorielles pour comprendre de quoi ca parle. Je posterai un autre message avec plus de details/explications plus tard. Histoire de se faire introduire en douceur (ha bravo) au code ci joint.

Le code est en revanche pas trop mal organise et bien separe en entitees distinctes… ca devrait aider a comprendre.

Voila ! J’espere que ca vous plait. C’est tout en C# et c’est ptet une occasion pour certain de regarder la tete que ca a. Y a meme le projet visual studio qui va avec mais vous en avez pas besoin pour compiler. Demandez moi de l’aide si vous y arrivez pas.

J’attend vos commentaires avec impatience.

Bé juste pour dire que je viens (enfin)de télécharger les sources et que je vais me plonger dedans pour voire comment tout marche !!! A noël, je rentre chez moi (enfin !!!) avec une pile de bouquain sur la 3D , le ray tracing et tout le tin toiiin La je suis en train d’ écumer ma bibliothéque (celle de l’ école) pour trouver les meilleurs bouquains j ai pas encore pensé à matter s’ il y avait le bouquain du prof de Tzim mais y en a plein d autres (la majorité en VONSTF :joie: ) donc je pense en plus, pouvoir, aprés le nouvelle an, faire un post sur une biblio !!! Voilou sinon une seule question ou ce trouve la liste des trucs déjà implémentés ??? (voire ce que je peux faire avec mes dix doigts et mon cerveau déjà eprouvé)

Allez à tout à l’ heure chez moi :wink:

Koubiak

ps : message subliminal regardez bien j’ ai mis des accents !!!

Bon deja je t’arrete la maniere dont je commente pour moi quand je code un projet perso a la maison est effectivement tres egoiste puisque je code POUR MOI. Et pour moi seul. Je commente differement au taf ou je bosse sur des gros gros projets utilises par des millions de personnes.

En revanche je suis pas d’accord coder degueu prend moins de temps que de coder propre dans l’immediat. La ou c’est pas payant DU TOUT c’est sur un projet ou il va falloir revenir sur le code, le faire evoluer, le debugger a fond etc la c’est clairement plus rapide de code proprement parceque passer des heures sur du code imbitable c’est pas rentable. Mais quand je code un truc pour une utilisation unique ou un truc pour moi rapide a la maison que je vais utiliser trois fois je code pas crado mais certainement moins bien que du code de production pour mon boulot.

Enfin tu peux demander a beaucoup de personnes qui bossent avec moi je suis plutot un integriste du code propre et bien ecrit et j’aime pas les truc pas carres et pas dans l’esprit du programme. Je suis meme pas mal chiant pour ca (n’est ce pas Kinik :smiley: ) Mais tout est une question de contexte et il faut savoir s’adapter.

Bon… sur ce retour au RAYTRACER :slight_smile:

[Edité le 28/11/2002 par GloP]

Après ça j’arrête. Glop, développer propre n’a jamais été plus long que de développer dégueux. C’est une erreur de croire ça. Faire du développement pour que toi seul soit capable de relire dans les 6 prochains mois est sacrément égoïste et encore une erreur, ou alors tu n’as jamais travaillé sur de très gros projets. Ce n’est pas un reproche, hein, à chacun sont XP.

Là où je suis totalement d’ac, c’est sur l’exemple du commentaire que tu as pris. J’en ai d’autres :

//-- Boucle de 0 à 9
for( int i=0; i

[quote]D’ailleurs, de mon point de vue, on ne doit pas lire le code mais uniquement les commentaires, la lecture du code venant par la suite…
[/quote]
Bah c’est bien beau de dire ca mais c’est comme de dire qu’il faudrait que dans le monde personne creve de faim :slight_smile: C’est mega utopique. En pratique quand tu travaille ca se passe pas comme ca. T’es presse t’as des contraintes, t’as un boss qui te dit que c’etait pour hier ou autre, genre t’as pas envie, tu le fais pour toi, t’aime bien hacker dans ton coin, whatever… En resume programmer proprement c’est une histoire de compromis et de tolerance. Tu fais un compromi entre faire du code nikel et le temps que tu passe sur chaque procedure et c’est une question de tolerance parceque quelqu’un qui connait perlin par coeur il survole le code et en 2 secondes il sait ce que ca fait et le choix que Xentyr a fait. Tout depend du « public » pour le code. Il y aussi une tolerence personelle. Moi je mets de commentaires que la ou je sais que je vais avoir des problemes quand je vais relire dans 6 mois. Je m’amuse pas a ecrire un algo dans des commentaires pour l’implementer 3 lignes plus bas. C’est profondement stupide et c’est une grosse perte de temps. Si qqn lit ton code c’est un programmeur qu’il assume de lire du code et pas un roman. Les commentaires doivent etre pertinents et amener quelque chose, sinon ils sont redondants et ne servent a rien. Si il y a bien qqch que je ne supporte pas c’est des trucs du genre:

/*Fonction Vecteur3d ProduitVectoriel(Vector3d a, Vector3d :D Fonction renvoyant le produit vectoriel de deux vecteurs Parametres: Vecteur a et vecteur b, les deux vecteurs a multiplier Resultat: le vecteur produit */ [/quote] Tu viens de perdre 5 lignes et 5 minutes de ton temps pour qqch qui prend une ligne en code et qui est [b]limpide[/b].

Enfin bon! Les gars c’est mon thread et ca serait bien qu’on reste sur le sujet : LE RAYTRACER! On va pas faire un debat sur la proprete du code et son influence sur la masturbation des crustaces d’eau douce en irlande du nord.

Pas cool de lancer cette discussion dans ce thread c0unt0, il est dejà hyper chargé :slight_smile:

Je me sens de bon humeur, je vais lancer une guerre de religion !

les variables prefixees, dite notation polonaise, hey bah moi j’aime pas, parce que ca allourdi le code pour pas grands chose.

voila ! :slight_smile:

si tout le monde met son p’tit bout de code, il va plus ressembler à rien ce thread…

enfin si vous voulez, j’peux vous donner mon algo de perlin
c’est pas crado, mais c pas optimisé, pas vraiment complet (je lisse pas), et j’l’ai un peu bidouillé parceque d’après ce que j’ai vu, rien n’empechait la valeur de depasser 1, et ca me genait

/edit
moktar : merci pour ces belles remarques d’une constructivité exemplaire, et qui aident manifestement à maintenir une ambiance cordiale
c’est vrai que son code n’est pas propre, c’est bien de lui faire remarquer, mais c’est peut-etre pas la peine d’insister lourdement, tu crois pas ?
/

[Edité le 28/11/2002 par urdle]

Hmmmm… comment ça corriger ? on écrit propre dès le début et non pas crados puis on reprend le tout pour réécrire l’ensemble… ça c’est une démarche à gerber (heu désolé ;)). C’est comme les commentaires, ils doivent être écrits en même temps que le code. D’ailleurs, de mon point de vue, on ne doit pas lire le code mais uniquement les commentaires, la lecture du code venant par la suite…

Xentyr :

:stuck_out_tongue:

[quote]Xentyr> petite critique, le nommage des variables n’est pas expressif et non préfixé (beurkk) et lorsque je vois ça :

int i, j, k ;
int ii, jj, kk ;
int f_x, f_y, f_z ;
//float fact ;
float d, dd, ddd ;
float w_x[2], w_y[2], w_z[2] ;

je gerbe.[/quote]Quand je dis que c’est programmé à la porcasse, c’est pas pour rien, hein !!! :wink: Et oui, j’ai la flemme de corriger et évite de parler de gerbe, mon foie réclame clémence :stuck_out_tongue:

Xentyr> petite critique, le nommage des variables n’est pas expressif et non préfixé (beurkk) et lorsque je vois ça :

int i, j, k ;
int ii, jj, kk ;
int f_x, f_y, f_z ;
//float fact ;
float d, dd, ddd ;
float w_x[2], w_y[2], w_z[2] ;

je gerbe.

Rhaaaa le porcos :wink: Du C/C++ ! Bhou! Die C/C++, DIE!

J’vous donnerai le bézier quand je le retrouverai (c’est vraiment bidon en fait et ça sert aussi bien pour créer de cute patches que le mouvement de la caméra par exemple…). V’là un exemple de perlin programmé à la porcasse :wink: pour ceusse qui n’en veulent. Bon je retourne au TAF moi (dès que j’ai dessaoulé)…

#include
#include « class.hpp »

#define N 128
#define NN 64

unsigned long int Seed = 1 ; /* — init a 1 — */
Vect G[N] ;
int P[N] ;

float Random( void )
{

static unsigned long int a = 16807 ;
static unsigned long int m = 0x7FFFFFFF ;
static unsigned long int n = 0x3FFFFFFF ; /* — m / 2 — /
static unsigned long int q = 127773 ; /
— m div a — /
static unsigned long int r = 2836 ; /
— m mod a — */

long int lo, hi, test ;

hi = Seed / q ;
lo = Seed % q ;

test = a * lo  -  r * hi ;

if ( test > 0 ) 
Seed = test ;
else
Seed = test + m ;

return( (float) ((double) Seed / (double) n) - 1.0f ) ;

}

int Random_Int( void )
{
static unsigned long int a = 16807 ;
static unsigned long int m = 0x7FFFFFFF ;
//static unsigned long int n = 0x7FFF ;
static unsigned long int q = 127773 ; /* — m div a — /
static unsigned long int r = 2836 ; /
— m mod a — */

long int lo, hi, test ;

hi = Seed / q ;
lo = Seed % q ;

test = a * lo  -  r * hi ;

if ( test > 0 ) 
Seed = test ;
else
Seed = test + m ;

return( (int) (Seed >> 16) ) ;

}

void Ray_Seed( unsigned long int new_Seed )
{
Seed = new_Seed ;
}

Vect *Gamma( int i, int j, int k )
{

int index ; // — index ds la table des « G » (vect random) —

index = (k % NN) + NN ;

index = P[index] ;

index = ((j+index) % NN) + NN ;

index = P[index] ;

index = ((i+index) % NN) + NN ;

index = P[index] ;

return( G + index ) ;

}

Vect V_Noise_P( float x, float y, float z )
{
int i, j, k ;
int ii, jj, kk ;
int f_x, f_y, f_z ;
//float fact ;
float d, dd, ddd ;
float w_x[2], w_y[2], w_z[2] ;

Vect v1, res ;

res = 0.0 ;

f_x = (int) floor(x) ; 
f_y = (int) floor(y) ; 
f_z = (int) floor(z) ; 

d   = x - f_x ;
d   = ABS(d) ;
dd  = d * d ;
ddd = dd * d ;
w_x[0] = 2.0f * ddd  -  3.0f * dd  +  1.0f ;

d   = x - (f_x+1) ;
d   = ABS(d) ;
dd  = d * d ;
ddd = dd * d ;
w_x[1] = 2.0f * ddd  -  3.0f * dd  +  1.0f ;

d   = y - f_y ;
d   = ABS(d) ;
dd  = d * d ;
ddd = dd * d ;
w_y[0] = 2.0f * ddd  -  3.0f * dd  +  1.0f ;

d   = y - (f_y+1) ;
d   = ABS(d) ;
dd  = d * d ;
ddd = dd * d ;
w_y[1] = 2.0f * ddd  -  3.0f * dd  +  1.0f ;

d   = z - f_z ;
d   = ABS(d) ;
dd  = d * d ;
ddd = dd * d ;
w_z[0] = 2.0f * ddd  -  3.0f * dd  +  1.0f ;

d   = z - (f_z+1) ;
d   = ABS(d) ;
dd  = d * d ;
ddd = dd * d ;
w_z[1] = 2.0f * ddd  -  3.0f * dd  +  1.0f ;

for ( ii=0,i=f_x; ii

Urdle: ben il n’y a rien a changer dans le code. Ce que tu decrit s’integre parfaitement dans le code tel qu’il est et c’est la maniere dont l’implementation est prevue. Rien ne t’empeche d’avoir une librairie de fonctions bumb, noise (ca s’appelle bruit de Perlin le truc que tu recherche pour faire des plasma et autre) qui peuvent au choix renvoyer un scalaire ou un vecteur de couleurs. Cette librairie doit etre faite en respectant des principes objets tel que tu le decrit.

C’est le principe de la construction d’une BRDF. Il n’y a pas a separer texture, materiaux et autre. Tout cela est une seule et meme chose, une BRDF qui en fonction de l’endroit ou l’on “regarde” et la normale va renvoyer une couleur differente. Le bump par exemple est une fonction a appeller sur la normale quand on calcule la composante diffuse et qui va perturber celle ci en fonction d’une image et de coordonees de textures donnees en parametre.

En general dans une BRDF on combine trois elements:

ambiant (en general une constante, independant de la lumiere)
diffuse (la ou vont intervenir la majorite des effets, textures, bump, effets anisotropiques, etc,etc)
specular (le hightlight, cad les effets de simulation de la reflexion directe de la lumiere comme sur un bout de metal par exemple)

Ces trois elements peuvent etre chacun composes de nombreux parametres et fonctions du genre “echequier 3d/2d”, bump, bruit de perlin, etc. Chaque composant s’influencant ou pas selon la maniere dont est programme le shader en question.

En gros et exactement comme dans les shader mental ray ou renderman on a une librairie de fonctions qui renvoit des valeurs (genre GetPerlinNoise(position, parametres du bruit) ou GetCheckerValues(position, params)) que l’on utilise pour construire la BRDF. Il n’y a donc rien a changer a l’architecture du programme, juste rajouter cette librairie assez complexe de fonctions qui etait inutile pour les composants de bases tres simples (Phong, Blinn, etc.).

Moktar, les fichiers pdf sont tels-quels (non zippés).

DrDrakeRamore, euh, nope, on a pas eu les corrigés, mais je peux t’envoyer les miens (ils marchent, enfin, les premiers).

Urdle, vois avec Glop.

[quote]Oui, IUT info de Clermont, Imagerie Numérique (antenne du puy, prof : un certain R.Malgouyres). En fait on avance sur l’algo et les maths en //.

Pour les maths, on a quasi fini (chap 10-11).
Pour l’algo, on en est au chap 13 (illumination).

Bon, te prends pas trop la tête sur les maths, essaye plutôt de regarder les TPs :
http://llaic3.u-clermont1.fr/~mr/livreinfog/livreinfog.shtml[/quote]
Rhhaaall j’ai essayé d’ouvrir le cours sur VC++ au format pdf (gzippé apparemment) mais NADA ! Winzip fait n’importe quoi et gunzip (sous Solaris) ne s’y retrouve pas… heuuu tu fais comment là ??

quelqu’un connait-il le nom d’une fonction de « bruit » utilisée pour rendre des textures aléatoires (genre plasma) ?

ah oui, puis moi aussi, je modifie le gloprender, mais j’ai l’intention de changer la facon dont sont conçus les matériaux, parceque ca me plait pas trop comme c’est là (moi j’opte pour un truc récursif dans le sens où un matériau peut-etre lié à un autre matériau)

si vous voulez, j’peux expliciter en détail, mais comme ca demande de grosses modifs de la partie matériaux, je prefere pas vous soumettre le code modifié comme ca, vu que Tzim et/ou xentyr travaillent deja sur cette partie… et puis vous accrocherez peut-etre pas sur le principe… notez bien que cette méthode offre plus de clartée, au détriment des performances.

Oh puis tient, j’vous donne le concept, hop ! vous me direz ce que vous en pensez :

Class TextureU (monochrome); possede une fonction « double getColor(x,y,z) »; d’autres classes descendent de TextureU comme :

  • TextureChessU

Class TextureRGB (j’vous fait pas un dessin :wink: ); possede une fonction « ColorRGB getColor(x,y,z) »; d’autres classes descendent de TextureRGB comme :

  • TextureChessRGB
  • TexturePlasmaRGB
  • TextureCombineRGB : membres : 2 TextureRGB et 1 TextureU qui donne le ratio

Ce système me permet, par exemple, de faire une TextureCombineRGB qui est la combinaison de 2 textures Plasmas (l’une noir et grise; l’autre blanche et grise), controlées par une TextureChessU; le tout nous donne un joli echiquier marbré

Le meme principe est appliqué à Material :

Class Material : possède une fonction
« ColorRGB getColor(point d’impact, normale à l’impact, scene /pour les reflections&refractions/ ) »
exemples de Classes hérirant de matériau :

  • ADSMaterial : membres : 3 textures RGB pour Ambiant, Diffuse et Specular
    – pas trop de mystere, matériau standard avec un specular effect

  • RefractionMaterial : membres : 1 textureU pour le niveau de transparence, et un double pour l’indice de réfraction
    – getColor provoque le renvoi d’un autre rayon dans la scene

  • BumpMaterial : membres : 1 TextureU, 1 Material (M)
    – pour le bump, lorsque la fonction getColor est appellée, le resultat renvoyé est celui que la fonction getColor renvoie lorsqu’elle est appelée pour le Materiau M mais avec une normale modifiée

du coup, on peut alors créer un matérial BumpMaterial sur une RefractionMatérial, et le résultat est celui auquel on s’attend.
J’avais fait comme ca pour mon TP d’image en matrise d’info, mais j’arrive à retrouver mon code source… toujours est-il que c’était très concluant…

PS : j’imagine que j’ai rien inventé hein… mais je trouve ca classe moi, et ca permet toutes les fantaisies et minimise le copier/coller
PPS : oubliez pas de me répondre pour le nom de la fonction de bruit :wink:
merci d’avance

TROP CLASSE :mortel: ! Il va vous enseigner le photon mapping ?

Ouéoué j’y suis déjà allé télécharger les tps et fait les premiers.
Tu as le corrigé des tps d’ailleurs ?

Oui, IUT info de Clermont, Imagerie Numérique (antenne du puy, prof : un certain R.Malgouyres). En fait on avance sur l’algo et les maths en //.

Pour les maths, on a quasi fini (chap 10-11).
Pour l’algo, on en est au chap 13 (illumination).

Bon, te prends pas trop la tête sur les maths, essaye plutôt de regarder les TPs :
http://llaic3.u-clermont1.fr/~mr/livreinfog/livreinfog.shtml

Ah t’es en IUT quoi ? Imagerie info ?
Enfin bref, le bouquin je le trouve plutot bien foutu, même si j’en suis encore à la partie maths. Vous en êtes où en cours là ?
Hier soir je me suis pris la tête sur les courbes de Bezier rholala c’est un truc de fou ! :casstet:
Mais ce serait bien aussi de comprendre toute la parties maths avant d’attaquer le rendu, c’est ça qui pourrait nous permettre de créer des shapes originales. A moins que je me fasse des films et que ca soit réservé aux matheux l33t :cool: