/*************************************************************************************************************************************/ /* */ /* D E F I N I T I O N S D E L ' E F F E T D E B R U M E : */ /* */ /* */ /* Author of '$xrv/champs_5.16$I' : */ /* */ /* Jean-Francois Colonna (LACTAMME, 1992??????????). */ /* */ /*************************************************************************************************************************************/ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* G E S T I O N D E L A B R U M E E V E N T U E L L E : */ /* */ /*************************************************************************************************************************************/ #define GENERER_UN_EFFET_DE_BRUME \ FAUX DEFV(Local,DEFV(Logical,INIT(generer_un_effet_de_brume,GENERER_UN_EFFET_DE_BRUME))); /* Indique s'il faut ('VRAI') ou pas ('FAUX') entourer les points dans un effet de brume. */ #define EDITER_LE_MESSAGE_CHAMP_DE_BRUME_OU_Z_BUFFER \ VRAI DEFV(Local,DEFV(Logical,INIT(editer_le_message_champ_de_brume_ou_z_buffer,EDITER_LE_MESSAGE_CHAMP_DE_BRUME_OU_Z_BUFFER))); /* Introduit le 20160806091642 pour controler 'v $xrv/champs_5.1A$I 20160806082438'... */ #define champ_de_brume \ ImageA6 \ /* Ou ranger le champ de brume... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P R E P A R A T I O N D E L ' I N I T I A L I S A T I O N D U ' Z - B U F F E R ' : */ /* */ /*************************************************************************************************************************************/ #define INITIALISER_LE_Z_BUFFER_EN_FONCTION_DES_SPHERES_VISUALISEES \ FAUX DEFV(Local,DEFV(Logical,INIT(initialiser_le_Z_Buffer_en_fonction_des_spheres_visualisees ,INITIALISER_LE_Z_BUFFER_EN_FONCTION_DES_SPHERES_VISUALISEES ) ) ); /* Indique s'il faut initialiser le 'Z-Buffer' en fonction de la sphere la plus eloignee de */ /* l'observateur ('VRAI') ou bien a l'infini ('FAUX')... */ /* */ /* L'examen des sequences : */ /* */ /* xivPdf 10 2 / 002561_003072 */ /* */ /* et : */ /* */ /* xivPdf 10 2 / 004609_005120 */ /* */ /* a montre le 20000623120000 un phenomene explique le 20000627164827. On voit sur la */ /* premiere sequence (le "piston") des particules qui semblent plus grosses que celles */ /* de la seconde (les "aggregats"). Or les rayons des petites boules de la premiere valent */ /* 0.028*1.2=0.0336 alors que ceux de la seconde valent 0.034 ; or 0.034 > 0.0336... */ /* Le phenomene est purement visuel et provient de traitement de l'anti-aliasing dans */ /* 'v $xrv/champs_5.1C$I correction_d_anti_aliasing_aux_intersections' ou cette derniere */ /* variable depend de 'valeur_d_initialisation_du_Z_Buffer' dans le cas de spheres qui */ /* n'ont aucune sphere derriere. Or sur la sequence du "piston", il y a des grosses boules */ /* de rayon 0.028*1.8=0.0504 ; c'est donc cette valeur qui sert a calculer par la suite */ /* 'valeur_d_initialisation_du_Z_Buffer' via 'rayon_reel_de_visualisation'. Cela a ete */ /* compris en observant la dependance du phenomene vis a vis du rayon des grosses boules */ /* du piston. */ /* */ /* Le 20000627164827, je rend conditionnel ce dispositif (et l'inhibe par defaut) qui figure */ /* dans 'v $xrv/champs_5.16$I 20000627164827' et 'v $xrv/champs_5.26$I 20000627164827'. */ DEFV(Local,DEFV(genere_Float,INIT(valeur_d_initialisation_du_Z_Buffer,F_MOINS_L_INFINI))); /* Valeur destinee a initialiser le 'Z-Buffer'. Celle-ci est calculee dynamiquement en */ /* fonction de l'ensemble des coordonnees 'Z' sur l'image. ATTENTION : il est imperatif */ /* de l'initialiser avec 'F_MOINS_L_INFINI', au cas ou l'effet de brume serait inactif... */ DEFV(Local,DEFV(genere_Float,INIT(valeur_de_la_valeur_d_initialisation_du_Z_Buffer,F_MOINS_L_INFINI))); /* Valeur destinee a initialiser le 'Z-Buffer'. Celle-ci a ete ajoutee le 20051220114226 */ /* afin de pouvoir etre introduite via un 'v $xrv/champs_5.1A$I Z0='. Il peut sembler lourd */ /* d'introduire 'valeur_de_la_valeur_d_initialisation_du_Z_Buffer' pour intialiser */ /* dynamiquement 'valeur_d_initialisation_du_Z_Buffer', mais c'est en fait destine a eviter */ /* des problemes au cas ou l'initialisation serait plusieurs fois (cas ou plusieurs images */ /* sont generees...). */ #define PREPARATION_DE_L_INITIALISATION_DU_Z_BUFFER \ Bblock \ Test(IL_FAUT(initialiser_le_Z_Buffer_en_fonction_des_spheres_visualisees)) \ Bblock \ EGAL(valeur_d_initialisation_du_Z_Buffer,F_INFINI); \ /* Afin de calculer dynamiquement la future valeur d'initialisation du 'Z-Buffer' en */ \ /* fonction de la sphere la plus eloignee (et de sa coordonnee 'Z' et de son rayon). */ \ Eblock \ ATes \ Bblock \ EGAL(valeur_d_initialisation_du_Z_Buffer,valeur_de_la_valeur_d_initialisation_du_Z_Buffer); \ /* Initialisation de la future valeur d'initialisation du 'Z-Buffer'... */ \ /* */ \ /* Le 20051220114226, 'valeur_de_la_valeur_d_initialisation_du_Z_Buffer' a remplace le */ \ /* valeur explicite 'F_MOINS_L_INFINI'... */ \ Eblock \ ETes \ Eblock \ /* Preparation de l'initialisation du 'Z-Buffer'... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* P A R A M E T R E S D E C O N V O L U T I O N D U ' Z - B U F F E R ' : */ /* */ /*************************************************************************************************************************************/ #define FACTEUR_MULTIPLICATIF_DE_CONVOLUTION_DU_Z_BUFFER \ FU \ /* Facteur multiplicatif du produit de convolution en chaque point {X,Y}. */ #define NOMBRE_DE_POINTS_DU_NOYAU \ EXP2(DOUP(UN)) DEFV(Local,DEFV(Int,INIT(nombre_de_points,NOMBRE_DE_POINTS_DU_NOYAU))); /* Nombre de points du noyau. ATTENTION, cette operation genere de legers artefacts, qui */ /* augmentent d'importance lorsque ce parametre augmente. On verra a ce propos l'image */ /* 'v $xiirs/ESCA.12' ou apparait une discontinuite lorsque l'on passe a des zones qui ont */ /* comme arriere-plan l'"infini"... */ #define IL_FAUT_RENORMALISER \ VRAI \ /* Faut-il renormaliser l'image ? */ #define NOYAU(numero,valeur) \ Bblock \ EGAL(ITb1(noyau,INDX(numero,PREMIER_POINT)),valeur); \ EGAL(ITb1(inhibition_du_noyau,INDX(numero,PREMIER_POINT)),ACTIF); \ Eblock \ /* Initialisation du noyau de convolution... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* M E M O R I S A T I O N D U C H A M P D E B R U M E ( O U ' Z - B U F F E R ' ) : */ /* */ /*************************************************************************************************************************************/ #define MEMORISER_LE_CHAMP_DE_BRUME \ FAUX DEFV(Local,DEFV(Logical,INIT(memoriser_le_champ_de_brume,MEMORISER_LE_CHAMP_DE_BRUME))); /* Si 'IL_FAUT(generer_un_effet_de_brume)', indique si le 'champ_de_brume' doit etre fourni */ /* comme resultat ('VRAI'), ou bien oublie apres le calcul ('FAUX') ; rppelons que le champ */ /* de brume est "a une transformation lineaire pres" le 'Z-Buffer'. Dans le cas contraire */ /* ou 'IL_NE_FAUT_PAS(generer_un_effet_de_brume)', indique si le 'Z-Buffer' doit etre fourni */ /* comme resultat ('VRAI'), ou bien oublie apres le calcul ('FAUX'). */ #define EDITER_LES_EXTREMA_DU_Z_BUFFER \ FAUX DEFV(Local,DEFV(Logical,INIT(editer_les_extrema_du_Z_Buffer,EDITER_LES_EXTREMA_DU_Z_BUFFER))); /* Introduit le 20190801213747... */ #define FILTRER_LE_Z_BUFFER \ FAUX #define FILTRAGE_DU_Z_BUFFER__PONDERATION_DU_MINIMUM \ FU #define FILTRAGE_DU_Z_BUFFER__PONDERATION_DU_MAXIMUM \ FZERO #define FILTRAGE_DU_Z_BUFFER__TRANSLATION___________ \ FZERO DEFV(Local,DEFV(Logical,INIT(filtrer_le_Z_Buffer,FILTRER_LE_Z_BUFFER))); DEFV(Local,DEFV(Float,INIT(filtrage_du_Z_Buffer__ponderation_du_minimum,FILTRAGE_DU_Z_BUFFER__PONDERATION_DU_MINIMUM))); DEFV(Local,DEFV(Float,INIT(filtrage_du_Z_Buffer__ponderation_du_maximum,FILTRAGE_DU_Z_BUFFER__PONDERATION_DU_MAXIMUM))); DEFV(Local,DEFV(Float,INIT(filtrage_du_Z_Buffer__translation___________,FILTRAGE_DU_Z_BUFFER__TRANSLATION___________))); /* Introduit le 20190801215802 et completes le 20190802090349 par les ponderations */ /* et translation... */ DEFV(Local,DEFV(CHAR,INIT(POINTERc(nom_imageZ),NOM_PIPE_Local))); /* Nom de la sequence a generer... */ #define GENERATION_D_UN_CHAMP_DE_BRUME(numero_de_l_image) \ Bblock \ Test(IL_FAUT(memoriser_le_champ_de_brume)) \ Bblock \ DEFV(CHAR,INIT(POINTERc(nom_temporaire_du_champ_de_brume_et_du_Z_Buffer) \ ,chain_Aconcaten2_sauf_nom_pipe(nom_imageZ,NUMERO_IMAGE(numero_de_l_image)) \ ) \ ); \ \ Test(IL_FAUT(generer_un_effet_de_brume)) \ /* ATTENTION, on ne peut ecrire : */ \ /* */ \ /* GENERATION_D_UNE_COMPOSANTE(nom_temporaire_du_champ_de_brume_et_du_Z_Buffer */ \ /* ,COND(IL_FAUT(generer_un_effet_de_brume) */ \ /* ,champ_de_brume */ \ /* ,Z_Buffer */ \ /* ) */ \ /* ,memoriser_le_champ_de_brume */ \ /* ); */ \ /* */ \ /* a cause de la definition de 'v $xrv/champs_5.14$I GENERATION_D_UNE_COMPOSANTE'. */ \ Bblock \ GENERATION_D_UNE_COMPOSANTE(nom_temporaire_du_champ_de_brume_et_du_Z_Buffer \ ,champ_de_brume \ ,memoriser_le_champ_de_brume \ ); \ /* Memorisation du 'champ_de_brume'. */ \ Eblock \ ATes \ Bblock \ Test(IL_FAUT(editer_les_extrema_du_Z_Buffer)) \ /* Test introduit le 20190801213747... */ \ Bblock \ CAL2(Prin2("extrema du 'Z_Buffer'=(%+.^^^,%+.^^^)\n",Z_Buffer_____minimum,Z_Buffer_____maximum)); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ Test(IL_FAUT(filtrer_le_Z_Buffer)) \ /* Test introduit le 20190801215802... */ \ Bblock \ BDEFV(imageF,Z_Buffer_filtre); \ /* Valeur du 'Z-Buffer' apres filtrage "passe-bande". */ \ \ CALS(IFmove_avec_remplacement_d_un_niveau(Z_Buffer_filtre \ ,Z_Buffer \ ,valeur_de_la_valeur_d_initialisation_du_Z_Buffer \ ,LIN2(filtrage_du_Z_Buffer__ponderation_du_minimum \ ,Z_Buffer_____minimum \ ,filtrage_du_Z_Buffer__ponderation_du_maximum \ ,Z_Buffer_____maximum \ ,filtrage_du_Z_Buffer__translation___________ \ ) \ ) \ ); \ /* Filtrage "passe-bande" du 'Z-Buffer' ; on notera que l'on ne peut utiliser la fonction */ \ /* 'IFnivo_extrema(...)' dans le cas du 'Z-Buffer' car, en effet, en ce qui concerne le */ \ /* 'niveau_minimal', on recupererait la valeur d'initialisation... */ \ /* */ \ /* On notera le 20190802093659 qu'evidemment si la valeur de remplacement de la valeur */ \ /* d'initialisation du 'Z-Buffer' est SUPERIEURE a 'Z_Buffer_____minimum', cela ne change */ \ /* pas ce minimum ! */ \ CALS(IFmove(Z_Buffer,Z_Buffer_filtre)); \ \ EDEFV(imageF,Z_Buffer_filtre); \ /* Valeur du 'Z-Buffer' apres filtrage "passe-bande". */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ \ GENERATION_D_UNE_COMPOSANTE(nom_temporaire_du_champ_de_brume_et_du_Z_Buffer \ ,Z_Buffer \ ,memoriser_le_champ_de_brume \ ); \ /* Memorisation du 'Z-Buffer'. */ \ Eblock \ ETes \ \ CALZ_FreCC(nom_temporaire_du_champ_de_brume_et_du_Z_Buffer); \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Generation d'un champ de brume de numero donne... */ /*===================================================================================================================================*/ /*************************************************************************************************************************************/ /* */ /* G E N E R A T I O N D E L ' E F F E T D E B R U M E : */ /* */ /*************************************************************************************************************************************/ #define GENERATION_DE_L_EVENTUEL_EFFET_DE_BRUME \ Bblock \ Test(IL_FAUT(generer_un_effet_de_brume)) \ Bblock \ DEFV(Logical,DTb1(niveaux_a_traiter,COULEURS)); \ /* Definit les niveaux sur lesquels on doit faire la convolution par 'Pconvolution()'. */ \ DEFV(Logical,DTb1(niveaux_cumulables,COULEURS)); \ /* Definit les niveaux cumulables lors du calcul de 'Pconvolution_____cumul_courant'. */ \ DEFV(Float,DTb1(noyau,TAILLE_MAXIMALE_D_UN_NOYAU_DE_CONVOLUTION)); \ /* Noyau de la convolution, */ \ DEFV(Logical,DTb1(inhibition_du_noyau,TAILLE_MAXIMALE_D_UN_NOYAU_DE_CONVOLUTION)); \ /* Et sa liste d'activite. */ \ DEFV(Int,INIT(index,UNDEF)); \ /* Index d'initialisation du noyau. */ \ BDEFV(image,champ_de_brume_non_convolue); \ /* Champ de brume avant sa convolution ; il est donc equivalent au 'Z_buffer' apres */ \ /* complementation... */ \ \ BoIn(niveau,NOIR,BLANC,PAS_COULEURS) \ Bblock \ EGAL(ITb1(niveaux_a_traiter,INDX(niveau,NOIR)),VRAI); \ EGAL(ITb1(niveaux_cumulables,INDX(niveau,NOIR)),VRAI); \ /* Initialisation telle que tous les niveaux soient a la fois "traitables" et "cumulables". */ \ Eblock \ EBoI \ \ Test(IFLE(nombre_de_points,TAILLE_MAXIMALE_D_UN_NOYAU_DE_CONVOLUTION)) \ Bblock \ DoIn(index,PREMIER_POINT,LSTX(PREMIER_POINT,nombre_de_points),I) \ Bblock \ NOYAU(index,FU); \ /* Initialisation du noyau de convolution. */ \ Eblock \ EDoI \ Eblock \ ATes \ Bblock \ PRINT_ERREUR("la taille demandee pour le noyau de convolution est incompatible avec les definitions"); \ \ EGAL(nombre_de_points,NOMBRE_DE_POINTS_DU_NOYAU); \ CAL1(Prer1("(la valeur %d par defaut est forcee)\n",nombre_de_points)); \ /* Introduit le 20111031141950 car, en effet, manquait cruellement... */ \ Eblock \ ETes \ \ CALi(Ifloat_std_avec_renormalisation(champ_de_brume_non_convolue,Z_Buffer)); \ /* Lorsqu'un effet de brume est demande, on renormalise le 'Z-Buffer'... */ \ CALi(Icomplementation(champ_de_brume_non_convolue,champ_de_brume_non_convolue)); \ /* Et on le complemente... */ \ \ CALi(Iconvolution_avec_renormalisation(champ_de_brume \ ,FACTEUR_MULTIPLICATIF_DE_CONVOLUTION_DU_Z_BUFFER \ ,champ_de_brume_non_convolue \ ,niveaux_a_traiter,niveaux_cumulables \ ,nombre_de_points,noyau,inhibition_du_noyau \ ,IL_FAUT_RENORMALISER \ ) \ ); \ /* Cette convolution du champ de brume est effectuee avant l'effet de transparence car en */ \ /* effet il s'agit la d'un post-processing qui donc peut rentrer en conflit avec le */ \ /* traitement anti-aliasing qui est fait lui sans savoir qu'il y aura de la brume... */ \ \ CALi(Itransparence_05(Image_ROUGE,champ_de_brume,Image_ROUGE)); \ CALi(Itransparence_05(Image_VERTE,champ_de_brume,Image_VERTE)); \ CALi(Itransparence_05(Image_BLEUE,champ_de_brume,Image_BLEUE)); \ /* Et on genere un effet de brume du type 'v $xci/vitre.51$K'... */ \ \ EDEFV(image,champ_de_brume_non_convolue); \ /* Champ de brume avant sa convolution ; il est donc equivalent au 'Z_buffer' apres */ \ /* complementation... */ \ Eblock \ ATes \ Bblock \ Eblock \ ETes \ Eblock \ /* Generation de l'eventuel effet de brume... */