Utilisation de Viewports

Introduction

Pensez à un Viewport comme un écran sur lequel le jeu est projeté. Afin de voir le jeu, nous avons besoin d'une surface sur laquelle le dessiner ; cette surface est la Racine Viewport.

../../_images/viewportnode.png

Viewports peut aussi être ajouté à la scène pour qu'il y ait plusieurs surfaces sur lesquelles dessiner. Lorsque nous dessinons vers un Viewport qui n'est pas la Racine, nous l'appelons une cible de rendu. Nous pouvons accéder au contenu d'une cible de rendu en accédant à sa texture correspondante. En utilisant un Viewport comme cible de rendu, nous pouvons soit rendre plusieurs scènes simultanément, soit rendre vers un texture qui est appliqué à un objet dans la scène, par exemple une skybox dynamique.

Viewports ont une variété de cas d'utilisation, y compris :

  • Rendu d'objets 3D dans un jeu 2D

  • Rendu d'éléments 2D dans un jeu 3D

  • Rendu de textures dynamiques

  • Génération de textures procédurales pendant l'exécution

  • Rendu de plusieurs caméras dans la même scène

Le point commun de tous ces cas d'utilisation est que vous avez la possibilité de dessiner des objets sur une texture comme s'il s'agissait d'un autre écran et que vous pouvez ensuite choisir ce que vous voulez faire avec la texture résultante.

Entrée

Viewports sont aussi responsables de délivrer lesévénements d'entrée correctement ajustés et mis à l'échelle pour tous leurs nœuds enfants. Typiquement, l'entrée est reçue par le plus proche Viewport dans l'arbre, mais vous pouvez définir Viewports de ne pas recevoir d'entrée en cochant 'Disable Input' à 'on' ; ceci permettra au plus proche Viewport suivant dans l'arbre de capturer l'entrée.

../../_images/input.png

Pour plus d'informations sur la façon dont Godot gère les entrées, veuillez lire le Input Event Tutorial.

Auditeur

Godot supporte le son 3D (dans les nœuds 2D et 3D) ; plus d'informations à ce sujet peuvent être trouvées dans le Audio Streams Tutorial. Pour que ce type de son soit audible, le Viewport doit être activé en tant qu'auditeur (pour la 2D ou la 3D). Si vous utilisez un Viewport personnalisé pour afficher votre World, n'oubliez pas de l'activer !

Caméras (2D & 3D)

Lorsque vous utilisez une Camera / Camera2D, les caméras s'afficheront toujours sur le parent le plus proche Viewport (en allant vers la racine). Par exemple, dans la hiérarchie suivante :

../../_images/cameras.png

CameraA va afficher sur la Racine Viewport et il va dessiner le MeshA. CameraB sera capturé par le nœud Viewport avec MeshB. Même si MeshB est dans la hiérarchie de la scène, il ne sera toujours pas dessiné à la Racine Viewport. De même, MeshA ne sera pas visible depuis le nœud Viewport car les nœuds Viewport ne capturent que les nœuds situés en dessous d'eux dans la hiérarchie.

Il ne peut y avoir qu'une seule caméra active par Viewport, donc s'il y en a plus d'une, assurez-vous que celle désirée a la propriété "current" définie, ou faites-en la caméra courante en l'appelant :

camera.make_current()

Par défaut, les caméras rendent tous les objets de leur monde. En 3D, les caméras peuvent utiliser leur propriété cull_mask combinée avec la propriété VisualInstance layer pour restreindre les objets à rendre.

Échelle et étirement

Les Viewports ont une propriété "size", qui représente la taille du Viewport en pixels. Pour Viewports qui sont les enfants de ViewportContainers, ces valeurs sont surchargées, mais pour toutes les autres, cela fixe leur résolution.

Il est aussi possible de mettre à l'échelle le contenu 2D et de rendre la résolution du Viewport différente de celle spécifiée en taille, en appelant :

viewport.set_size_override(true, Vector2(width, height)) # Custom size for 2D.
viewport.set_size_override_stretch(true) # Enable stretch for custom size.

La racine Viewport utilise ceci pour les options d'étirement dans les paramètres du projet. Pour plus d'informations sur la mise à l'échelle et l'étirement, visitez le Multiple Resolutions Tutorial

Worlds

Pour la 3D, un Viewport contiendra un World. Il s'agit essentiellement de l'univers qui relie la physique et le rendu ensemble. Les nœuds basé sur Spatial s'enregistreront en utilisant le World du plus proche Viewport. Par défaut, les nouveaux Viewports ne contiennent pas de World mais utilisent le même que leur parent Viewport (le Viewport racine contient toujours un World, qui est celui vers lequel les objets sont rendus par défaut). Un World peut être défini dans un Viewport en utilisant la propriété "world", et cela séparera tous les nœuds enfants de ce Viewport de l'interaction avec le parent Viewport World. Ceci est particulièrement utile dans les scénarios où, par exemple, vous pourriez vouloir montrer un personnage séparé en 3D imposé sur le jeu (comme dans StarCraft).

Comme aide pour les situations où vous voulez créer des Viewports qui affichent des objets simples et où ne vous ne voulez pas créer un World, Viewport a l'option d'utiliser son propre World. C'est utile lorsque vous voulez instancier des personnages ou des objets 3D dans un environnement 2D World.

Pour la 2D, chaque Viewport contient toujours son propre World2D. Cela suffit dans la plupart des cas, mais au cas où partager serait souhaité, il est possible de le faire en paramétrant le Viewport's World2D manuellement.

Pour un exemple de fonctionnement, voir les projets de démonstration 3D in 2D et 2D in 3D respectivement.

Capturer

Il est possible de demander une capture du contenu d'un Viewport. Pour le Viewport racine, c'est effectivement une capture d'écran. Cela se fait avec le code suivant :

# Retrieve the captured Image using get_data().
var img = get_viewport().get_texture().get_data()
# Flip on the Y axis.
# You can also set "V Flip" to true if not on the root Viewport.
img.flip_y()
# Convert Image to ImageTexture.
var tex = ImageTexture.new()
tex.create_from_image(img)
# Set Sprite Texture.
$sprite.texture = tex

Mais si vous utilisez ceci dans _ready() ou depuis la première image de l'initialisation du Viewport, vous obtiendrez une texture vide car il n'y a rien à obtenir comme texture. Vous pouvez y faire face en utilisant (par exemple) :

# Wait until the frame has finished before getting the texture.
yield(VisualServer, "frame_post_draw")
# You can get the image after this.

Viewport Container

Si le Viewport est un enfant d'un ViewportContainer, il deviendra actif et affichera tout ce qu'il a à l'intérieur. La mise en page ressemble à ça :

../../_images/container.png

Le Viewport couvrira la zone de son parent ViewportContainer complètement si Stretch est réglé sur true dans ViewportContainer. Note : La taille du ViewportContainer ne peut pas être plus petite que la taille du Viewport.

Rendu

Du fait que le Viewport est une entrée dans une autre surface de rendu, il expose quelques propriétés de rendu qui peuvent être différentes des paramètres du projet. Le premier est MSAA ; vous pouvez choisir d'utiliser un niveau différent de MSAA pour chaque Viewport ; le comportement par défaut est DISABLED. Vous pouvez aussi définir le Viewport pour utiliser HDR, HDR est très utile pour quand vous voulez stocker des valeurs dans la texture qui sont en dehors de la plage 0.0 - 1.0.

Si vous savez comment le Viewport va être utilisé, vous pouvez régler son Utilisation sur 3D ou 2D. Godot va alors restreindre la façon dont le Viewport est dessiné en fonction de votre choix ; la valeur par défaut est 3D. Le mode d'utilisation 2D est légèrement plus rapide et utilise moins de mémoire que le mode 3D. C'est une bonne idée de mettre la propriété Usage de Viewport à 2D si votre viewport ne rend rien en 3D.

Note

Si vous devez rendre des ombres 3D dans le viewport, assurez-vous de définir la propriété Shadow Atlas Size du viewport à une valeur supérieure à 0, sinon les ombres ne seront pas rendues. Pour référence, les Paramètres de projet la définissent à 4096 par défaut.

Godot fournit également un moyen de personnaliser la façon dont tout est dessiné à l'intérieur des Viewports en utilisant "Debug Draw". Debug Draw vous permet de spécifier une des quatre options pour la façon dont le Viewport affichera les choses dessinées à l'intérieur. Debug Draw est désactivé par défaut.

../../_images/default_scene.png

Une scène dessinée avec Debug Draw désactivé

Les trois autres options sont Unshaded, Overdraw, et Wireframe. Unshaded, il dessine la scène sans utiliser les informations d'éclairage, de sorte que tous les objets apparaissent colorés de façon uniforme, de la couleur de leur albedo.

../../_images/unshaded.png

La même scène avec Debug Draw réglé sur Unshaded

Overdraw dessine les mailles semi-transparentes avec un mélange additif pour que vous puissiez voir comment les mailles se chevauchent.

../../_images/overdraw.png

La même scène avec Debug Draw réglé sur Overdraw

Enfin, Wireframe dessine la scène en utilisant uniquement les bords des triangles dans les mailles.

Note

Les effets du mode Wireframe ne sont visibles que dans l'éditeur, pas pendant l'exécution du projet.

Cible de rendu

Lors du rendu vers un Viewport, ce qui se trouve à l'intérieur ne sera pas visible dans l'éditeur de scènes. Pour afficher le contenu, vous devez dessiner le Viewport's ViewportTexture quelque part. Ceci peut être demandé par code en utilisant (par exemple) :

# This gives us the ViewportTexture.
var rtt = viewport.get_texture()
sprite.texture = rtt

Ou il peut être assigné dans l'éditeur en sélectionnant "New ViewportTexture"

../../_images/texturemenu.png

et ensuite en sélectionnant le Viewport que vous voulez utiliser.

../../_images/texturepath.png

A chaque image, la texture de Viewport est effacée avec la couleur d'éffacement par défaut (ou une couleur transparente si Transparent Bg est réglé sur true). Cela peut être changé en réglant Clear Mode sur Never ou Next Frame. Comme son nom l'indique, Never signifie que la texture ne sera jamais effacée, tandis que Next Frame effacera la texture sur l'image suivante et se mettra ensuite à Never.

Par défaut, le re-rendu du Viewport se produit quand la ViewportTexture du Viewport a été dessiné dans l'image. Si elle est visible, elle sera rendue ; sinon, elle ne le sera pas. Ce comportement peut être changé en rendu manuel (une fois), ou toujours rendu, qu'il soit visible ou non. Cette flexibilité permet aux utilisateurs de rendre une image une seule fois et d'utiliser ensuite la texture sans avoir à supporter le coût du rendu de chaque image.

Assurez-vous de consulter les démos de Viewport ! Dossier Viewport dans l'archive des démos disponible au téléchargement, ou https://github.com/godotengine/godot-demo-projects/tree/master/viewport