Shaders
Ce guide vous aidera à démarrer avec les shaders dans TresJS.
Nous allons construire une scène simple avec un blob. Ensuite, nous l'animerons pour le déformer doucement.
WARNING
Il est nécessaire d’avoir des connaissances de base sur le fonctionnement des shaders
Configurer la scène (facultatif)
Nous importons tous les modules dont nous avons besoin. Pour plus de commodité, nous pouvons utiliser les orbit-controls de cientos. Voir ici comment.
Mettons notre caméra en position [11,11,11]
.
Enfin, pour nous aider avec le placement, ajoutons un plan simple, tourné sur l'axe X, avec une mesure de [10, 10]
unités.
<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="[11, 11, 11]" />
<TresMesh :rotation="[-Math.PI / 2, 0, 0]">
<TresPlaneGeometry :args="[10, 10]" />
<TresMeshBasicMaterial color="#444" />
</TresMesh>
</TresCanvas>
</template>
ShaderMaterial
Comme vous le savez, chaque instance dans ThreeJs est disponible dans TresJs, nous pouvons donc également utiliser le ShaderMaterial
, il suffit d'ajouter le préfixe Tres
pour l'utiliser.
Pour notre blob, nous pourrions utiliser un simple SphereGeometry
en ajoutant des widthSegments
et heightSegments
pour créer un effet fluide et positionner notre blob 4 unités sur l'axe Y positif.
<TresMesh :position="[0, 4, 0]">
<TresSphereGeometry :args="[2, 32, 32]" />
<TresShaderMaterial />
</TresMesh>
Le ShaderMaterial
accepte des propriétés spéciales, telles que uniforms
, vertexShader
et fragmentShader
, afin que nous puissions le créer dans notre section de script et établir la connexion à notre instance.
Pour cet exemple, nos uniformes ressemblent à ceci :
import { Vector2 } from 'three'
// ...
const uniforms = {
uTime: { value: 0 },
uAmplitude: { value: new Vector2(0.1, 0.1) },
uFrequency: { value: new Vector2(20, 5) },
}
// ..
Notre fragment shader ressemble à ceci :
// ...
const fragmentShader = `
precision mediump float;
varying vec2 vUv;
void main() {
gl_FragColor = vec4(1.0, vUv.y, 0.5, 1.0);
}
`
// ..
Et enfin notre vertexShader
:
const vertexShader = `
uniform vec2 uAmplitude;
uniform vec2 uFrequency;
uniform float uTime;
varying vec2 vUv;
void main() {
vec4 modelPosition = modelMatrix * vec4(position, 1.0);
modelPosition.y += sin(modelPosition.x * uFrequency.x - uTime) * uAmplitude.x;
modelPosition.x += cos(modelPosition.y * uFrequency.y - uTime) * uAmplitude.y;
vec4 viewPosition = viewMatrix * modelPosition;
gl_Position = projectionMatrix * viewPosition;
vUv = uv;
}
`
// ..
Animer le blob
Semblable à ce que nous avons appris dans l'exemple des Animations de bases, Nous commençons par référencer notre blob en utilisant Template Ref
<script setup lang="ts">
import { shallowRef } from 'vue'
import { TresCanvas } from '@tresjs/core'
import { OrbitControls } from '@tresjs/cientos'
const blobRef = shallowRef(null)
// ...
</script>
<template>
<TresCanvas
clear-color="#111"
window-size
>
<OrbitControls />
<TresPerspectiveCamera :position="[11, 11, 11]" />
<TresMesh
ref="blobRef"
:position="[0, 4, 0]"
>
<TresSphereGeometry :args="[2, 32, 32]" />
<TresShaderMaterial />
</TresMesh>
</TresCanvas>
</template>
Une fois que nous avons fait cela, nous pouvons utiliser le rappel onLoop
pour animer notre uTime
.
import { TresCanvas, useRenderLoop } from '@tresjs/core'
// ...
const { onLoop } = useRenderLoop()
onLoop(({ elapsed }) => {
if (blobRef.value) {
blobRef.value.material.uniforms.uTime.value = elapsed
}
})
// ...
Et voilà, notre shader de base fonctionne correctement.
Avec GLSL vite-plugin (optionel)
Cette étape est totalement facultative et hors du cadre de l'équipe TresJs.
Définir notre shader en ligne n'est pas toujours la meilleure idée, mais si vous utilisez vite, vous pouvez mettre vos fichiers GLSL
dans un fichier différent en utilisant le vite-plugin-glsl. (voir lien pour la documentation officielle)
Et vous devriez avoir une structure similaire à celle-ci :
├── src/
│ ├── myTresJsComponent.vue
│ ├── shaders/
│ ├── vertexShader.glsl
│ ├── fragmentShader.glsl