# 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
```