Lumières et ombres
Ce guide vous aidera à démarrer avec des lumières et des ombres simples dans TresJS.
Nous allons construire une scène simple avec trois maillages et un plan, mais seulement deux auront des ombres.
Configurer la scène (facultatif)
Nous importons tous les modules dont nous avons besoin, pour plus de commodité nous pouvons utiliser des centaines de contrôles d'orbite, voir ici pour savoir comment.
Plaçons quatre objets dans notre scène, l'un sera le plan qui recevra les ombres, deux d'entre eux projetteront des ombres et le dernier ne projettera aucune ombre.
Nous allons utiliser MeshToonMaterial. Tout simplement parce que l’on voit facilement le « soft overlay ».
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
import { OrbitControls } from '@tresjs/cientos'
</script>
<template>
<TresCanvas
clear-color="#111"
window-size
>
<OrbitControls />
<TresPerspectiveCamera :position="[5, 7.5, 7.5]" />
<TresMesh
:position="[-2, 2, 0]"
:rotation="[0, Math.PI, 0]"
>
<TresConeGeometry :args="[1, 1.5, 3]" />
<TresMeshToonMaterial color="#82DBC5" />
</TresMesh>
<TresMesh
:position="[0, 0, 0]"
>
<TresBoxGeometry :args="[1.5, 1.5, 1.5]" />
<TresMeshToonMaterial color="#4F4F4F" />
</TresMesh>
<TresMesh
:position="[2, -2, 0]"
>
<TresSphereGeometry />
<TresMeshToonMaterial color="#FBB03B" />
</TresMesh>
<TresMesh
:position="[0, -3, 0]"
:rotation="[-Math.PI / 2, 0, 0]"
>
<TresPlaneGeometry :args="[10, 10, 10, 10]" />
<TresMeshStandardMaterial color="#f7f7f7" />
</TresMesh>
</TresCanvas>
</template>
Lumières (explication)
Comme vous le savez, chaque instance dans ThreeJs est disponible dans TresJs, donc tous les types de lumières sont également disponibles, il suffit d'ajouter le préfixe Tres
pour les utiliser.
Mais toutes les lumières ne peuvent pas projeter des ombres, cette définition vient directement de ThreeJs et est logique. Par exemple, le but d'un ambientLight est d'éclairer tous les côtés de votre scène, cela n'a donc aucun sens de projeter des ombres. D'un autre côté, une DirectionalLight qui imite le soleil peut et doit générer des ombres.
Ombres (explication)
Il existe également de nombreux types d'ombres, par exemple une "ombre douce" est générée automatiquement lorsqu'un objet reçoit plus de lumière d'un côté, mais en bref, une "ombre par défaut ThreeJS" qui est dirigée vers une autre surface doit être projetée par un maillage et une autre maille doit le recevoir. Comme nous le voyons dans notre exemple, le Plan
reçoit une ombre mais ne la projette pas. Gardez à l’esprit que tous les matériaux ne peuvent pas projeter ou recevoir des ombres.
En interne, ThreeJS génère automatiquement un nouveau maillage avec un ShadowMaterial qui met à jour chaque image, donc si vous appliquez des animations, l'ombre s'anime également, mais c'est aussi pourquoi vous devez utiliser les ombres avec précaution car elles peuvent ralentir les performances.
WARNING
Une utilisation excessive des ombres de cette manière peut affecter les performances. Il existe cependant des moyens d’améliorer les performances. Pour plus d'informations, regardez cette vidéo
Activation des ombres
Nous pouvons décomposer cela en trois étapes :
Activer les ombres dans le moteur de rendu
//...
<template>
<TresCanvas
clear-color="#111"
shadows
window-size
/>
//...
</template>
Réglez la lumière pour projeter des ombres
Nous pouvons simplement ajouter le booléen cast-shadow
, Vue l'interprète comme un prop
avec la valeur true
.
La lumière ambiante ne génère ici aucun type d'ombre
//...
<template>
<TresAmbientLight :intensity="1" />
<TresDirectionalLight
cast-shadow
:position="[0, 2, 0]"
:intensity="1"
/>
//...
</template>
Définir des objets pour projeter ou recevoir des ombres
Semblable à l'étape précédente, nous définissons le maillage sur lequel nous voulons projeter l'ombre (notre sphère) avec la propriété cast-shadow
, et nous définissons l'objet pour qu'il reçoive l'ombre (notre plan) avec la propriété receive-shadow
.
//...
<template>
<TresMesh
cast-shadow
:position="[2, -2, 0]"
>
<TresSphereGeometry />
<TresMeshToonMaterial color="#FBB03B" />
</TresMesh>
<TresMesh
receive-shadow
:position="[0, -3, 0]"
:rotation="[-Math.PI / 2, 0, 0]"
>
<TresPlaneGeometry :args="[10, 10, 10, 10]" />
<TresMeshStandardMaterial color="#f7f7f7" />
</TresMesh>
//...
</template>
Nous avons maintenant toutes les étapes nécessaires pour ajouter des ombres à notre scène, et si nous appliquons ce que nous avons appris dans animations de base et ajoutons du mouvement à notre cube, vous verrez que l'ombre s'anime bien 🤩
<script setup>
import { shallowRef } from 'vue'
import { TresCanvas, useRenderLoop } from '@tresjs/core'
const boxRef = shallowRef()
const { onLoop } = useRenderLoop()
onLoop(() => {
if (boxRef.value) {
boxRef.value.rotation.y += 0.01
}
})
</script>
<template>
//...
<TresMesh
ref="boxRef"
cast-shadow
:position="[0, 0, 0]"
>
<TresBoxGeometry :args="[1.5, 1.5, 1.5]" />
<TresMeshToonMaterial color="#4F4F4F" />
</TresMesh>
//...
</template>
Notez que je n'ai intentionnellement pas appliqué cast-shadow
au Cone
afin qu'il ne projette aucune ombre