Skills Agentes

Threejs Shaders

Shaders en Three.js: GLSL, ShaderMaterial, uniforms y efectos propios. Úsalo al crear efectos visuales a medida, modificar vértices o escribir fragment shaders.

Estrellas
49.5k

en todo el repo

Actividad
36

0–100, la ruta de este skill

Actualizado
hace 4 meses

último commit aquí

Commits
0

últimos 90 días

Contexto
3.5k tok

47 tok en reposo

Paquete
1 archivo

14 KB

Instalar

Funciona con cualquier agente que lea SKILL.md

npx -y skills add calesthio/OpenMontage --skill threejs-shaders --agent claude-code

Se instala solo en este repositorio.

Qué hace

  • Explica la diferencia entre `ShaderMaterial` y `RawShaderMaterial`
  • Cubre uniforms, varyings y los patrones de shader más habituales
  • Enseña a extender los materiales integrados en lugar de escribir uno desde cero
  • Documenta funciones integradas de GLSL, includes de shader y shaders instanciados
  • Trae técnicas de depuración de shaders y consejos de rendimiento

Úsalo cuando

  • Crear efectos visuales propios
  • Modificar vértices o escribir fragment shaders
  • Extender un material integrado de Three.js

No lo uses cuando

    Qué lo activa

    Di cualquiera de estas frases y el agente debería cargar este skill.

    • Escríbeme un fragment shader para este efecto
    • Deforma los vértices de esta malla con un shader
    • Extiende el material estándar con GLSL propio
    • Mi shader no compila, ¿cómo lo depuro?

    SKILL.md

    En inglés

    Three.js Shaders

    Quick Start

    import * as THREE from "three";
    
    const material = new THREE.ShaderMaterial({
      uniforms: {
        time: { value: 0 },
        color: { value: new THREE.Color(0xff0000) },
      },
      vertexShader: `
        void main() {
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
      `,
      fragmentShader: `
        uniform vec3 color;
    
        void main() {
          gl_FragColor = vec4(color, 1.0);
        }
      `,
    });
    
    // Update in animation loop
    material.uniforms.time.value = clock.getElapsedTime();
    

    ShaderMaterial vs RawShaderMaterial

    ShaderMaterial

    Three.js provides built-in uniforms and attributes.

    const material = new THREE.ShaderMaterial({
      vertexShader: `
        // Built-in uniforms available:
        // uniform mat4 modelMatrix;
        // uniform mat4 modelViewMatrix;
        // uniform mat4 projectionMatrix;
        // uniform mat4 viewMatrix;
        // uniform mat3 normalMatrix;
        // uniform vec3 cameraPosition;
    
        // Built-in attributes available:
        // attribute vec3 position;
        // attribute vec3 normal;
        // attribute vec2 uv;
    
        void main() {
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
      `,
      fragmentShader: `
        void main() {
          gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
        }
      `,
    });
    

    RawShaderMaterial

    Full control - you define everything.

    const material = new THREE.RawShaderMaterial({
      uniforms: {
        projectionMatrix: { value: camera.projectionMatrix },
        modelViewMatrix: { value: new THREE.Matrix4() },
      },
      vertexShader: `
        precision highp float;
    
        attribute vec3 position;
        uniform mat4 projectionMatrix;
        uniform mat4 modelViewMatrix;
    
        void main() {
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
      `,
      fragmentShader: `
        precision highp float;
    
        void main() {
          gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
        }
      `,
    });
    

    Uniforms

    Uniform Types

    const material = new THREE.ShaderMaterial({
      uniforms: {
        // Numbers
        floatValue: { value: 1.5 },
        intValue: { value: 1 },
    
        // Vectors
        vec2Value: { value: new THREE.Vector2(1, 2) },
        vec3Value: { value: new THREE.Vector3(1, 2, 3) },
        vec4Value: { value: new THREE.Vector4(1, 2, 3, 4) },
    
        // Colors (converted to vec3)
        colorValue: { value: new THREE.Color(0xff0000) },
    
        // Matrices
        mat3Value: { value: new THREE.Matrix3() },
        mat4Value: { value: new THREE.Matrix4() },
    
        // Textures
        textureValue: { value: texture },
        cubeTextureValue: { value: cubeTexture },
    
        // Arrays
        floatArray: { value: [1.0, 2.0, 3.0] },
        vec3Array: {
          value: [new THREE.Vector3(1, 0, 0), new THREE.Vector3(0, 1, 0)],
        },
      },
    });
    

    GLSL Declarations

    // In shader
    uniform float floatValue;
    uniform int intValue;
    uniform vec2 vec2Value;
    uniform vec3 vec3Value;
    uniform vec3 colorValue;    // Color becomes vec3
    uniform vec4 vec4Value;
    uniform mat3 mat3Value;
    uniform mat4 mat4Value;
    uniform sampler2D textureValue;
    uniform samplerCube cubeTextureValue;
    uniform float floatArray[3];
    uniform vec3 vec3Array[2];
    

    Updating Uniforms

    // Direct assignment
    material.uniforms.time.value = clock.getElapsedTime();
    
    // Vector/Color updates
    material.uniforms.position.value.set(x, y, z);
    material.uniforms.color.value.setHSL(hue, 1, 0.5);
    
    // Matrix updates
    material.uniforms.matrix.value.copy(mesh.matrixWorld);
    

    Varyings

    Pass data from vertex to fragment shader.

    const material = new THREE.ShaderMaterial({
      vertexShader: `
        varying vec2 vUv;
        varying vec3 vNormal;
        varying vec3 vPosition;
    
        void main() {
          vUv = uv;
          vNormal = normalize(normalMatrix * normal);
          vPosition = (modelViewMatrix * vec4(position, 1.0)).xyz;
    
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
      `,
      fragmentShader: `
        varying vec2 vUv;
        varying vec3 vNormal;
        varying vec3 vPosition;
    
        void main() {
          // Use interpolated values
          gl_FragColor = vec4(vNormal * 0.5 + 0.5, 1.0);
        }
      `,
    });
    

    Common Shader Patterns

    Texture Sampling

    const material = new THREE.ShaderMaterial({
      uniforms: {
        map: { value: texture },
      },
      vertexShader: `
        varying vec2 vUv;
    
        void main() {
          vUv = uv;
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
      `,
      fragmentShader: `
        uniform sampler2D map;
        varying vec2 vUv;
    
        void main() {
          vec4 texColor = texture2D(map, vUv);
          gl_FragColor = texColor;
        }
      `,
    });
    

    Vertex Displacement

    const material = new THREE.ShaderMaterial({
      uniforms: {
        time: { value: 0 },
        amplitude: { value: 0.5 },
      },
      vertexShader: `
        uniform float time;
        uniform float amplitude;
    
        void main() {
          vec3 pos = position;
    
          // Wave displacement
          pos.z += sin(pos.x * 5.0 + time) * amplitude;
          pos.z += sin(pos.y * 5.0 + time) * amplitude;
    
          gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
        }
      `,
      fragmentShader: `
        void main() {
          gl_FragColor = vec4(0.5, 0.8, 1.0, 1.0);
        }
      `,
    });
    

    Fresnel Effect

    const material = new THREE.ShaderMaterial({
      vertexShader: `
        varying vec3 vNormal;
        varying vec3 vWorldPosition;
    
        void main() {
          vNormal = normalize(normalMatrix * normal);
          vWorldPosition = (modelMatrix * vec4(position, 1.0)).xyz;
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
      `,
      fragmentShader: `
        varying vec3 vNormal;
        varying vec3 vWorldPosition;
    
        void main() {
          // cameraPosition is auto-provided by ShaderMaterial
          vec3 viewDirection = normalize(cameraPosition - vWorldPosition);
          float fresnel = pow(1.0 - dot(viewDirection, vNormal), 3.0);
    
          vec3 baseColor = vec3(0.0, 0.0, 0.5);
          vec3 fresnelColor = vec3(0.5, 0.8, 1.0);
    
          gl_FragColor = vec4(mix(baseColor, fresnelColor, fresnel), 1.0);
        }
      `,
    });
    

    Noise-Based Effects

    // Simple noise function
    float random(vec2 st) {
      return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453);
    }
    
    // Value noise
    float noise(vec2 st) {
      vec2 i = floor(st);
      vec2 f = fract(st);
    
      float a = random(i);
      float b = random(i + vec2(1.0, 0.0));
      float c = random(i + vec2(0.0, 1.0));
      float d = random(i + vec2(1.0, 1.0));
    
      vec2 u = f * f * (3.0 - 2.0 * f);
    
      return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
    }
    
    // Usage
    float n = noise(vUv * 10.0 + time);
    

    Gradient

    // Linear gradient
    vec3 color = mix(colorA, colorB, vUv.y);
    
    // Radial gradient
    float dist = distance(vUv, vec2(0.5));
    vec3 color = mix(centerColor, edgeColor, dist * 2.0);
    
    // Smooth gradient with custom curve
    float t = smoothstep(0.0, 1.0, vUv.y);
    vec3 color = mix(colorA, colorB, t);
    

    Rim Lighting

    const material = new THREE.ShaderMaterial({
      vertexShader: `
        varying vec3 vNormal;
        varying vec3 vViewPosition;
    
        void main() {
          vNormal = normalize(normalMatrix * normal);
          vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
          vViewPosition = mvPosition.xyz;
          gl_Position = projectionMatrix * mvPosition;
        }
      `,
      fragmentShader: `
        varying vec3 vNormal;
        varying vec3 vViewPosition;
    
        void main() {
          vec3 viewDir = normalize(-vViewPosition);
          float rim = 1.0 - max(0.0, dot(viewDir, vNormal));
          rim = pow(rim, 4.0);
    
          vec3 baseColor = vec3(0.2, 0.2, 0.8);
          vec3 rimColor = vec3(1.0, 0.5, 0.0);
    
          gl_FragColor = vec4(baseColor + rimColor * rim, 1.0);
        }
      `,
    });
    

    Dissolve Effect

    uniform float progress;
    uniform sampler2D noiseMap;
    
    void main() {
      float noise = texture2D(noiseMap, vUv).r;
    
      if (noise < progress) {
        discard;
      }
    
      // Edge glow
      float edge = smoothstep(progress, progress + 0.1, noise);
      vec3 edgeColor = vec3(1.0, 0.5, 0.0);
      vec3 baseColor = vec3(0.5);
    
      gl_FragColor = vec4(mix(edgeColor, baseColor, edge), 1.0);
    }
    

    Extending Built-in Materials

    onBeforeCompile

    Modify existing material shaders.

    const material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
    
    material.onBeforeCompile = (shader) => {
      // Add custom uniform
      shader.uniforms.time = { value: 0 };
    
      // Store reference for updates
      material.userData.shader = shader;
    
      // Modify vertex shader
      shader.vertexShader = shader.vertexShader.replace(
        "#include <begin_vertex>",
        `
        #include <begin_vertex>
        transformed.y += sin(position.x * 10.0 + time) * 0.1;
        `,
      );
    
      // Add uniform declaration
      shader.vertexShader = "uniform float time;\n" + shader.vertexShader;
    };
    
    // Update in animation loop
    if (material.userData.shader) {
      material.userData.shader.uniforms.time.value = clock.getElapsedTime();
    }
    

    Common Injection Points

    // Vertex shader chunks
    "#include <begin_vertex>"; // After position is calculated
    "#include <project_vertex>"; // After gl_Position
    "#include <beginnormal_vertex>"; // Normal calculation start
    
    // Fragment shader chunks
    "#include <color_fragment>"; // After diffuse color
    "#include <output_fragment>"; // Final output
    "#include <fog_fragment>"; // After fog applied
    

    GLSL Built-in Functions

    Math Functions

    // Basic
    abs(x), sign(x), floor(x), ceil(x), fract(x)
    mod(x, y), min(x, y), max(x, y), clamp(x, min, max)
    mix(a, b, t), step(edge, x), smoothstep(edge0, edge1, x)
    
    // Trigonometry
    sin(x), cos(x), tan(x)
    asin(x), acos(x), atan(y, x), atan(x)
    radians(degrees), degrees(radians)
    
    // Exponential
    pow(x, y), exp(x), log(x), exp2(x), log2(x)
    sqrt(x), inversesqrt(x)
    

    Vector Functions

    // Length and distance
    length(v), distance(p0, p1), dot(x, y), cross(x, y)
    
    // Normalization
    normalize(v)
    
    // Reflection and refraction
    reflect(I, N), refract(I, N, eta)
    
    // Component-wise
    lessThan(x, y), lessThanEqual(x, y)
    greaterThan(x, y), greaterThanEqual(x, y)
    equal(x, y), notEqual(x, y)
    any(bvec), all(bvec)
    

    Texture Functions

    // GLSL 1.0 (default) - use texture2D/textureCube
    texture2D(sampler, coord)
    texture2D(sampler, coord, bias)
    textureCube(sampler, coord)
    
    // GLSL 3.0 (glslVersion: THREE.GLSL3) - use texture()
    // texture(sampler, coord) replaces texture2D/textureCube
    // Also use: out vec4 fragColor instead of gl_FragColor
    
    // Texture size (GLSL 1.30+)
    textureSize(sampler, lod)
    

    Common Material Properties

    const material = new THREE.ShaderMaterial({
      uniforms: {
        /* ... */
      },
      vertexShader: "/* ... */",
      fragmentShader: "/* ... */",
    
      // Rendering
      transparent: true,
      opacity: 1.0,
      side: THREE.DoubleSide,
      depthTest: true,
      depthWrite: true,
    
      // Blending
      blending: THREE.NormalBlending,
      // AdditiveBlending, SubtractiveBlending, MultiplyBlending
    
      // Wireframe
      wireframe: false,
      wireframeLinewidth: 1, // Note: >1 has no effect on most platforms (WebGL limitation)
    
      // Extensions
      extensions: {
        derivatives: true, // For fwidth, dFdx, dFdy
        fragDepth: true, // gl_FragDepth
        drawBuffers: true, // Multiple render targets
        shaderTextureLOD: true, // texture2DLod
      },
    
      // GLSL version
      glslVersion: THREE.GLSL3, // For WebGL2 features
    });
    

    Shader Includes

    Using Three.js Shader Chunks

    import { ShaderChunk } from "three";
    
    const fragmentShader = `
      ${ShaderChunk.common}
      ${ShaderChunk.packing}
    
      uniform sampler2D depthTexture;
      varying vec2 vUv;
    
      void main() {
        float depth = texture2D(depthTexture, vUv).r;
        float linearDepth = perspectiveDepthToViewZ(depth, 0.1, 1000.0);
        gl_FragColor = vec4(vec3(-linearDepth / 100.0), 1.0);
      }
    `;
    

    External Shader Files

    // With vite/webpack
    import vertexShader from "./shaders/vertex.glsl";
    import fragmentShader from "./shaders/fragment.glsl";
    
    const material = new THREE.ShaderMaterial({
      vertexShader,
      fragmentShader,
    });
    

    Instanced Shaders

    // Instanced attribute
    const offsets = new Float32Array(instanceCount * 3);
    // Fill offsets...
    geometry.setAttribute("offset", new THREE.InstancedBufferAttribute(offsets, 3));
    
    const material = new THREE.ShaderMaterial({
      vertexShader: `
        attribute vec3 offset;
    
        void main() {
          vec3 pos = position + offset;
          gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
        }
      `,
      fragmentShader: `
        void main() {
          gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
        }
      `,
    });
    

    Debugging Shaders

    // Check for compile errors
    material.onBeforeCompile = (shader) => {
      console.log("Vertex Shader:", shader.vertexShader);
      console.log("Fragment Shader:", shader.fragmentShader);
    };
    
    // Visual debugging
    fragmentShader: `
      void main() {
        // Debug UV
        gl_FragColor = vec4(vUv, 0.0, 1.0);
    
        // Debug normals
        gl_FragColor = vec4(vNormal * 0.5 + 0.5, 1.0);
    
        // Debug position
        gl_FragColor = vec4(vPosition * 0.1 + 0.5, 1.0);
      }
    `;
    
    // Check WebGL errors
    renderer.debug.checkShaderErrors = true;
    

    Performance Tips

    1. Minimize uniforms: Group related values into vectors
    2. Avoid conditionals: Use mix/step instead of if/else
    3. Precalculate: Move calculations to JS when possible
    4. Use textures: For complex functions, use lookup tables
    5. Limit overdraw: Avoid transparent objects when possible
    // Instead of:
    if (value > 0.5) {
      color = colorA;
    } else {
      color = colorB;
    }
    
    // Use:
    color = mix(colorB, colorA, step(0.5, value));
    

    See Also

    • threejs-materials - Built-in material types
    • threejs-postprocessing - Full-screen shader effects
    • threejs-textures - Texture sampling in shaders

    Reproducido de calesthio/OpenMontage bajo licencia AGPL-3.0. Leer esta página en markdown.

    Archivos

    1 archivo en el paquete. Solo se lee SKILL.md al activarse — las referencias se cargan si el skill decide que las necesita.

    Detalles

    Creador
    calesthio
    Categoría
    Diseño y UI
    Licencia
    AGPL-3.0
    Recursos incluidos
    Solo SKILL.md
    Código fuente
    Ver SKILL.md

    Etiquetas

    Más de calesthio/OpenMontage

    Este repo incluye 89 skills. Si instalas uno, normalmente ya tienes los demás.

    Comfyui

    49.5k

    Úsalo al trabajar con workflows de ComfyUI en OpenMontage: comfyui_image/video/music, workflows propios, selección de output_node, modelos que faltan, LoRAs, poca VRAM e importación de workflows de la comunidad.

    Costo de contexto al activarse
    1.9k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 9 días
    diseno ui

    Genera vídeo cinematográfico de 4-30 s con ByteDance Seedance 2.5 por fal.ai, Volcengine Ark, Runway o ComfyUI. Cubre el contrato de prompt 2.5, cortes duros, locks de continuidad y voz.

    Costo de contexto al activarse
    3.2k tok
    Tamaño del paquete
    2 archivos
    Última actualización
    hace 4 días
    diseno ui

    Genera narración expresiva y multilingüe con fish.audio (modelos S1 / S2) y reutiliza voces clonadas mediante reference_id.

    Costo de contexto al activarse
    1.4k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 9 días
    diseno ui

    Genera y edita conversacionalmente vídeos cortos con Google Gemini Omni Flash: itera con ediciones en lenguaje natural, clips de 3-10s a 720p con audio y texto en pantalla, e imágenes de referencia por etiquetas.

    Costo de contexto al activarse
    2.1k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 9 días
    Permisos
    diseno ui

    Genera vídeo con MiniMax H3 (Hailuo 3.0) por la API oficial v2, fal.ai, Runway, nodos partner de ComfyUI o pesos abiertos locales. Clips de 4-15s a 2K con animación de primer/último fotograma.

    Costo de contexto al activarse
    582 tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 9 días
    diseno ui

    Genera, reconstruye, inspecciona y enruta activos 3D de producción para mundos de OpenMontage con Atlas Cloud, fal.ai, catálogos con licencia y Blender.

    Costo de contexto al activarse
    1.2k tok
    Tamaño del paquete
    2 archivos
    Última actualización
    hace 9 días
    diseno ui

    Skills relacionados

    Genera, reconstruye, inspecciona y enruta activos 3D de producción para mundos de OpenMontage con Atlas Cloud, fal.ai, catálogos con licencia y Blender.

    Costo de contexto al activarse
    1.2k tok
    Tamaño del paquete
    2 archivos
    Última actualización
    hace 9 días
    diseno ui

    Acestep

    49.5k

    Generación musical con ACE-Step 1.5: música de fondo, pistas con voz, versiones y extracción de stems para producción de vídeo.

    Costo de contexto al activarse
    2.3k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    hace 4 meses
    diseno ui

    Genera vídeos con IA desde texto usando varias pasarelas — HeyGen, fal.ai, Kling y Gemini — con soporte de imagen a vídeo y comparación entre VEO, Kling, Sora, Runway, Seedance y MiniMax.

    Costo de contexto al activarse
    3k tok
    Tamaño del paquete
    1 archivo
    Última actualización
    el mes pasado
    diseno ui