Voyage vers la prochaine dimension avec Papervision3D Partie 2

Dans la partie 1 où nous avons découvert Papervision3D, la partie 2 pousse la scène un peu plus loin. Dans cette partie finale, vous apprendrez à faire sauter vos cubes rotatifs au spectateur avec des lunettes 3D..




introduction

Je sais qu'il est dit que ce tutoriel concerne Papervision3D en Flash, mais qu’il s’agit en réalité de tromper votre cerveau. Nous allons faire croire à votre cerveau qu'il regarde un objet 3D réel, alors qu'en fait, il ne s'agit que de voir une image 2D.

Si vous connaissez Papervision3D, vous pourrez le suivre en utilisant n’importe quel projet comportant une scène, une caméra et une fenêtre. Sinon, jetez un œil à la première partie de ce didacticiel, car je vais continuer là où nous en étions restés. Voici le genre de chose que nous allons travailler:

Étape 1: Ajouter une deuxième caméra

Pointez votre doigt en l'air et tenez-le devant votre nez..

Regardez-le simplement avec votre œil droit ouvert, puis juste avec votre gauche. Voyez comment il semble sauter de gauche à droite, alors que tout ce qui se trouve à l'arrière-plan semble à peine bouger?

Votre cerveau remarque ces différences entre ce que chacun de vos yeux voit et les utilise pour générer une simulation 3D complète du monde qui vous entoure. Dans ta tête. Immédiatement. Assez impressionnant!

Si nous voulons tromper votre cerveau, nous devrons faire en sorte que chacun de vos yeux voie une image différente. Alors pour commencer, ajoutons un autre "œil" (une autre caméra) à la scène. Ceci sera utilisé pour créer l'image pour votre œil droit, tandis que l'image de la caméra existante sera transmise à votre œil gauche.

Créez une nouvelle variable publique appelée camera2

 var publique camera2: Camera3D;

… Et l'initialiser dans la fonction constructeur Main ():

 camera = new Camera3D ();

Étape 2: Créer une nouvelle fenêtre

Nous aurons besoin d'une autre fenêtre pour prendre la sortie de la caméra, ajoutez donc ce qui suit:

 public var viewport2: Viewport3D;
 viewport2 = new Viewport3D (); viewport2.autoScaleToStage = true; // cela va rendre la fenêtre d'affichage aussi grande que la scène addChild (viewport2);

(Je me précipite à ce sujet, puisque nous avons tout couvert la dernière fois.)

Étape 3: Rendre la deuxième caméra dans la deuxième fenêtre

Rappelles toi, viewport2 sera vide jusqu'à ce que nous lui rendions quelque chose. Nous n'avons pas besoin de créer un nouveau moteur de rendu pour cela; utilisez simplement l'existant deux fois. Donc, dans Main (), prenez ce code:

 renderer = new BasicRenderEngine (); renderer.renderScene (scène, caméra, fenêtre d'affichage);

… Et ajoutez une nouvelle ligne pour rendre la deuxième caméra à la deuxième fenêtre, comme suit:

 renderer = new BasicRenderEngine (); renderer.renderScene (scène, caméra, fenêtre d'affichage); renderer.renderScene (scene, camera2, viewport2);

Faites la même chose dans votre fonction onEnterFrame ():

 renderer.renderScene (scène, caméra, fenêtre d'affichage); renderer.renderScene (scene, camera2, viewport2);

Si vous testez cela maintenant, eh bien, ça aura le même aspect qu'avant:

Mais ce n’est pas une surprise: d’une part, les deux caméras sont exactement au même endroit!

Étape 4: séparez les caméras

Par défaut, les caméras sont placées à (x = 0, y = 0, z = -1000) - vous pouvez vérifier en faisant trace (camera.x, camera.y, camera.z).

Alors vue d'en haut, la scène ressemble à ceci:

Vu de côté, c'est comme ça:

Pour bien imiter nos propres yeux, nous devrions placer notre deuxième caméra un peu à droite de notre première:

Essayons de le déplacer de 50 pixels vers la droite et voyons ce qui se passe. Mettez ceci dans Main (), quelque part après la création de la deuxième caméra:

 camera2.x = camera.x + 50;

Maintenant, testez-le et voyez ce que vous obtenez:

Ça a l'air bizarre, mais ça fonctionne clairement! La zone entourant les cubes est transparente dans chaque fenêtre. Ainsi, le premier est visible derrière le second..

Étape 5: Faites-le cligner!

Il sera utile de pouvoir regarder ce que chaque caméra voit individuellement, alors allons au-delà de l'analogie visuelle en les faisant "cligner des yeux" lorsque nous cliquons. Tout d’abord, ajoutez un écouteur d’événements à chaque fenêtre pour détecter les clics de souris:

 viewport.addEventListener (MouseEvent.CLICK, onClickViewport); viewport2.addEventListener (MouseEvent.CLICK, onClickViewport2);

Mettez cela à la fin de la fonction Main (). N'oubliez pas d'importer MouseEvent:

 import flash.events.MouseEvent;

Étape 6: Configuration des gestionnaires d’événements Click

Ajoutez ces nouvelles fonctions à votre code, en dehors de la fonction Main () mais à l'intérieur de la classe Main:

 fonction publique onClickViewport (mouseEvt: MouseEvent): void  fonction publique onClickViewport2 (mouseEvt: MouseEvent): void 

Étape 7: Basculer la visibilité de la fenêtre d'affichage

Lorsque nous cliquons sur la première fenêtre, nous avons besoin qu'elle devienne invisible et que la seconde devienne visible (et vice-versa, lorsque nous cliquons sur la seconde). Alors modifiez vos gestionnaires d’événements de la manière suivante:

 fonction publique onClickViewport (mouseEvt: MouseEvent): void viewport.visible = false; viewport2.visible = true;  fonction publique onClickViewport2 (mouseEvt: MouseEvent): void viewport.visible = true; viewport2.visible = false; 

Essaye le:

Notez que vous devez cliquer sur l'un des cubes. les zones transparentes ne déclenchent pas un MouseEvent CLICK.

Étape 8: Trouvez des lunettes 3D

Vous allez avoir besoin d'une paire de lunettes 3D "anaglyphes"; le genre où chaque objectif est une couleur différente. La paire que j'utilise a un objectif jaune à l'œil gauche et un objectif bleu à l'œil droit (appelé système ColorCode3D), mais d'autres combinaisons de couleurs sont également populaires, comme le rouge et le cyan..

Vous pouvez trouver ces lunettes sur eBay pour quelques dollars: il suffit de chercher lunettes 3D

Alternativement, vous pouvez même faire le vôtre! André a posté un commentaire sur la première partie de ce tutoriel en expliquant qu’il utilise des boîtes de Tic-Tac de différentes couleurs pour fabriquer le sien. Génie!

Bien que mes exemples soient conçus pour les lunettes jaunes et bleues, je vais essayer d’expliquer les principes afin que vous puissiez utiliser les couleurs que vous possédez. C'est un peu délicat, alors merci de poster un commentaire ci-dessous si cela devient confus!

Étape 9: Comprendre le fonctionnement des lunettes

Chaque pixel de votre ordinateur est comme un groupe de trois ampoules: une rouge, une verte et une bleue.

En ajustant la luminosité de chaque "ampoule", nous pouvons modifier la couleur de ce pixel:

  • Un pixel blanc a les trois ampoules allumées complètement
  • Un pixel noir a les trois éteints
  • Un pixel vert a le bulbe vert allumé et les deux autres éteints

Les lentilles des lunettes 3D empêchent la lumière de traverser certaines de ces ampoules. Par exemple, la lentille bleue de mes lunettes empêche la lumière rouge et verte d’atteindre l’œil.

Donc, si je regarde cette image à travers mon objectif bleu, je ne pourrai pas la lire:

Aucune lumière ne parvient à mes yeux depuis la zone noire, car les trois ampoules sont éteintes. Et aucune lumière ne parvient à mes yeux depuis la zone verte, car seule l'ampoule verte est allumée et la lentille bleue la filtre. Donc tout ce que je vois est un rectangle noir.

Bon, d'accord, si vous essayez cela vous-même, vous constaterez peut-être que ce n'est pas tout à fait vrai. Votre objectif n’est probablement pas 100% bleu pur, alors il laisse passer un peu de lumière verte et rouge. Ou peut-être que les couleurs de votre moniteur sont calibrées différemment des miennes, le texte vert contient donc une petite quantité de rouge et de bleu. Pour être honnête, il en va de même pour moi - mais cela n'a pas d'importance, tant que le texte est difficile lire.

Notre objectif est de rendre difficile pour votre œil droit de voir l'image de la caméra gauche, ainsi que pour votre œil gauche et la caméra droite.

Étape 10: Rendre la fenêtre gauche invisible à votre œil droit

La lentille bleue est au-dessus de mon œil droit, donc en théorie, si je supprime tout le bleu de l'image de la caméra gauche, je ne pourrai pas le voir de mon œil droit..

Dans cette étape, faisons en sorte que l'image de la fenêtre de gauche n'émette que de la lumière rouge et verte; pas de lumière bleue du tout. Nous pouvons le faire en utilisant un ColorTransform. Celles-ci sont faciles à mettre en place. d'abord, importez la classe:

 import flash.geom.ColorTransform;

Ensuite, créez une nouvelle variable publique pour contenir une instance de la classe:

 public var leftViewportColorTransform: ColorTransform;

Maintenant, créez réellement cette nouvelle instance dans Main ():

 leftViewportColorTransform = new ColorTransform ();

Enfin, indiquez à Flash d’appliquer ce ColorTransform à la fenêtre de l’appareil photo de gauche:

 viewport.transform.colorTransform = leftViewportColorTransform;

(Cette dernière ligne doit être postérieure à la création de la fenêtre et de la transformation de couleur. Il est probablement plus simple de la mettre à la fin de Main ().)

Étape 11: Supprimer tout le bleu de la fenêtre

Le fichier SWF ne sera pas encore différent, car ColorTransform ne modifie pas du tout l'image par défaut..

Nous pouvons choisir quelle fraction de la lumière de chaque ampoule nous voulons laisser passer en modifiant la blueMultiplier, greenMultiplier et multiplicateur rouge propriétés de notre ColorTransform.

Définir l’un de ces éléments pour 1 indique à Flash de le laisser tranquille tout en le configurant 0 indique à Flash de l'éteindre complètement. Et naturellement, 0.5 le fera sortir la moitié de la quantité normale, 2.0 va le faire doubler, et ainsi de suite.

Donc, pour vider tout le bleu de la fenêtre de gauche, nous pouvons le faire:

 leftViewportColorTransform.blueMultiplier = 0;

Vous devez mettre cela avant la ligne qui applique la transformation à la fenêtre d'affichage, comme ceci:

 leftViewportColorTransform.blueMultiplier = 0; viewport.transform.colorTransform = leftViewportColorTransform;

Si vos lunettes ont une lentille rouge ou verte sur l’œil droit, vous devez régler le multiplicateur rouge ou greenMultiplier à 0, plutôt que le bleu. Pour toutes les autres couleurs, vous devrez utiliser un mélange de rouge, de vert et de bleu - pour plus d'informations à ce sujet à l'étape 15.

Testez le fichier SWF:

Il est difficile de distinguer le "a" du logo à travers l'objectif bleu, mais il n'est pas difficile du tout de distinguer la forme des cubes sur ce fond blanc.!

Étape 12: Remplir les zones transparentes

Si vous modifiez l'arrière-plan de votre fichier SWF, le problème apparaît. Parce que la zone "blanche" autour des cubes n'est pas réellement blanche, mais plutôt transparente et laisse transparaître le fond blanc du fichier SWF, il n'est pas affecté par ColorTransform..

Pour résoudre ce problème, nous devons attribuer à la fenêtre d'affichage un fond blanc et solide sur lequel les cubes seront restitués. C'est assez facile. retournez simplement à l'endroit où vous avez créé la fenêtre:

 viewport = new Viewport3D (); viewport.autoScaleToStage = true; // cela va rendre la fenêtre aussi grande que la scène

… Et ajoutez quelques lignes pour dessiner un rectangle blanc aussi grand que la scène:

 viewport = new Viewport3D (); viewport.autoScaleToStage = true; // cela va rendre la fenêtre d'affichage aussi grande que la scène viewport.graphics.beginFill (0xffffff); // 0xffffff est blanc viewport.graphics.drawRect (0, 0, stage.stageWidth, stage.stageHeight);

Testez à nouveau:

L'image doit être très sombre, terne et difficile à voir à travers l'objectif droit, mais aussi facile que l'image ordinaire à voir à travers l'objectif gauche.

Étape 13: Créer un nouveau ColorTransform

Nous devons faire la même chose pour la bonne fenêtre maintenant. Alors, créez votre nouveau ColorTransform:

 public var rightViewportColorTransform: ColorTransform;
 rightViewportColorTransform = new ColorTransform ();

Étape 14: Appliquer le nouveau ColorTransform

Appliquez maintenant cette nouvelle transformation à la fenêtre de droite:

 viewport2.transform.colorTransform = rightViewportColorTransform;

Étape 15: Supprimez tout le jaune de la fenêtre

Comme mon objectif gauche est jaune, je dois vider tout le jaune de cette fenêtre..

(Si votre objectif gauche est rouge, cette étape est simple: il vous suffit de régler le multiplicateur rouge de votre nouveau ColorTransform à 0.)

Mais comment pouvons-nous obtenir le jaune du rouge, du vert et du bleu?

Si nous utilisions de la peinture, nous ne pourrions pas; le jaune est une couleur primaire dans ce cas. Mais lorsqu'il s'agit de lumière, les choses sont différentes. Regarde ça:

Image de Wikimedia Commons. Merci, Mike Horvath et Jacobolus!

Comme vous pouvez le constater, le rouge et le vert se mélangent pour former le jaune (ce qui explique pourquoi l'arrière-plan de la fenêtre de gauche est devenu jaune lorsque nous avons supprimé tout le bleu). Donc, pour supprimer tout le jaune de notre image, nous devons supprimer tout le rouge et tout le vert!

On peut faire ça comme ça:

 rightViewportColorTransform = new ColorTransform (); rightViewportColorTransform.redMultiplier = 0; rightViewportColorTransform.greenMultiplier = 0; viewport2.transform.colorTransform = rightViewportColorTransform;

Oh, d'accord, nous devons également remplir l'arrière-plan de cette fenêtre..

Étape 16: Remplissez les zones transparentes

Faites cela de la même manière que précédemment:

 viewport2 = new Viewport3D (); viewport2.autoScaleToStage = true; // cela va rendre la fenêtre d'affichage aussi grande que la scène viewport2.graphics.beginFill (0xffffff); // 0xffffff est blanc viewport2.graphics.drawRect (0, 0, stage.stageWidth, stage.stageHeight);

Testez-le:

La lentille jaune de mes lunettes laisse passer une bonne quantité de lumière bleue, mais elle est toujours beaucoup plus sombre à travers cette lentille que lorsque vous la regardez à travers une lentille bleue, et c'est ce qui compte.

Étape 17: Fusionnez les deux images

Nous avons donc nos deux images préparées et transformées en couleurs. Le problème, c’est que pour le moment, nous ne pouvons en voir qu’un à la fois..

La façon la plus évidente de voir les deux à la fois est de réduire l’alpha (la transparence) de la fenêtre au premier plan, comme suit:

 viewport2.alpha = 0,5;

Testez ceci:

Ah OK, pas un succès enthousiaste. Alpha n'est clairement pas le bon outil pour le poste. qu'avons-nous d'autre?

Étape 18: Mélanger les deux images

Flash nous donne le choix entre plusieurs modes de fusion, méthodes de fusion de deux objets d'affichage. Il y en a une liste complète ici, mais je vais me concentrer sur celui qui s'appelle ajouter.

le ajouter mode de fusion passe par chaque pixel des deux images, et ajoute la luminosité de chacune des trois ampoules.

Ainsi, si un pixel de la première image a l’ampoule verte complètement allumée et les deux autres complètement éteints, et que le même pixel de la deuxième image a l’ampoule bleue complètement allumée et les deux autres complètement éteints, puis, une fois fusionnés, le vert et les ampoules bleues seront complètement allumées et l'ampoule rouge sera complètement éteinte.

Si les ampoules rouges sont à moitié allumées dans les première et seconde images et que les deux autres sont complètement éteintes, l'ampoule rouge sera complètement allumée, tandis que les deux autres resteront éteintes..

Obtenez la photo? Génial, utilisons-le. Supprimez la ligne que nous venons d'écrire qui a ajusté l'alpha et remplacez-la par ceci:

 viewport2.blendMode = "add";

(Nous n'avons pas besoin d'appliquer le mode de fusion aux deux fenêtres, mais uniquement à celle située en haut de la liste.)

Testez-le:

C'est plus comme ça!

Si vous le regardez à travers un œil à la fois, vous remarquerez que chaque œil voit une fenêtre d'affichage différente de manière plus visible. Vous pourrez probablement également voir un faible fantôme de l'autre fenêtre d'affichage, mais ce n'est pas un problème. ton cerveau peut ignorer ça.

Cependant, l'image n'a pas encore l'air 3D. Réglons ça.

Étape 19: Ajustez la séparation

Même si vos yeux voient des images différentes, cela ne suffit pas à tromper votre cerveau. Votre cerveau est assez intelligent, vous voyez; Certains diraient même que c'est l'organe le plus intelligent de votre corps. Il sait qu'il doit utiliser d'autres indices pour déterminer si un objet est en 3D ou non. Perspective, par exemple: à quel point un objet doit paraître petit en fonction de son éloignement.

Le principal problème ici est que nos deux caméras sont beaucoup plus éloignées l'une de l'autre que nos propres yeux. Ce n'est pas surprenant, puisque j'ai choisi le nombre 50 au hasard.

La distance de séparation que nous devrions utiliser dépendra de plusieurs facteurs, tels que la distance qui vous sépare du moniteur et la taille de votre écran. Je ne peux donc pas vous donner un nombre magique à utiliser. Nous devrons le comprendre manuellement.

Nous pourrions le faire en essayant un grand nombre de chiffres différents un par un, mais cela est fastidieux et prendra une éternité. J'ai une meilleure idée.

Ajoutez cette ligne à votre fonction onEnterFrame ():

 camera2.x = camera.x + (mouseX * 0.1);

Modifiez maintenant vos fonctions onClickViewport et onClickViewport2 comme suit:

 fonction publique onClickViewport (mouseEvt: MouseEvent): void trace (camera2.x - camera.x);  fonction publique onClickViewport2 (mouseEvt: MouseEvent): void trace (camera2.x - camera.x); 

Exécutez le fichier SWF, puis déplacez la souris vers la gauche et la droite. Ça va ressembler à ça:

Mettez vos lunettes, éteignez les lumières et continuez à déplacer la souris jusqu'à ce que vous trouviez le "point idéal" où l'image semble devenir solide. Cliquez sur la souris à ce stade, et il va tracer un nombre. En prendre note!

Étape 20: Définissez la séparation

Une fois que vous avez trouvé la séparation optimale, supprimez la ligne que nous venons d'ajouter à la fonction onEnterFrame ():

 camera2.x = camera.x + (mouseX * 0.1);

Maintenant, trouvez la ligne dans Main () où vous définissez la distance entre les caméras:

 camera2.x = camera.x + 50;

… Et remplacez le 50 par le numéro que vous avez noté. J'ai trouvé que 18 était un bon nombre à utiliser pour ma configuration.

Enfin, testez le fichier SWF:

Ta-da!

Conclusion

Bien fait - vous avez créé une scène 3D dans Flash et utilisé des astuces pour la transférer dans une scène 3D à l'intérieur de votre tête;)

Si vous avez compris tout ce que vous avez vécu, vous devriez pouvoir utiliser la même technique pour créer des images anaglyphes 3D à l'aide d'autres moteurs 3D..

J'ai mentionné dans la première partie que vous voudriez peut-être essayer de permettre à l'utilisateur de déplacer la caméra avec la souris. Maintenant que vous avez ajouté l'effet anaglyphe, déplacer les caméras vers l'avant et l'arrière sera très impressionnant.

Merci d'avoir lu ce tutoriel, j'espère que vous l'avez trouvé utile. Comme toujours, si vous avez des questions, veuillez les poser dans les commentaires ci-dessous..