# Shaders Esta guía te ayudará a comenzar con los shaders en TresJS. Construiremos una escena simple con un blob. Luego alo animaremos para distorsionarlo suavemente. ::: warning _Es necesario tener conocimientos básicos sobre cómo funcionan los shaders_ ::: ## Configurando la escena (opcional) Importamos todos los módulos que necesitamos. Para mayor comodidad, podemos usar los orbit-controls de cientos. [Consulta aquí para ver cómo](/examples/orbit-controls). Ahora, coloquemos nuestra cámara en la posición `[11,11,11]`. Por último, para ayudarnos con la ubicación, agreguemos un plano simple, rotado en el eje X, con una medida de `[10, 10]` unidades. ```vue ``` ## ShaderMaterial Como sabes, cada instancia en [ThreeJs](https://threejs.org/) está disponible en **TresJs**, por lo que también podemos usar el `ShaderMaterial`, solo necesitamos agregar el prefijo `Tres` para utilizarlo. Para nuestro blob, podríamos usar una simple `SphereGeometry` agregando algunos `widthSegments` y `heightSegments` para crear un efecto suave, y colocar nuestro blob 4 unidades en el eje Y positivo. ```vue ``` El `ShaderMaterial` acepta propiedades especiales, como `uniforms`, `vertexShader` y `fragmentShader`, por lo que podemos crearlo en nuestra sección de script y hacer la conexión con nuestra instancia. Para este ejemplo, nuestros uniforms se ven así: ```ts import { Vector2 } from 'three' //... const uniforms = { uTime: { value: 0 }, uAmplitude: { value: new Vector2(0.1, 0.1) }, uFrequency: { value: new Vector2(20, 5) }, } //.. ``` Nuestro fragment shader se ve así: ```ts //... const fragmentShader = ` precision mediump float; varying vec2 vUv; void main() { gl_FragColor = vec4(1.0, vUv.y, 0.5, 1.0); } ` //.. ``` Y finalmente nuestro `vertexShader`: ```ts 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; } ` //.. ``` ## Animando el blob Similar a lo que aprendimos en el ejemplo de [Animaciones básicas](/examples/basic-animations), comenzamos haciendo referencia a nuestro blob utilizando [Template Ref](https://vuejs.org/guide/essentials/template-refs.html) ```vue ``` Una vez que hayamos hecho eso, podemos usar el callback `onLoop` para animar nuestro `uTime`. ```ts import { TresCanvas, useRenderLoop } from '@tresjs/core' //... const { onLoop } = useRenderLoop() onLoop(({ elapsed }) => { if (blobRef.value) { blobRef.value.material.uniforms.uTime.value = elapsed } }) //... ``` Y eso es todo, tenemos nuestro shader básico funcionando sin problemas. ## Usando GLSL vite-plugin (opcional) _Este paso es completamente opcional y está fuera del alcance del equipo de **TresJs**_ Definir nuestro shader en línea no siempre es la mejor idea, pero si estás utilizando [vite](https://vitejs.dev/), puedes colocar tus archivos `GLSL` en un archivo diferente utilizando el [vite-plugin-glsl](https://www.npmjs.com/package/vite-plugin-glsl) (consulta el enlace para obtener la documentación oficial). Y podrías tener una estructura similar a esta: ``` ├── src/ │ ├── myTresJsComponent.vue │ ├── shaders/ │ ├── vertexShader.glsl │ ├── fragmentShader.glsl ```