/** Calcul de l'éclairement local d'un point d'intersection => Phong avec ombres portées. - toutes les données nécessaires au point d'intersection sont dans le paramêtre intersection (point, normale, noeud CSG intersecté) - les données de la scène (sources lumineuses) sont accessibles par scene()->... */ Vector3 Raytrace::computeLocalColor(const Intersection &intersection) { /** * P est le point d'intersection (Vector3) * L est le vecteur d'éclairement (Vector3) * N est la normale au point d'intersection (Vector3) * V est le vecteur d'observation * m contient le materiel au point : m.diffuse() donne le matériel diffus (de type Vector3 : on peut utiliser les opérateurs *, +, etc), de même m.specular(), m.shininess() * intersection.incident() donne le rayon qui a provoqué l'intersection * Pour les sources : * - _scene->nbLight() donne le nombre de source lumineuses * - _scene->lightPosition(i) donne la position de la source i (uniquement des sources ponctuelles). * Remarque : il faut faire la somme des couleurs obtenues pour chacune des sources (risque de saturation si plusieurs sources lumineuses). */ Vector3 P; Vector3 L; Vector3 N; Vector3 V; Vector3 R; N=intersection.normal(); P=intersection.point(); N.normalize(); V = - intersection.incident().direction(); V.normalize(); double diffuseIntensity = 0; double specularIntensity = 0; Material m=intersection.node()->primitive()->material(); Vector3 result = m.ambient().xyz(); for (int i = 0 ; i < _scene->nbLight() ; i++){ if (V.dot(N) < 0) N = -N; L = _scene->lightPosition(i) - P; L.normalize(); R = 2* (N.dot(L))*N - L; R.normalize(); Ray shadow(P,_scene->lightPosition(i)-P); Intersection *nearestIntersection=_scene->intersection(shadow,0.1); if (nearestIntersection != NULL){ if(nearestIntersection->lambda()>1) { diffuseIntensity = max(N.dot(L),0.0); specularIntensity = pow(max(V.dot(R),0.0),m.shininess()); result += diffuseIntensity*m.diffuse()+specularIntensity*m.specular(); } } else { diffuseIntensity = max(N.dot(L),0.0); specularIntensity = pow(max(V.dot(R),0.0),m.shininess()); result += diffuseIntensity*m.diffuse()+specularIntensity*m.specular(); } delete nearestIntersection; } return result; }