Skills Agentes

Threejs Postprocessing

Post-procesado en Three.js: EffectComposer, bloom, profundidad de campo y efectos de pantalla. Úsalo al añadir efectos visuales, gradación de color, desenfoque o brillo.

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.6k tok

43 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-postprocessing --agent claude-code

Se instala solo en este repositorio.

Qué hace

  • Monta `EffectComposer` para post-procesado en Three.js
  • Cubre los efectos habituales: bloom, profundidad de campo, desenfoque y gradación de color
  • Explica `ShaderPass` propio y cómo combinar varios efectos
  • Trata render a textura y renderizado multipaso
  • Incluye post-procesado con WebGPU a partir de r150 y el manejo del resize

Úsalo cuando

  • Añadir efectos visuales a una escena 3D
  • Aplicar gradación de color, desenfoque o brillo
  • Crear shaders propios de espacio de pantalla

No lo uses cuando

    Qué lo activa

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

    • Añade bloom a esta escena
    • Quiero profundidad de campo en el render
    • Crea un efecto de pantalla con shader propio
    • Combina varios efectos de post-procesado

    SKILL.md

    En inglés

    Three.js Post-Processing

    Quick Start

    import * as THREE from "three";
    import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";
    import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
    import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
    
    // Setup composer
    const composer = new EffectComposer(renderer);
    
    // Render scene
    const renderPass = new RenderPass(scene, camera);
    composer.addPass(renderPass);
    
    // Add bloom
    const bloomPass = new UnrealBloomPass(
      new THREE.Vector2(window.innerWidth, window.innerHeight),
      1.5, // strength
      0.4, // radius
      0.85, // threshold
    );
    composer.addPass(bloomPass);
    
    // Animation loop - use composer instead of renderer
    function animate() {
      requestAnimationFrame(animate);
      composer.render(); // NOT renderer.render()
    }
    

    EffectComposer Setup

    import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";
    import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
    
    const composer = new EffectComposer(renderer);
    
    // First pass: render scene
    const renderPass = new RenderPass(scene, camera);
    composer.addPass(renderPass);
    
    // Add more passes...
    composer.addPass(effectPass);
    
    // Last pass should render to screen
    effectPass.renderToScreen = true; // Default for last pass
    
    // Handle resize
    function onResize() {
      const width = window.innerWidth;
      const height = window.innerHeight;
    
      camera.aspect = width / height;
      camera.updateProjectionMatrix();
    
      renderer.setSize(width, height);
      composer.setSize(width, height);
    }
    

    Common Effects

    Bloom (Glow)

    import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
    
    const bloomPass = new UnrealBloomPass(
      new THREE.Vector2(window.innerWidth, window.innerHeight),
      1.5, // strength - intensity of glow
      0.4, // radius - spread of glow
      0.85, // threshold - brightness threshold
    );
    
    composer.addPass(bloomPass);
    
    // Adjust at runtime
    bloomPass.strength = 2.0;
    bloomPass.threshold = 0.5;
    bloomPass.radius = 0.8;
    

    Selective Bloom

    Apply bloom only to specific objects.

    import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
    import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";
    
    // Layer setup
    const BLOOM_LAYER = 1;
    const bloomLayer = new THREE.Layers();
    bloomLayer.set(BLOOM_LAYER);
    
    // Mark objects to bloom
    glowingMesh.layers.enable(BLOOM_LAYER);
    
    // Dark material for non-blooming objects
    const darkMaterial = new THREE.MeshBasicMaterial({ color: 0x000000 });
    const materials = {};
    
    function darkenNonBloomed(obj) {
      if (obj.isMesh && !bloomLayer.test(obj.layers)) {
        materials[obj.uuid] = obj.material;
        obj.material = darkMaterial;
      }
    }
    
    function restoreMaterial(obj) {
      if (materials[obj.uuid]) {
        obj.material = materials[obj.uuid];
        delete materials[obj.uuid];
      }
    }
    
    // Custom render loop
    function render() {
      // Render bloom pass
      scene.traverse(darkenNonBloomed);
      composer.render();
      scene.traverse(restoreMaterial);
    
      // Render final scene over bloom
      renderer.render(scene, camera);
    }
    

    FXAA (Anti-Aliasing)

    import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";
    import { FXAAShader } from "three/addons/shaders/FXAAShader.js";
    
    const fxaaPass = new ShaderPass(FXAAShader);
    fxaaPass.material.uniforms["resolution"].value.set(
      1 / window.innerWidth,
      1 / window.innerHeight,
    );
    
    composer.addPass(fxaaPass);
    
    // Update on resize
    function onResize() {
      fxaaPass.material.uniforms["resolution"].value.set(
        1 / window.innerWidth,
        1 / window.innerHeight,
      );
    }
    

    SMAA (Better Anti-Aliasing)

    import { SMAAPass } from "three/addons/postprocessing/SMAAPass.js";
    
    const smaaPass = new SMAAPass(
      window.innerWidth * renderer.getPixelRatio(),
      window.innerHeight * renderer.getPixelRatio(),
    );
    
    composer.addPass(smaaPass);
    

    SSAO (Ambient Occlusion)

    import { SSAOPass } from "three/addons/postprocessing/SSAOPass.js";
    
    const ssaoPass = new SSAOPass(
      scene,
      camera,
      window.innerWidth,
      window.innerHeight,
    );
    ssaoPass.kernelRadius = 16;
    ssaoPass.minDistance = 0.005;
    ssaoPass.maxDistance = 0.1;
    
    composer.addPass(ssaoPass);
    
    // Output modes
    ssaoPass.output = SSAOPass.OUTPUT.Default;
    // SSAOPass.OUTPUT.Default - Final composited output
    // SSAOPass.OUTPUT.SSAO - Just the AO
    // SSAOPass.OUTPUT.Blur - Blurred AO
    // SSAOPass.OUTPUT.Depth - Depth buffer
    // SSAOPass.OUTPUT.Normal - Normal buffer
    

    Depth of Field (DOF)

    import { BokehPass } from "three/addons/postprocessing/BokehPass.js";
    
    const bokehPass = new BokehPass(scene, camera, {
      focus: 10.0, // Focus distance
      aperture: 0.025, // Aperture (smaller = more DOF)
      maxblur: 0.01, // Max blur amount
    });
    
    composer.addPass(bokehPass);
    
    // Update focus dynamically
    bokehPass.uniforms["focus"].value = distanceToTarget;
    

    Film Grain

    import { FilmPass } from "three/addons/postprocessing/FilmPass.js";
    
    const filmPass = new FilmPass(
      0.35, // noise intensity
      0.5, // scanline intensity
      648, // scanline count
      false, // grayscale
    );
    
    composer.addPass(filmPass);
    

    Vignette

    import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";
    import { VignetteShader } from "three/addons/shaders/VignetteShader.js";
    
    const vignettePass = new ShaderPass(VignetteShader);
    vignettePass.uniforms["offset"].value = 1.0; // Vignette size
    vignettePass.uniforms["darkness"].value = 1.0; // Vignette intensity
    
    composer.addPass(vignettePass);
    

    Color Correction

    import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";
    import { ColorCorrectionShader } from "three/addons/shaders/ColorCorrectionShader.js";
    
    const colorPass = new ShaderPass(ColorCorrectionShader);
    colorPass.uniforms["powRGB"].value = new THREE.Vector3(1.2, 1.2, 1.2); // Power
    colorPass.uniforms["mulRGB"].value = new THREE.Vector3(1.0, 1.0, 1.0); // Multiply
    
    composer.addPass(colorPass);
    

    Gamma Correction

    import { GammaCorrectionShader } from "three/addons/shaders/GammaCorrectionShader.js";
    
    const gammaPass = new ShaderPass(GammaCorrectionShader);
    composer.addPass(gammaPass);
    

    Pixelation

    import { RenderPixelatedPass } from "three/addons/postprocessing/RenderPixelatedPass.js";
    
    const pixelPass = new RenderPixelatedPass(6, scene, camera); // 6 = pixel size
    
    composer.addPass(pixelPass);
    

    Glitch Effect

    import { GlitchPass } from "three/addons/postprocessing/GlitchPass.js";
    
    const glitchPass = new GlitchPass();
    glitchPass.goWild = false; // Continuous glitching
    
    composer.addPass(glitchPass);
    

    Halftone

    import { HalftonePass } from "three/addons/postprocessing/HalftonePass.js";
    
    const halftonePass = new HalftonePass(window.innerWidth, window.innerHeight, {
      shape: 1, // 1 = dot, 2 = ellipse, 3 = line, 4 = square
      radius: 4, // Dot size
      rotateR: Math.PI / 12,
      rotateB: (Math.PI / 12) * 2,
      rotateG: (Math.PI / 12) * 3,
      scatter: 0,
      blending: 1,
      blendingMode: 1,
      greyscale: false,
    });
    
    composer.addPass(halftonePass);
    

    Outline

    import { OutlinePass } from "three/addons/postprocessing/OutlinePass.js";
    
    const outlinePass = new OutlinePass(
      new THREE.Vector2(window.innerWidth, window.innerHeight),
      scene,
      camera,
    );
    
    outlinePass.edgeStrength = 3;
    outlinePass.edgeGlow = 0;
    outlinePass.edgeThickness = 1;
    outlinePass.pulsePeriod = 0;
    outlinePass.visibleEdgeColor.set(0xffffff);
    outlinePass.hiddenEdgeColor.set(0x190a05);
    
    // Select objects to outline
    outlinePass.selectedObjects = [mesh1, mesh2];
    
    composer.addPass(outlinePass);
    

    Custom ShaderPass

    Create your own post-processing effects.

    import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";
    
    const CustomShader = {
      uniforms: {
        tDiffuse: { value: null }, // Required: input texture
        time: { value: 0 },
        intensity: { value: 1.0 },
      },
      vertexShader: `
        varying vec2 vUv;
    
        void main() {
          vUv = uv;
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
      `,
      fragmentShader: `
        uniform sampler2D tDiffuse;
        uniform float time;
        uniform float intensity;
        varying vec2 vUv;
    
        void main() {
          vec2 uv = vUv;
    
          // Wave distortion
          uv.x += sin(uv.y * 10.0 + time) * 0.01 * intensity;
    
          vec4 color = texture2D(tDiffuse, uv);
          gl_FragColor = color;
        }
      `,
    };
    
    const customPass = new ShaderPass(CustomShader);
    composer.addPass(customPass);
    
    // Update in animation loop
    customPass.uniforms.time.value = clock.getElapsedTime();
    

    Invert Colors Shader

    const InvertShader = {
      uniforms: {
        tDiffuse: { value: null },
      },
      vertexShader: `
        varying vec2 vUv;
        void main() {
          vUv = uv;
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
      `,
      fragmentShader: `
        uniform sampler2D tDiffuse;
        varying vec2 vUv;
    
        void main() {
          vec4 color = texture2D(tDiffuse, vUv);
          gl_FragColor = vec4(1.0 - color.rgb, color.a);
        }
      `,
    };
    

    Chromatic Aberration

    const ChromaticAberrationShader = {
      uniforms: {
        tDiffuse: { value: null },
        amount: { value: 0.005 },
      },
      vertexShader: `
        varying vec2 vUv;
        void main() {
          vUv = uv;
          gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
        }
      `,
      fragmentShader: `
        uniform sampler2D tDiffuse;
        uniform float amount;
        varying vec2 vUv;
    
        void main() {
          vec2 dir = vUv - 0.5;
          float dist = length(dir);
    
          float r = texture2D(tDiffuse, vUv - dir * amount * dist).r;
          float g = texture2D(tDiffuse, vUv).g;
          float b = texture2D(tDiffuse, vUv + dir * amount * dist).b;
    
          gl_FragColor = vec4(r, g, b, 1.0);
        }
      `,
    };
    

    Combining Multiple Effects

    import { EffectComposer } from "three/addons/postprocessing/EffectComposer.js";
    import { RenderPass } from "three/addons/postprocessing/RenderPass.js";
    import { UnrealBloomPass } from "three/addons/postprocessing/UnrealBloomPass.js";
    import { ShaderPass } from "three/addons/postprocessing/ShaderPass.js";
    import { FXAAShader } from "three/addons/shaders/FXAAShader.js";
    import { VignetteShader } from "three/addons/shaders/VignetteShader.js";
    import { GammaCorrectionShader } from "three/addons/shaders/GammaCorrectionShader.js";
    
    const composer = new EffectComposer(renderer);
    
    // 1. Render scene
    composer.addPass(new RenderPass(scene, camera));
    
    // 2. Bloom
    const bloomPass = new UnrealBloomPass(
      new THREE.Vector2(window.innerWidth, window.innerHeight),
      0.5,
      0.4,
      0.85,
    );
    composer.addPass(bloomPass);
    
    // 3. Vignette
    const vignettePass = new ShaderPass(VignetteShader);
    vignettePass.uniforms["offset"].value = 0.95;
    vignettePass.uniforms["darkness"].value = 1.0;
    composer.addPass(vignettePass);
    
    // 4. Gamma correction
    composer.addPass(new ShaderPass(GammaCorrectionShader));
    
    // 5. Anti-aliasing (always last before output)
    const fxaaPass = new ShaderPass(FXAAShader);
    fxaaPass.uniforms["resolution"].value.set(
      1 / window.innerWidth,
      1 / window.innerHeight,
    );
    composer.addPass(fxaaPass);
    

    Render to Texture

    // Create render target
    const renderTarget = new THREE.WebGLRenderTarget(512, 512);
    
    // Render scene to target
    renderer.setRenderTarget(renderTarget);
    renderer.render(scene, camera);
    renderer.setRenderTarget(null);
    
    // Use texture
    const texture = renderTarget.texture;
    otherMaterial.map = texture;
    

    Multi-Pass Rendering

    // Multiple composers for different scenes/layers
    const bgComposer = new EffectComposer(renderer);
    bgComposer.addPass(new RenderPass(bgScene, camera));
    
    const fgComposer = new EffectComposer(renderer);
    fgComposer.addPass(new RenderPass(fgScene, camera));
    fgComposer.addPass(bloomPass);
    
    // Combine in render loop
    function animate() {
      // Render background without clearing
      renderer.autoClear = false;
      renderer.clear();
    
      bgComposer.render();
    
      // Render foreground over it
      renderer.clearDepth();
      fgComposer.render();
    }
    

    WebGPU Post-Processing (Three.js r150+)

    import { postProcessing } from "three/addons/nodes/Nodes.js";
    import { pass, bloom, dof } from "three/addons/nodes/Nodes.js";
    
    // Using node-based system
    const scenePass = pass(scene, camera);
    const bloomNode = bloom(scenePass, 0.5, 0.4, 0.85);
    
    const postProcessing = new THREE.PostProcessing(renderer);
    postProcessing.outputNode = bloomNode;
    
    // Render
    function animate() {
      postProcessing.render();
    }
    

    Performance Tips

    1. Limit passes: Each pass adds a full-screen render
    2. Lower resolution: Use smaller render targets for blur passes
    3. Disable unused effects: Toggle passes on/off
    4. Use FXAA over MSAA: Less expensive anti-aliasing
    5. Profile with DevTools: Check GPU usage
    // Disable pass
    bloomPass.enabled = false;
    
    // Reduce bloom resolution
    const bloomPass = new UnrealBloomPass(
      new THREE.Vector2(window.innerWidth / 2, window.innerHeight / 2),
      strength,
      radius,
      threshold,
    );
    
    // Only apply effects in high-performance scenarios
    const isMobile = /iPhone|iPad|Android/i.test(navigator.userAgent);
    if (!isMobile) {
      composer.addPass(expensivePass);
    }
    

    Handle Resize

    function onWindowResize() {
      const width = window.innerWidth;
      const height = window.innerHeight;
      const pixelRatio = renderer.getPixelRatio();
    
      camera.aspect = width / height;
      camera.updateProjectionMatrix();
    
      renderer.setSize(width, height);
      composer.setSize(width, height);
    
      // Update pass-specific resolutions
      if (fxaaPass) {
        fxaaPass.material.uniforms["resolution"].value.set(
          1 / (width * pixelRatio),
          1 / (height * pixelRatio),
        );
      }
    
      if (bloomPass) {
        bloomPass.resolution.set(width, height);
      }
    }
    
    window.addEventListener("resize", onWindowResize);
    

    See Also

    • threejs-shaders - Custom shader development
    • threejs-textures - Render targets
    • threejs-fundamentals - Renderer setup

    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