# Cibles de rendu

Une cible de rendu dans three.js est essentiellement une texture sur laquelle vous pouvez effectuer un rendu. Une fois le rendu effectué, vous pouvez utiliser cette texture comme n'importe quelle autre texture.

Faisons un exemple simple. Nous allons commencer par un exemple tiré de l'article sur la responsivité.

Rendre sur une cible de rendu est presque exactement la même chose qu'un rendu normal. D'abord, nous créons un `WebGLRenderTarget`.

    const rtWidth = 512;
    const rtHeight = 512;
    const renderTarget = new THREE.WebGLRenderTarget(rtWidth, rtHeight);

Ensuite, nous avons besoin d'une `Camera` et d'une `Scene`

    const rtFov = 75;
    const rtAspect = rtWidth / rtHeight;
    const rtNear = 0.1;
    const rtFar = 5;
    const rtCamera = new THREE.PerspectiveCamera(rtFov, rtAspect, rtNear, rtFar);
    rtCamera.position.z = 2;

    const rtScene = new THREE.Scene();
    rtScene.background = new THREE.Color('red');

Notez que nous avons défini l'aspect sur celui de la cible de rendu, et non sur celui du canvas. Le bon aspect à utiliser dépend de ce pour quoi nous rendons. Dans ce cas, nous utiliserons la texture de la cible de rendu sur la face d'un cube. Puisque les faces de du cube sont carrées, nous voulons un aspect de 1.0.

Nous remplissons la scène. Dans ce cas, nous utilisons la lumière et les 3 cubes de l'article précédent.

    {
      const color = 0xFFFFFF;
      const intensity = 1;
      const light = new THREE.DirectionalLight(color, intensity);
      light.position.set(-1, 2, 4);
    *  rtScene.add(light);
    }

    const boxWidth = 1;
    const boxHeight = 1;
    const boxDepth = 1;
    const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth);

    function makeInstance(geometry, color, x) {
      const material = new THREE.MeshPhongMaterial({color});

      const cube = new THREE.Mesh(geometry, material);
    *  rtScene.add(cube);

      cube.position.x = x;

      return cube;
    }

    *const rtCubes = [
      makeInstance(geometry, 0x44aa88,  0),
      makeInstance(geometry, 0x8844aa, -2),
      makeInstance(geometry, 0xaa8844,  2),
    ];

La `Scene` et la `Camera` de l'article précédent sont toujours là. Nous les utiliserons pour rendre sur le canvas. Il nous suffit d'ajouter des éléments à rendre.

Ajoutons un cube qui utilise la texture de la cible de rendu.

    const material = new THREE.MeshPhongMaterial({
      map: renderTarget.texture,
    });
    const cube = new THREE.Mesh(geometry, material);
    scene.add(cube);

Maintenant, au moment du rendu, nous rendons d'abord la scène de la cible de rendu sur la cible de rendu.

    function render(time) {
      time *= 0.001;

      ...

      // faire tourner tous les cubes dans la scène de la cible de rendu
      rtCubes.forEach((cube, ndx) => {
        const speed = 1 + ndx * .1;
        const rot = time * speed;
        cube.rotation.x = rot;
        cube.rotation.y = rot;
      });

      // dessiner la scène de la cible de rendu sur la cible de rendu
      renderer.setRenderTarget(renderTarget);
      renderer.render(rtScene, rtCamera);
      renderer.setRenderTarget(null);

Ensuite, nous rendons la scène avec le cube unique qui utilise la texture de la cible de rendu sur le canvas.

      // faire tourner le cube dans la scène
      cube.rotation.x = time;
      cube.rotation.y = time * 1.1;

      // rendre la scène sur le canvas
      renderer.render(scene, camera);

And voilà

cliquez ici pour ouvrir dans une fenêtre séparée

Le cube est rouge car nous avons défini le `background` de la `rtScene` sur rouge, de sorte que la texture de la cible de rendu est effacée en rouge.

Les cibles de rendu sont utilisées pour toutes sortes de choses. Les ombres utilisent des cibles de rendu. La sélection (picking) peut utiliser une cible de rendu. Divers types d'effets de post-traitement nécessitent des cibles de rendu. Rendre un rétroviseur dans une voiture ou une vue en direct sur un moniteur à l'intérieur d'une scène 3D pourrait utiliser une cible de rendu.

Quelques notes sur l'utilisation de `WebGLRenderTarget`.

- Par défaut, `WebGLRenderTarget` crée 2 textures. Une texture de couleur et une texture de profondeur/stencil. Si vous n'avez pas besoin des textures de profondeur ou de stencil, vous pouvez demander à ne pas les créer en passant des options. Exemple :

        const rt = new THREE.WebGLRenderTarget(width, height, {
          depthBuffer: false,
          stencilBuffer: false,
        });

- Vous pourriez avoir besoin de changer la taille d'une cible de rendu

  Dans l'exemple ci-dessus, nous créons une cible de rendu de taille fixe, 512x512. Pour des choses comme le post-traitement, vous devez généralement créer une cible de rendu de la même taille que votre canvas. Dans notre code, cela signifierait que lorsque nous changeons la taille du canvas, nous mettons également à jour la taille de la cible de rendu et la caméra que nous utilisons lors du rendu sur la cible de rendu. Exemple :

      function render(time) {
        time *= 0.001;

        if (resizeRendererToDisplaySize(renderer)) {
          const canvas = renderer.domElement;
          camera.aspect = canvas.clientWidth / canvas.clientHeight;
          camera.updateProjectionMatrix();

      +    renderTarget.setSize(canvas.width, canvas.height);
      +    rtCamera.aspect = camera.aspect;
      +    rtCamera.updateProjectionMatrix();
      }