//============================================================================== // TP : Programmation d'un algorithme de Lance de rayons (modele de reflexion) // Sujet : on se propose de generer une image "realiste" (pixel d'une matrice) // d'une sphere eclairee avec le modele de reflexion diffuse et speculaire . //============================================================================== // ======================= STEP 1 ============================================== // Scilab permet d'afficher des matrices (image) avec Matplot background=0.; foreground=1.; nbl=150;nbc=150; image = zeros(nbl,nbc) + background; // une image noire (background) ifig=1; f=scf(ifig); f.color_map =graycolormap(256); Matplot(image*256); // et maintenant une image aleatoire : image = rand(nbl,nbc); Matplot(image*256); // ======================= STEP 2 ============================================== // Pour afficher des geometries il suffit de reflechir un peu ;-) // Completer l'exemple ci-dessous pour mettre tous les points d'un disque a blanc R = 50 X0=75; Y0 = 75; for x=1:nbc for y=1:nbl D= // Trouvez la fonction D telle que l'image calculee et affichee soit un disque blanc if( D < 0 ) then image(x,y)=foreground; else image(x,y)=background; end end end Matplot(image*256); // ======================= STEP 3 ============================================== // Une image est une fenetre sur le monde ; on suppose que le // repere de la camera est identique au repere global. La taille de la fenetre // en X/Y est de [-10:10] et l'axe des Z donne la distance des objets au plan // image. La projection est orthographique, la distance de la sphere au plan // image n'intervient donc pas. // Dans ce cas simple ; l'image d'une sphere (de rayon R=1 et centree en 0,0 ) // est donne par le code ci-dessous (on retrouve l'image du disque a l'affichage): // function [image]=RayTracer1(Window,Viewport) // =============================================== nbl=Viewport(1); nbc=Viewport(2); Xmin=Window(1,1);Ymin=Window(1,2); Xmax=Window(2,1);Ymax=Window(2,2); for i=1:nbc for j=1:nbl x=(i-1)*(Xmax-Xmin)/(nbc-1) + Xmin y=(j-1)*(Ymax-Ymin)/(nbl-1) + Ymin // Pour tous les pixels de l'image image(i,j)=SceneIntersection(x,y) end end endfunction function [intensity]=SceneIntersection(x,y) // =============================================== background=0.; foreground=ambiant_light; // La scene est composee d'un disque centre de rayon R R = 1.; // X0=0; Y0 = 0; modifier le rayon pour retrouver la figure precedente D=4*((x^2+y^2)-R^2); if( D < 0 ) then intensity=foreground; // integrer le(s) modele(s) d'eclairage(s) else intensity=background; end endfunction //le repere de la camera Window=[-10,-10;10,10]; Viewport=[nbl,nbc]; ambiant_light = 0.5; [image]=RayTracer1(Window,Viewport); Matplot(image*256); // Modifier le rayon "R" pour retrouver la figure precedente. // ======================= STEP 4 ============================================== // A l'aide du code precedent, on se propose de calculer une image "realiste" de // la sphere eclairee avec le modele de reflexion diffuse. Noter au passage que // l'on peut considerer l'image actuelle comme le resultat du modele d'eclairage // "ambiant". // On suppose que la scene est eclairee par une source a l'infinie (direction unique) // Modifier le code precedent pour integrer un modele de reflexion diffuse qui // est donne par un produit scalaire. On retrouvera l'expression de la normale // en chaque point de sa surface de la sphere sur l'image, a partir du point // d'intersection entre le rayon (du raytracer) et la sphere. // 1. Calcul de la coordonnee Z du point d'intersection // Calculer l'intersection entre les rayons (representation parametrique en t) et // la sphere (representation algebrique). Rappelons que suivant nos hypotheses ; // Le rayon (du raytracer) partant du point (Xi,Yi) du plan image est une // droite de vecteur directeur (0,0,1). Montrer que l'on obtient une equation du // second degre qui n'admet de solution que si D=4*((x^2+y^2)-R^2) >= 0. // Determiner "t" dans l'équation du second degré : // En deduire le point d'intersection : // 2. Normale au point d'intersection // A partir du point d'intersection, // Deduire la normale a la sphere au point d'intersection : // 3. Eclairage diffus // On supposera que la scene est eclairee par une source a l'infinie (direction // unique) que vous placerez ou bon vous semble. On rappele que l'intensite de // la reflexion diffuse est donnee par le produit scalaire entre le rayon de // lumiere et la normale a la surface. // Modifier le code de la fonction "SceneIntersection" pour adapter le calcul // de l'intensité // ======================= STEP 5 ============================================== // Etendez le modele de reflexion pour gerer de multiples sources d'eclairage. // // ======================= STEP 6 ============================================== // Integrer un modele de reflexion speculaire; jouer sur la puissance (dans // l'equation) pour passer d'un objet mat a un objet brillant. Sauvez les images.