/////////////////////////////////////////////////////////////////////////////// /// private constant ObtenirCouleur \n /// Description : Obtenir la couleur du pixel pour un rayon donné /// /// @param [in] Rayon const CRayon & Le rayon à tester /// /// @return const CCouleur La couleur du pixel /// /// @author Olivier Dionne /// @date 13/08/2008 /// /////////////////////////////////////////////////////////////////////////////// const CCouleur CScene::ObtenirCouleur( const CRayon& Rayon ) const { CIntersection Result; CIntersection Tmp; for( SurfaceIterator aSurface = m_Surfaces.begin(); aSurface != m_Surfaces.end(); aSurface++ ) { Tmp = ( *aSurface )->Intersection( Rayon ); if( Tmp.ObtenirDistance() > EPSILON && ( Tmp.ObtenirDistance() < Result.ObtenirDistance() || Result.ObtenirDistance() < 0 ) ) Result = Tmp; } // S'il n'y a aucune intersection, retourner la couleur de l'arrière-plan // Sinon, retourner la couleur à l'intersection return ( Result.ObtenirDistance() < 0 ) ? m_CouleurArrierePlan : ObtenirCouleurSurIntersection( Rayon, Result ); }
/////////////////////////////////////////////////////////////////////////////// /// private constant ObtenirCouleurSurIntersection \n /// Description : Obtient la couleur à un point d'intersection en particulier /// Calcule les contributions colorées de toutes les lumières, avec /// les modèles de Phong et de Gouraud. Aussi, dépendemment des /// propriétés de la surface en intersection, on réfléchi ou in /// réfracte le rayon courant. /// current ray. /// /// @param [in] Rayon const CRayon & Le rayon à tester /// @param [in] Intersection const Scene::CIntersection & L'ntersection spécifiée /// /// @return const CCouleur La couleur à l'intersection donnée /// /// @author Olivier Dionne /// @date 13/08/2008 /// /////////////////////////////////////////////////////////////////////////////// const CCouleur CScene::ObtenirCouleurSurIntersection( const CRayon& Rayon, const CIntersection& Intersection ) const { CCouleur Result = Intersection.ObtenirSurface()->ObtenirCouleur() * Intersection.ObtenirSurface()->ObtenirCoeffAmbiant(); CVecteur3 IntersectionPoint = Rayon.ObtenirOrigine()+ Intersection.ObtenirDistance() * Rayon.ObtenirDirection(); // Calculer les contribution colorées des toutes les lumières dans la scène CCouleur LumiereContributions = CCouleur::NOIR; CRayon LumiereRayon; for( LumiereIterator uneLumiere = m_Lumieres.begin(); uneLumiere != m_Lumieres.end(); uneLumiere++ ) { // Initialise le rayon de lumière (ou rayon d'ombre) LumiereRayon.AjusterOrigine( IntersectionPoint ); LumiereRayon.AjusterDirection( ( *uneLumiere )->GetPosition() - IntersectionPoint ); LumiereRayon.AjusterEnergie( 1 ); LumiereRayon.AjusterIndiceRefraction( 1 ); if( CVecteur3::ProdScal( LumiereRayon.ObtenirDirection(), Intersection.ObtenirNormale() ) > 0 ) { // Obtenir la couleur à partir de la lumière CCouleur Filter = ObtenirFiltreDeSurface( LumiereRayon ); CCouleur LumiereCouleur = ( *uneLumiere )->ObtenirCouleur() * Filter; // Ajouter la contribution de Gouraud REAL GouraudFactor = ( *uneLumiere )->GetIntensity() * Intersection.ObtenirSurface()->ObtenirCoeffDiffus() * CVecteur3::ProdScal( Intersection.ObtenirNormale(), LumiereRayon.ObtenirDirection() ); Result += Intersection.ObtenirSurface()->ObtenirCouleur() * GouraudFactor * LumiereCouleur; // ... } } return Result; }
/////////////////////////////////////////////////////////////////////////////// /// private constant ObtenirFiltreDeSurface \n /// Description : Obtenir le filtre du matériau de la surface. Le coefficient de /// réfraction nous indique du même coup s'il y a transparence de la /// surface. /// /// @param [in, out] LumiereRayon CRayon & Le rayon de lumière (ou d'ombre) à tester /// /// @return const CCouleur Le filtre de couleur /// /// @author Olivier Dionne /// @date 13/08/2008 /// /////////////////////////////////////////////////////////////////////////////// const CCouleur CScene::ObtenirFiltreDeSurface( CRayon& LumiereRayon ) const { CCouleur Filter = CCouleur::BLANC; CIntersection LumiereIntersection; REAL Distance = CVecteur3::Norme( LumiereRayon.ObtenirDirection() ); LumiereRayon.AjusterDirection( LumiereRayon.ObtenirDirection() / Distance ); // TODO : À COMPLÉTER LORS DU VOLET 2... // Tester le rayon de lumière avec chaque surface de la scène // pour vérifier s'il y a intersection CIntersection Result; CIntersection Tmp; for (SurfaceIterator aSurface = m_Surfaces.begin(); aSurface != m_Surfaces.end(); aSurface++) { Tmp = (*aSurface)->Intersection(LumiereRayon); if (Tmp.ObtenirDistance() > EPSILON) { Filter *= Tmp.ObtenirSurface()->ObtenirCoeffRefraction() * Tmp.ObtenirSurface()->ObtenirCouleur(); } } // S'il y a une intersection appliquer la translucidité de la surface // intersectée sur le filtre return Filter; }