Pour faire écho à notre cadeau Papervision3D Essentials, le didacticiel d’aujourd’hui comporte également un thème PV3D..
Ce didacticiel en deux parties vous montrera comment utiliser le moteur Papervision3D, puis comment faire en sorte que votre création sorte de l'écran en utilisant un effet anaglyphe associé à des lunettes 3D..
Vous avez une paire de lunettes 3D qui traînent? Ici au Royaume-Uni, Channel 4 organise une semaine spéciale 3D - sept jours de programmes télévisés diffusés en 3D -, donc beaucoup de gens le font ici. Mettons-les à utiliser.
Ce didacticiel en deux parties vous montrera comment utiliser le moteur Papervision3D, puis comment faire en sorte que votre création sorte de l'écran..
Dans cette première partie, vous allez apprendre les bases de PV3D, avec comme résultat:
… Et dans la seconde partie, vous découvrirez l'effet anaglyphe des lunettes 3D et l'appliquerez à ce que vous avez créé:
Si vous utilisez Flash, créez un nouveau fichier Flash ActionScript 3.0. Définissez la taille de la scène comme vous le souhaitez - je m'en tiendrai au paramètre par défaut de 550 x 400 pixels.
Pendant que vous y êtes, créez un nouveau fichier ActionScript et enregistrez-le sous. Main.as dans le même dossier que votre FLA. Nous allons utiliser ce fichier AS en tant que FLA classe de document, alors cliquez sur un espace vide dans votre fichier FLA, et entrez Principale dans la zone "Classe de document" du panneau Propriétés.
(Si vous n'utilisez pas l'IDE Flash, créez simplement un nouveau projet AS3.)
Rendez-vous sur la page de téléchargement de Papervision. Il y a beaucoup de versions différentes et quelques types de fichiers différents (zip, swc, mxp). Il suffit de saisir le dernier fichier .zip (il devrait indiquer En vedette à côté de cela). Celui que j'utilise s'appelle Papervision3D 2.1.920.zip (à utiliser avec le livre "Papervision3D Essentials").
Extrayez le fichier zip que vous venez de télécharger n'importe où sur votre disque dur. J'aime garder tous les moteurs que j'utilise dans le même dossier, mais c'est à vous de voir.
Flash doit savoir où vous avez extrait Papervision avant de pouvoir l'utiliser. Nous utilisons un classpath pour cela: clic Édition> Préférences, sélectionner ActionScript, puis clique Paramètres ActionScript 3.0… .
Dans la zone qui apparaît, cliquez sur la petite icône "réticule", recherchez le dossier dans lequel vous avez décompressé Papervision et cliquez sur OK. Cliquez sur OK pour les autres zones jusqu'à ce que vous reveniez à la FLA..
Si vous n'utilisez pas l'IDE Flash, vous devrez définir ceci d'une manière différente. Par exemple, dans FlashDevelop, vous devez cliquer sur Outils> Classpaths globaux.
Dans Papervision, tous vos objets 3D doivent être placés dans un scène. C'est un peu comme la scène dans ActionScript classique. Donc, avant de faire quoi que ce soit, nous devons créer un Scene3D objet qui contiendra tout le reste.
Basculez vers votre fichier Main.as. Ajoutons rapidement le code de base nécessaire à toute classe de document:
package import flash.display.MovieClip; Classe publique Main étend MovieClip fonction publique Main ()
L'objet Scene3D est en org.papervision3d.scenes.Scene3D, donc nous devons importation que, puis créer un nouveau var publique pour tenir la scène et enfin créer l'objet de la scène: (lignes 4, 8 et 12)
package import flash.display.MovieClip; import org.papervision3d.scenes.Scene3D; public class Main étend MovieClip public var scene: Scene3D; fonction publique Main () scene = new Scene3D ();
Pour commencer, créons simplement un grand cube simple dans notre scène.
Nous allons suivre les mêmes étapes que ci-dessus pour le créer, puis l'ajouter à notre scène: (lignes 5, 10, 15, 16)
package import flash.display.MovieClip; import org.papervision3d.scenes.Scene3D; import org.papervision3d.objects.primitives.Cube; public class Main étend MovieClip public var scene: Scene3D; var cube public: Cube; fonction publique Main () scene = new Scene3D (); cube = nouveau Cube (); scene.addChild (cube);
Notez que nous utilisons "addChild ()" pour ajouter le cube à la scène, exactement comme lors de l'ajout d'un MovieClip à la scène..
Le code ci-dessus vous donnera une erreur si vous essayez de l'exécuter. C'est parce que nous n'avons pas dit au cube à quoi devrait ressembler sa surface..
Papervision utilise matériaux décrire l'aspect d'une surface. Nous pouvons fabriquer un matériau très simple, unicolore, en utilisant un ColorMaterial:
var grayMaterial: ColorMaterial = new ColorMaterial (0xCCCCCC);
"0xCCCCCC" représente la couleur grise; il suffit de prendre le code de couleur de n'importe quelle couleur et de remplacer le # avec 0x:
Parce qu'un cube a six faces, nous devons lui donner six matériaux. Pour ce faire, nous mettons les six dans une liste:
var materialsList: MaterialsList = new MaterialsList (); materialsList.addMaterial (grayMaterial, "front"); materialsList.addMaterial (grayMaterial, "back"); materialsList.addMaterial (grayMaterial, "left"); materialsList.addMaterial (grayMaterial, "right"); materialsList.addMaterial (grayMaterial, "top"); materialsList.addMaterial (grayMaterial, "bottom");
… Puis transmettons cette liste au cube lorsque nous la créons:
cube = nouveau cube (liste de matériaux);
Ainsi, tout votre code devrait ressembler à ceci: (n'oubliez pas le importation déclarations!)
package import flash.display.MovieClip; import org.papervision3d.scenes.Scene3D; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.materials.utils.MaterialsList; public class Main étend MovieClip public var scene: Scene3D; var cube public: Cube; fonction publique Main () var grayMaterial: ColorMaterial = new ColorMaterial (0xCCCCCC); var materialsList: MaterialsList = new MaterialsList (); materialsList.addMaterial (grayMaterial, "front"); materialsList.addMaterial (grayMaterial, "back"); materialsList.addMaterial (grayMaterial, "left"); materialsList.addMaterial (grayMaterial, "right"); materialsList.addMaterial (grayMaterial, "top"); materialsList.addMaterial (grayMaterial, "bottom"); scene = new Scene3D (); cube = nouveau cube (liste de matériaux); scene.addChild (cube);
Donc, nous n’avons aucune erreur, mais pour voir quoi que ce soit, nous devons ajouter un caméra à la scène. Nous verrons tout à travers "l'objectif" de la caméra.
Ajouter une caméra est aussi simple que d’ajouter un cube - en fait, il n’est pas nécessaire de l’ajouter à la scène:
importer org.papervision3d.cameras.Camera3D;
caméra var publique: Camera3D;
scene = new Scene3D (); cube = nouveau cube (liste de matériaux); scene.addChild (cube); camera = new Camera3D (); // c'est la nouvelle ligne dans Main ()
Maintenant, une caméra est sur la scène, mais elle n'est reliée à aucune sortie. Nous ne pouvons donc toujours pas voir le cube.!
Par défaut, le cube est placé bien en plein milieu de la scène (à x = 0, y = 0, z = 0) et la caméra est positionnée à 1000 unités de lui (à x = 0, y = 0, z = -1000).
Comment pouvons-nous obtenir l'image que la caméra voit dans la fenêtre de Flash Player?
La réponse est, nous utilisons un fenêtre d'affichage. Ceci est un type de DisplayObject, comme un MovieClip, afin que nous puissions l’ajouter à la scène. Mais on peut aussi faire Papervision rendre (c'est-à-dire dessiner) la vue de la caméra dans cette fenêtre - c'est un peu comme si un artiste dessinait ce qu'il pouvait voir à travers une lentille de caméra, puis prenait son dessin et le collait à un téléviseur. Sauf plus vite.
Nous devons donc créer une fenêtre et un moteur de rendu:
importer org.papervision3d.view.Viewport3D; import org.papervision3d.render.BasicRenderEngine;
public viewport var: Viewport3D; public var renderer: BasicRenderEngine;
// place ceci à la fin de Main () viewport = new Viewport3D (); viewport.autoScaleToStage = true; // cela va rendre la fenêtre d'affichage aussi grande que la scène addChild (viewport); renderer = new BasicRenderEngine ();
Il ne reste plus qu’à faire en sorte que le moteur de rendu effectue le rendu. Pour cela, il doit connaître la scène, la caméra et la fenêtre de visualisation:
renderer.renderScene (scène, caméra, fenêtre d'affichage);
Enfin! Nous pouvons enfin tester le fichier SWF. Roulement de tambour s'il vous plaît…
Incroyable! Étonnant! OK bien, c'est en fait assez boiteux. Comment pouvons-nous même dire que c'est un cube? Ça ressemble à un carré.
Si nous faisons tourner le cube, nous serons en mesure de dire s'il s'agit ou non d'un cube.
Comme le cube est en trois dimensions, le mot "rotation" est un peu déroutant - quelle direction voulons-nous dire? Nous devons spécifier si nous tournons autour de l'axe des x, des y ou des z.
le cube L'objet a trois propriétés que nous pouvons utiliser pour définir cela, appelée (sans surprise) rotationX, rotationY et rotationZ. Changeons-en quelques-uns:
scene = new Scene3D (); cube = nouveau cube (liste de matériaux); cube.rotationX = 25; // change le cube de rotation.rotationY = 40; // change la rotation scene.addChild (cube); camera = new Camera3D ();
C'est mieux, mais comme tous les visages ont exactement la même couleur, ils se fondent l'un dans l'autre. Corrigeons ça.
Au lieu de gris, je vais peindre les côtés avec le logo ActiveTuts +.
Si vous utilisez Flash IDE, créez un nouveau clip et tracez ou collez l'image que vous souhaitez utiliser. J'ai inclus le logo dans la bibliothèque de ma FLA à l'intérieur du zip.
Cliquez avec le bouton droit sur votre clip et sélectionnez Propriétés. Cochez "export for ActionScript" et donnez-lui un nom de classe. Cela vous permettra d'y accéder en utilisant le code. (Si vous n'utilisez pas l'IDE Flash, le zip contient également un SWC avec un MovieClip appelé ActiveTutsLogo que vous pouvez utiliser. Ou vous pouvez créer un nouveau MovieClip dans le code et y ajouter votre image. entrer dans les détails de cela ici, cependant.)
Au lieu d'une ColorMaterial nous allons utiliser un MovieMaterial, et au lieu de spécifier une couleur, nous allons spécifier un clip. Alors remplacez ceci:
var grayMaterial: ColorMaterial = new ColorMaterial (0xCCCCCC); var materialsList: MaterialsList = new MaterialsList (); materialsList.addMaterial (grayMaterial, "front"); materialsList.addMaterial (grayMaterial, "back"); materialsList.addMaterial (grayMaterial, "left"); materialsList.addMaterial (grayMaterial, "right"); materialsList.addMaterial (grayMaterial, "top"); materialsList.addMaterial (grayMaterial, "bottom");
… avec ça:
var logoMaterial: MovieMaterial = new MovieMaterial (new ActiveTutsLogo ()); // remplace "ActiveTutsLogo" ci-dessus par le nom de classe de votre clip. var materialsList: MaterialsList = new MaterialsList (); materialsList.addMaterial (logoMaterial, "front"); materialsList.addMaterial (logoMaterial, "back"); materialsList.addMaterial (logoMaterial, "left"); materialsList.addMaterial (logoMaterial, "right"); materialsList.addMaterial (logoMaterial, "top"); materialsList.addMaterial (logoMaterial, "bottom");
Vous devrez également importer le MovieMaterial:
import org.papervision3d.materials.MovieMaterial;
Testez à nouveau:
Eh bien, ça marche, mais ça a l'air un peu bosselé.
L'aspect "bosselé" vient du fait que Papervision est configuré par défaut pour dessiner rapidement et non avec précision. Je veux m'assurer que ce tutoriel fonctionnera sur des ordinateurs plus lents, je vais donc en rester là, mais voici comment vous pouvez l'améliorer:
Lorsque vous créez le cube, vous pouvez lui passer des paramètres pour définir le nombre de segments chaque visage est divisé en. Plus vous choisissez de segments, plus le cube est précis, mais plus le rendu sera lent.
J'ai trouvé que 10 correspond à un bon nombre de segments à utiliser dans chaque direction. Voici comment le code pour cela ressemble:
cube = nouveau cube (matériaux, 500, 500, 500, 10, 10, 10);
Les cinquième, sixième et septième paramètres définissent le nombre de segments utilisés dans chaque direction. Pour les définir, cependant, nous devons spécifier tous les paramètres avant le cinquième aussi.
Nous spécifions déjà le premier paramètre - c'est la liste des matériaux. Les deuxième, troisième et quatrième paramètres définissent la largeur, la profondeur et la hauteur du cube. Celles-ci sont réglées sur 500 par défaut, je les ai donc conservées ici.
Si vous utilisez la ligne de code ci-dessus, votre cube ressemblera à ceci:
Beaucoup plus propre!
Nous pouvons faire tourner un MovieClip régulièrement en augmentant son rotation propriété chaque image - et bien sûr, nous pouvons faire la même chose avec le cube et ses valeurs rotationX / Y / Z.
Créez un écouteur d'événement ENTER_FRAME, qui exécutera chaque image:
import flash.events.Event;
// au bas de Main () addEventListener (Event.ENTER_FRAME, onEnterFrame);
// en tant que nouvelle fonction // à l'intérieur de la classe Main mais à l'extérieur de la fonction Main () public function onEnterFrame (evt: Event): void cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5;
Cela fera tourner le cube un peu plus chaque image. Donc, si vous testez le fichier SWF maintenant… le cube restera complètement immobile. Hein?
Repensez au peintre. Nous continuons à regarder son ancienne photo - nous avons besoin de lui pour nous en dessiner une nouvelle à chaque image, sinon nous ne verrons aucun changement!
Alors, modifiez la fonction onEnterFrame ():
fonction publique onEnterFrame (evt: Event): void cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5; renderer.renderScene (scène, caméra, fenêtre d'affichage);
Vérifiez-le maintenant:
Un cube est génial, mais comme Roman vous a déjà montré comment faire cela avec Away3D, allons un peu plus loin..
Ajoutons un peu plus, pour former une ligne horizontale de cubes. Nous pouvons utiliser un simple pour boucle pour le faire; il suffit de remplacer ce code:
cube = nouveau cube (liste de matériaux); cube.rotationX = 25; // change le cube de rotation.rotationY = 40; // change la rotation scene.addChild (cube);
… avec ça:
pour (var i: int = -1; i <= 1; i++ ) cube = new Cube( materialsList ); cube.x = i * 350; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube );
Notez que je fais en sorte que la position x de chaque cube dépende de la distance qui nous sépare de la boucle. Si vous exécutez ceci, vous obtiendrez ce qui suit:
Oups, les cubes sont trop rapprochés. Nous pouvons les réduire pour éviter cela; il suffit de changer le échelle propriété de chaque cube:
pour (var i: int = -1; i <= 1; i++ ) cube = new Cube( materialsList ); cube.x = i * 350; cube.scale = 0.40; //make the cubes 40% of original size cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube );
Cela résout donc le problème d'intersection, mais un seul de nos cubes est en train de tourner. Comment venir?
C'est parce que cube variable se réfère toujours uniquement à la dernier cube créé - et notre fonction onEnterFrame () ne modifie que les rotations de ce cube.
Donc, pour résoudre ce problème, nous aurons besoin d'un tableau. Tout comme notre liste de matériel stocké plusieurs matériaux, notre Array stockera plusieurs cubes.
public var cubeArray: Array;
cubeArray = new Array (); // crée le nouveau tableau pour (var i: int = -1; i <= 1; i++ ) cube = new Cube( materialsList ); cube.x = i * 350; cube.scale = 0.40; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube ); cubeArray.push( cube ); //add the new cube to the array
("Push" signifie simplement "ajouter à la fin de la liste".)
Maintenant que chaque cube est dans le tableau, nous pouvons parcourir le tableau de chaque image et faire pivoter chacun d'entre eux:
fonction publique onEnterFrame (evt: Event): void pour chaque (cube dans cubeArray) cube.rotationX = cube.rotationX + 5; cube.rotationY = cube.rotationY + 5; renderer.renderScene (scène, caméra, fenêtre d'affichage);
La boucle "pour chaque" fait la cube variable fait référence à chaque cube, tour à tour, plutôt qu’au dernier cube créé comme auparavant. Voici le résultat:
Succès!
Nous avons créé une ligne de cubes, donc un carré ne va pas être difficile. Au lieu de faire trois cubes, nous en ferons trois lignes de trois cubes.
Pour ce faire, nous pouvons utiliser une boucle dans une boucle, comme ceci:
pour (var i: int = -1; i <= 1; i++ ) for ( var j:int = -1; j <= 1; j++ ) //loop inside a loop cube = new Cube( materialsList ); cube.x = i * 350; cube.y = j * 350; //don't forget to change j! cube.scale = 0.40; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube ); cubeArray.push( cube ); //don't forget this closing bracket either
Testez-le:
Agréable. Et notez que nous n’avions pas du tout besoin de changer le code dans onEnterFrame (); la boucle qui exécute chaque image fait simplement pivoter chaque cube du tableau - et nous poussons toujours chaque cube sur le tableau.
Eh bien, il serait décevant de s'arrêter sur une place, n'est-ce pas? Après tout, ceci est un tutoriel 3D.
Je m'attends à ce que vous sachiez comment faire cette étape par vous-même. Mais au cas où vous voudriez comparer:
pour (var i: int = -1; i <= 1; i++ ) for ( var j:int = -1; j <= 1; j++ ) for ( var k:int = 0; k <= 2; k++ ) cube = new Cube( materialsList ); cube.x = i * 350; cube.y = j * 350; cube.z = k * 350; cube.scale = 0.40; cube.rotationX = 25; cube.rotationY = 40; scene.addChild( cube ); cubeArray.push( cube );
J'ai été un peu sournois ici. J'ai commencé k à 0 au lieu de -1, car sinon la couche de cubes la plus en avant serait trop proche de la caméra. Bien sûr, vous pouvez utiliser les numéros de votre choix.
Hé, avez-vous remarqué que l'effet "bosselé" a pratiquement disparu maintenant que nous utilisons des cubes plus petits?
Impressionnant!
Cela ne fait que gratter la surface de ce que vous pouvez faire avec Papervision3D. Avant de passer aux lunettes 3D, voici quelques exemples d'expérimentations possibles:
Dans la deuxième partie, vous apprendrez à faire fonctionner votre scène avec des lunettes 3D. Donc, si vous en avez une paire, ne les jetez pas!
En attendant, merci d'avoir lu la première partie. J'espère que tu as trouvé ça utile. Si vous avez des questions, ou si quelque chose était source de confusion, veuillez poster un commentaire ci-dessous.