shaders
Docs y Tools
- Shadertoy Final shader
- Shadertoy
- Inigo Quilez website
- Color palette article — IQ
- 2D Signed Distance Functions
- Cosine gradient generator
- Graphtoy
- GLSL Reference & Swizzling
- The Book of Shaders
- Shadertoy Unofficial
- Inigo Quilez’s channel
- The Art of Code’s channel
Videos
- An introduction to Shader Art Coding
- Vectores y componentes
- Canvas y píxeles
- Aspect ratio
- GLSL y funciones SDF
- Dynamic rendering
- Transformaciones UV
- Añadir iteraciones
- Introduction to shaders: Learn the basics!
Nuevas Secciones Recomendadas
Conceptos Base de Shaders (GLSL)
- Tipos de shaders:
- Vertex Shader
- Fragment Shader
- Pipeline:
- Entrada de atributos → Vertex → Rasterizado → Fragment
- Tipos de datos:
float,vec2,vec3,vec4- Matrices (
mat2,mat3,mat4) - Swizzling (
color.rg,uv.xy, etc.)
- Uniforms:
- Tiempo (
u_time) - Resolución (
u_resolution) - Mouse (
u_mouse) - Texturas (
sampler2D)
- Tiempo (
- Funciones comunes:
mix(),step(),smoothstep()dot(),length(),normalize()fract(),mod()
Patrones Visuales Comunes
- Raymarching básico
- Signed Distance Functions (SDF)
- Composición con
min,max - Operaciones booleanas
- Composición con
- Gradientes:
- Cosine palettes (IQ)
- Interpolaciones
- Noise:
- Value noise
- Perlin noise
- Simplex noise
- Domain warping
- Efectos:
- Glitch
- Distorsión UV
- Efectos de onda
- Fog y volumétricos simples
Uso en Three.js
- ShaderMaterial
- Uniforms dinámicos con
clock.getElapsedTime() - Pasar texturas (
THREE.Texture) - Modificar posición de vértices
- Render targets para efectos de post-procesado
Uso en p5.js (WebGL mode)
createShader()shader(shaderVar)- Pasar uniforms con
shader.setUniform() - Manejo de framebuffers simples con
createGraphics(WEBGL)
Herramientas Extra para Estudiar Shaders
- Visualizadores de SDF
- Sketches en The Book of Shaders Editor
- Plantillas para Three.js + GLSL
- Shader graph como referencia conceptual (aunque no GLSL puro)
Ejemplos de Bloques de Código
Fragment shader base
#ifdef GL_ES
precision mediump float;
#endif
uniform float u_time;
uniform vec2 u_resolution;
void main() {
vec2 uv = gl_FragCoord.xy / u_resolution.xy;
vec3 color = vec3(uv.x, uv.y, abs(sin(u_time)));
gl_FragColor = vec4(color, 1.0);
}
`
Vertex shader mínimo
attribute vec3 position;
void main() {
gl_Position = vec4(position, 1.0);
}
Shaders: Guía Avanzada y Arquitectura Mental
1. Cómo Pensar en Shaders
Los shaders requieren una mentalidad distinta a la programación tradicional. En lugar de “ordenar tareas secuenciales”, trabajas describiendo lo que debe ocurrir en cada píxel o vértice, de forma paralela y sin dependencias directas.
Principios mentales clave:
- Pensar en funciones puras, sin estado.
- Visualizar valores: todo es un número, incluso color, luz o movimiento.
- Entender que los outputs son instantáneos por frame, no persistentes.
- Diseñar transformaciones como “etapas matemáticas” encadenadas.
2. Anatomía Práctica de un Shader
Un shader eficaz suele componerse de pequeños bloques reutilizables:
- Normalización inicial
Transformaciones de coordenadas, espacio local o pantalla. - Construcción de patrones
Repetición, offset, mirroring, modulación. - Función principal
La operación visual: mezcla, forma, textura, deformación, luz. - Correcciones finales
Contraste, gamma, suavizado, dithering. - Salida
Clamping y composición final del color.
Estructurar tus shaders así te permitirá escalar sin caos.
3. Diseño de Shaders Orientado a Sistemas
En proyectos grandes conviene modular:
- Módulos matemáticos: rotación, ruido, smoothing, mezclas.
- Módulos de color: paletas, curvas, contraste local.
- Módulos geométricos: repeticiones, tiling, offsets, folding.
- Módulos visuales: iluminación, ambient occlusion creativo, materiales simples.
- Módulos temporales: curvas de animación, osciladores, delays.
La idea es construir un “lenguaje personal” de funciones GLSL reutilizables.
4. Cómo Diseñar un Shader desde Cero
Guía práctica para producir arte generativo o efectos visuales:
- Define un gesto visual principal
Patrón base, textura procedural, forma, luz o movimiento. - Establece un ritmo o dinámica
Velocidades, repeticiones, ciclos o perturbaciones. - Expande dimensionalmente
Agregar profundidad, loops, simetrías, distorsiones. - Introduce variación controlada
Ruido, offsets temporales, desplazamientos. - Refina
Quita pasos innecesarios, optimiza, ajusta contraste. - Añade detalle
Bordes suaves, halos, pequeñas imperfecciones. - Cierra composición
Color final, balance visual, transición entre estados.
5. Guía Profesional de Debugging
Depurar shaders puede ser complejo. Técnicas útiles:
- Visual debugging
Mostrar valores numéricos mediante colores (ej., valor → gradiente). - Aislar etapas
Comentar fragmentos y mostrar solo la parte problemática. - Debug temporal
Detener animaciones fijando el tiempo para analizar un frame. - Debug de rangos
Clampear señales para evitar artefactos invisibles. - Reemplazo por ruido
Si una función falla, probar con ruido simple para validar flujo.
6. Performance Real en GPU
A diferencia del CPU, optimizar en GPU significa:
- Minimizar ramificaciones (
ifpesados). - Reducir bucles largos (especialmente raymarching excesivo).
- Evitar cálculos repetidos: usa variables temporales.
- Preferir operaciones vectoriales a muchas escalares.
- Simplificar distancias y funciones cuando sea posible.
- Precalcular constantes matemáticas.
Regla general: menos operaciones por píxel = más FPS.
7. Estilos Visuales Avanzados
Ideas para explorar nuevas direcciones estéticas:
- Pattern Folding
Repeticiones que se pliegan sobre sí mismas. - Domain Distortion
Modificar UV antes de dibujar formas. - Fake Volumetrics
Capas semi-transparentes simulando profundidad. - Color Fields
Grandes masas de color basadas en funciones suaves. - Estructuras fractales suaves
Iteraciones controladas sin raymarching pesado. - Motion Texture
Usar el tiempo como si fuera un eje adicional.
8. Organización de un Proyecto Shader
Para mantener claridad:
- Tener un archivo con todas las constantes (pi, 2pi, escalas).
- Separar funciones por categorías.
- Crear un documento de pruebas visuales.
- Mantener un registro de versiones (evolución del shader).
- Anotar decisiones visuales, no solo técnicas.
9. Workflow Artístico
No todo es matemática; también es proceso creativo:
- Experimentación rápida (probar pequeñas variaciones).
- Bocetos visuales (mini shaders de 15–20 líneas).
- Captura de resultados interesantes.
- Selección de una dirección estética.
- Refinado de la composición.
- Documentación del estado visual final.
10. Cómo Crear un Estilo Propio
- Escribe tus propias funciones, incluso si ya existen.
- Reutiliza errores visuales como estéticas intencionales.
- Mantén una librería personal.
- Crea restricciones: paletas limitadas, deformaciones específicas.
- Experimenta con imperfecciones numéricas y aliasing estético.
11. Expansión con Web y Entornos Creativos
Sin repetir los frameworks anteriores, una perspectiva diferente:
- Integrar shaders con herramientas de prototipado visual.
- Usar buffers multipaso para efectos encadenados.
- Crear pipelines de postproducción personalizados.
- Integrar audio → parámetros del shader (FFT, picos, energía).
- Sincronizar shaders con animaciones, timelines y playback.
12. Ejercicios Guiados (sin repetir los del otro documento)
- Rediseñar un shader sin trigonometría.
- Crear un shader compuesto de solo 3 funciones.
- Generar un degradado no lineal basado en curvas bézier.
- Simular rugosidad usando micro-variaciones UV.
- Crear un patrón orgánico sin ruido procedural.
- Diseñar una animación basada solo en mod, fract y step.
13. Lista de Verificación antes de Finalizar un Shader
- ¿La composición es equilibrada?
- ¿El color tiene intención estética?
- ¿Hay redundancias matemáticas?
- ¿El código está estructurado en etapas?
- ¿La animación tiene ritmo?
- ¿El shader reacciona bien a diferentes resoluciones?
- ¿El rendimiento es adecuado?
Shader patterns: catálogo de estructuras visuales
Catálogo sin repetir nada de las notas anteriores.
Esta nota está pensada como una biblioteca conceptual de patrones visuales para shaders, describiendo cómo funcionan, qué producen y cómo se combinan.
1. Patrones Fundamentales
▸ Domain Distortion
Transformar las coordenadas antes de dibujar cualquier forma.
Crea efectos líquidos, deformaciones, turbulencias o distorsiones suaves.
Usos:
- Fundidos orgánicos
- Paisajes abstractos
- Efectos de calor o refracción
▸ Pattern Mirroring
Duplicar el dominio aplicando simetrías controladas.
Produce imágenes fracturadas, estilizadas o simétricas.
Variantes:
- Espejo horizontal
- Espejo radial
- Espejo segmentado en ángulos
▸ Repetición Modular (Tiling)
Repetir un patrón en mosaico, usando mod o coordenadas envueltas.
Aplicaciones:
- Texturas procedurales
- Fondos infinitos
- Patrón base para ruido complejo
▸ Subdivisión Fractal Suave
Sin raymarching. Se basa en repetir operaciones suaves como fract, smoothstep, rotaciones y escalas.
Resultados:
- Red de líneas repetidas
- Estructuras pseudo-organizadas
- Formas fractales “planas” sin cálculo volumétrico
2. Patrones Basados en Geometría
▸ SDF Blending
Mezcla progresiva entre formas usando operadores suaves.
Produce shapes fluidas y mutables.
Composiciones típicas:
- Soft Union / Soft Subtract
- Combinación con curvas temporales
- Interpolación entre siluetas
▸ Edge Emphasis
Resaltar bordes alterando la distancia cercana a la superficie.
Usos:
- Efectos estilo cómic
- Bordes luminosos
- Contornos animados
▸ Radial Structures
Patrones formados desde un centro: ángulos, radios, espirales.
Variantes:
- Segmentación angular
- Barrido circular
- Espiral logarítmica
▸ Polar Modulation
Distorsionar la parte angular o radial de las coordenadas polares.
Efectos:
- Ondas circulares
- Flujos centrífugos
- Patrones mandálicos orgánicos
3. Patrones Temporales y de Movimiento
▸ Motion Phase Cycling
Dividir la animación en fases y alternar patrones según fase.
Aplicaciones:
- Ciclos de pulsación
- Transiciones entre motivos
- Animación narrativa generativa
▸ Osciladores Múltiples
Combinar varias señales periódicas (seno, triángulo, ruido) para obtener movimiento rico.
Resultados:
- Efectos rítmicos
- Interferencias
- Vibración estética controlada
▸ Temporal Offset Fields
Aplicar delays espaciales: cada región del shader “entra en la animación” en diferente momento.
Usos:
- Ondas en cadena
- Deformación cinemática
- Efectos de despliegue o aparición gradual
4. Patrones Basados en Color
▸ Mapas Multidimensionales de Color
El color se calcula usando varias dimensiones simultáneamente: distancia, ángulo, tiempo, ruido.
Efectos:
- Nebulosas
- Paletas dinámicas
- Gradientes imposibles
▸ Color Quantization Estético
Reducir rango de color para crear estilos:
- pixel art
- posterización suave
- estética analógica
La clave es elegir puntos de quiebre no uniformes.
▸ Color by Structure
El color representa alguna estructura geométrica: distancia, curvatura, velocidad del patrón.
Aplicaciones:
- Mapas científicos estilizados
- Iluminación falsa
- Luces de contorno reactivas
5. Patrones Basados en Ruido (sin repetir SDFs ni ruido clásico)
▸ Noise Folding
Plegar valores de ruido dentro de sí mismos mediante operaciones periódicas.
Resultados:
- Texturas orgánicas ruidosas
- Materiales suaves
- Caos controlado
▸ Ring Noise
Ruido aplicado sobre el ángulo o el radio, no sobre UV.
Resultados:
- Bandas concéntricas vivas
- Texturas psicodélicas
- Ondas radiales con vibración
▸ Time-Sliced Noise
El ruido cambia solo en algunos intervalos discretos.
Efectos:
- Flicker artístico
- Saltos estilizados
- Efecto de animación “cuadro a cuadro”
6. Patrones Estructurales Avanzados
▸ Pattern Morphing
Interpolar entre dos patrones distintos (no solo formas), por ejemplo:
- grid → hex pattern
- espiral → campo radial
- patches orgánicos → líneas minimalistas
Crea animaciones profundas.
▸ Pattern Deconstruction
Dividir un patrón en componentes visuales (bordes, regiones sólidas, zonas de transición).
Usos:
- efectos abstractos
- transición entre escenas
- composición artística compleja
▸ Modulated Grids
Una cuadrícula clásica, pero distorsionada por un campo: ondas, ruido, dominios torcidos.
Efectos:
- glitch suave
- distorsión digital
- mapas conceptuales animados
7. Patrones Compositivos (combinación de varios)
▸ Layers Interactivos
Capas de patrones que reaccionan entre sí según distancia, color o tiempo.
Ideas:
- capas que ondulan al tocarse
- capas que “repelen” o “atraen”
- capas que intercambian atributos
▸ Pattern Masking
Un patrón controla la visibilidad de otro.
Ejemplo: un ruido decide qué partes del patrón principal son visibles.
Aplicaciones:
- máscaras animadas
- revelados
- transiciones complejas
▸ Structural Chaining
Cada patrón alimenta el siguiente:
dominio → distorsión → forma → color → distorsión final.
Crea shaders con narrativa visual.
8. Patrones para Efectos Visuales
▸ Fake Depth Layers
Simular parallax y volumen con capas desplazadas.
Usos:
- niebla procedural
- atmósferas
- nubes pseudo-volumétricas
▸ Distance-Based Flicker
La intensidad depende de la distancia a una zona activa.
Efectos:
- luces danzantes
- parpadeos reactivos
- ritmos visuales
9. Patrones para Iluminación Creativa
▸ Gradient Lighting
Iluminación por gradiente en vez de luz puntual.
Estilo:
- muy artístico
- no realista
- útil para efectos suaves
▸ Edge Glow Driven by Geometry
El brillo depende del ángulo o posición, simulando luz interna.
Aplicación:
Iluminación “mágica” o “energética”.
▸ Pseudo AO 2D
Ocultación ambiental falsa basada en distancia o contraste local.
Usos:
- sombreado abstracto
- atmósferas densas
- paisajes en 2D simulando volumen
10. Patrones Narrativos (para VFX o arte generativo)
▸ Morphing Escalado
Un patrón se “acerca” o “aleja” como si fuese cámara, pero deformado.
▸ Transiciones Meta
Pasar de un patrón a otro usando propiedades extrañas:
distancia, ruido, ciclos temporales.
▸ Aperture Patterns
Aperturas y cierres circulares, hexagonales o libres, usados como transiciones cinematográficas.
11. Cómo Combinar Patrones (guía rápida)
- Un dominio distorsionado aplicado a un grid genera texturas ricas.
- Un ruido plegado sobre coordenadas polares produce nubes abstractas.
- Un SDF blend modulando colores crea formas vivas.
- Una simetría radial con motion cycling genera animaciones hipnóticas.
- Un patrón base más un masking produce transiciones complejas.
12. Checklist de Exploración Creativa
- ¿Qué ocurre si alteras UV antes de todo?
- ¿Qué pasa si usas tiempo modulado en lugar de tiempo continuo?
- ¿Y si el color depende de un atributo geométrico inesperado?
- ¿Puedes hacer que dos patrones “dialoguen” entre sí?
- ¿Y si introduces una simetría parcial, no total?
¿Quieres otra nota complementaria?
Puedo seguir la serie con:
- “Raymarching avanzado y arquitectura modular”
- “Catálogo de texturas procedurales 2D”
- “Librería personal de funciones GLSL”
- “Diseño visual con shaders: composición, ritmo y estética”
Sólo dime cuál quieres.
Fundamentos de Shaders: Evolución e Implementación
Esta nota explica los fundamentos de los shaders, su evolución histórica y cómo se implementan en sistemas y motores gráficos modernos.
Estructurada para Obsidian como referencia central de GameDev y gráficos por computadora.
1. ¿Qué es un Shader?
Un shader es un programa que se ejecuta en la GPU para controlar cómo se procesan los datos gráficos.
Se centra en dos principales fases:
- Vertex Shader: define la posición, orientación y atributos de cada vértice.
- Fragment Shader (Pixel Shader): determina el color y la apariencia de cada fragmento/píxel.
Opcionalmente, se agregan:
- Geometry Shaders: crean nuevas primitivas desde vértices existentes.
- Compute Shaders: permiten cálculos generales en GPU, fuera del pipeline gráfico clásico.
2. Fundamentos Matemáticos y Conceptuales
▸ Transformaciones
- Matrices 4x4 para translation, rotation, scale.
- Coordinadas homogéneas y normalización.
- Model, View y Projection matrices.
▸ Interpolación y Varying
- Datos pasados del vertex shader al fragment shader se interpolan automáticamente.
- Permite gradientes, normales suavizadas y efectos derivados de posiciones.
▸ Funciones básicas
- Operadores vectoriales (
dot,cross,normalize) - Funciones de suavizado (
smoothstep,mix) - Proceduralidad: ruido, fractales, SDF
▸ Pensamiento paralelo
- Cada fragmento se procesa independientemente, obligando a pensar en funciones puras y sin dependencias externas.
3. Evolución Histórica
▸ Fixed-Function Pipeline
- Antes de 2003, la GPU tenía un pipeline fijo: transformaciones y iluminación predefinidas.
- Limitaciones: efectos restringidos, poca flexibilidad.
▸ Programmable Pipeline (Shader-Based)
- Introducción de GLSL, HLSL, Cg.
- Vertex y fragment shaders personalizables.
- Mayor control de iluminación, texturas, efectos visuales y animaciones.
▸ Compute Shaders y Física GPU
- Procesamiento paralelo masivo.
- Simulación de fluidos, partículas, físicas complejas.
- Integración en motores para efectos de postprocesado y generativos.
▸ Motores modernos
- Abstracciones visuales (Shader Graph, Material Editor).
- Modularización de funciones, reutilización y nodos paramétricos.
- Integración con audio, IA y animaciones generativas.
4. Implementación en Motores Gráficos
▸ Unity
- Shader Graph para nodos visuales.
- HLSL o ShaderLab para shaders escritos a mano.
- Integración con URP/HDRP pipelines.
- Funciones reutilizables: librerías, includes, multi-pass shaders.
▸ Unreal Engine
- Material Editor: nodo visual y gráficos de shaders.
- Custom HLSL para efectos avanzados.
- Postprocesado, iluminación avanzada y SDF en tiempo real.
▸ Godot
- Godot Shader Language (GDScript-like).
- Sintaxis similar a GLSL simplificada.
- Soporte para 2D, 3D y canvas shaders.
- Integración con nodos y animaciones del motor.
▸ WebGL / Three.js
- GLSL directamente en WebGL.
- Materiales y efectos visuales encapsulados en Three.js o Babylon.js.
- Compatible con buffers múltiples, postprocessing y efectos generativos.
5. Pipeline de Implementación General
- Definir objetivo visual: color, iluminación, efecto.
- Elegir fase de shader: vertex, fragment, compute, geometry.
- Diseñar transformaciones y funciones básicas.
- Probar en un entorno controlado: resolución baja, variables uniformes.
- Optimizar para GPU: evitar bucles pesados, ramificaciones, operaciones innecesarias.
- Integrar en motor: nodos, materiales, scripts de control.
- Documentar y modularizar: funciones reutilizables, librerías y presets.
6. Buenas Prácticas
- Modularizar funciones y operadores matemáticos.
- Mantener shaders puros y determinísticos.
- Evitar dependencias externas o globales dentro del shader.
- Usar constantes y uniformes para parámetros variables.
- Documentar la relación entre coordenadas, color y tiempo.
- Mantener pruebas visuales y snapshots de cada versión.
7. Ejemplos de Uso Común
- Efectos de agua: deformaciones, ondas, reflejos.
- Materiales metalizados y orgánicos: normal mapping, fresnel, SDF.
- Partículas: animaciones generativas con compute shaders.
- Postprocesado: bloom, color grading, distorsiones.
- Procedural content: texturas, paisajes, patrones.
8. Alternativas y Evolución Tecnológica
- GLSL (OpenGL/WebGL)
- HLSL (DirectX / Unity / Unreal)
- Cg (histórico, NVIDIA)
- Metal Shading Language (Apple)
- WGSL (WebGPU)
- SPIR-V (Vulkan, compilación intermedia)
Tendencias modernas:
- Nodos visuales como estándar en motores.
- Integración con IA y generación procedural.
- Computación general en GPU.
- Shaders para XR/VR y entornos interactivos.
9. Recursos y Documentación
- LearnOpenGL: Advanced GLSL
- The Book of Shaders
- Unity Shader Graph Documentation
- Unreal Engine Material Editor
- Godot Shaders
- WebGPU & WGSL
- Metal Shading Language Guide
——
Librería personal de funciones GLSL
Esta nota sirve como referencia rápida para crear tu propia librería de funciones GLSL, organizada, reutilizable y escalable para proyectos de shaders.
No repite patrones, ejemplos ni contenidos de notas previas.
1. Funciones Matemáticas Básicas
▸ Operaciones comunes
float square(float x) { return x*x; }
float cube(float x) { return x*x*x; }
float clamp01(float x) { return clamp(x, 0.0, 1.0); }
`
▸ Map / Remap
float map(float value, float min1, float max1, float min2, float max2) {
return min2 + (value - min1) * (max2 - min2) / (max1 - min1);
}
▸ Smoothstep avanzado
float smoothstep_range(float edge0, float edge1, float x) {
float t = clamp((x - edge0)/(edge1 - edge0), 0.0, 1.0);
return t*t*(3.0 - 2.0*t);
}
2. Transformaciones de Coordenadas
▸ Rotación 2D
vec2 rotate2D(vec2 uv, float angle) {
float c = cos(angle);
float s = sin(angle);
return vec2(c*uv.x - s*uv.y, s*uv.x + c*uv.y);
}
▸ Escalado / Translación
vec2 translate(vec2 uv, vec2 offset) { return uv + offset; }
vec2 scale(vec2 uv, vec2 factor) { return uv * factor; }
▸ Polar Coordinates
vec2 cartesianToPolar(vec2 uv) {
float r = length(uv);
float theta = atan(uv.y, uv.x);
return vec2(r, theta);
}
3. Funciones de Ruido y Variación
▸ Pseudo-random básico
float random(vec2 st) {
return fract(sin(dot(st.xy, vec2(12.9898,78.233))) * 43758.5453123);
}
▸ Noise básico 2D
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;
}
▸ Domain warp
vec2 warp(vec2 uv, float factor) {
return uv + vec2(noise(uv*factor), noise(uv*factor+10.0));
}
4. Funciones de Color
▸ Paleta por interpolación
vec3 palette(float t, vec3 a, vec3 b, vec3 c, vec3 d) {
return a + b*cos(6.28318*(c*t + d));
}
▸ Lerp de colores
vec3 lerpColor(vec3 col1, vec3 col2, float t) {
return mix(col1, col2, t);
}
▸ Ajuste de saturación
vec3 adjustSaturation(vec3 color, float sat) {
float gray = dot(color, vec3(0.299, 0.587, 0.114));
return mix(vec3(gray), color, sat);
}
5. Formas y Geometría
▸ SDF básica
float sdCircle(vec2 p, float r) { return length(p) - r; }
float sdBox(vec2 p, vec2 b) { vec2 d = abs(p) - b; return length(max(d,0.0)) + min(max(d.x,d.y),0.0); }
▸ Operadores SDF
float opUnion(float d1, float d2) { return min(d1,d2); }
float opIntersection(float d1, float d2) { return max(d1,d2); }
float opSubtraction(float d1, float d2) { return max(d1,-d2); }
▸ Smooth blending
float opSmoothUnion(float d1, float d2, float k) {
float h = clamp(0.5 + 0.5*(d2 - d1)/k, 0.0, 1.0);
return mix(d2, d1, h) - k*h*(1.0 - h);
}
6. Funciones de Animación
▸ Osciladores
float oscillate(float t, float freq, float amp) { return sin(t*freq)*amp; }
float triangle(float t) { return abs(fract(t) - 0.5)*2.0; }
float pulse(float t, float width) { return step(mod(t,1.0), width); }
▸ Phase shift
float phaseShift(float value, float phase) { return fract(value + phase); }
▸ Lerp animado
float animateLerp(float a, float b, float t) { return mix(a,b,smoothstep(0.0,1.0,t)); }
7. Funciones de Utilidad
▸ Remap UV a [-1,1]
vec2 uvCentered(vec2 uv) { return uv*2.0 - 1.0; }
▸ Normalización de valores
float normalize01(float value, float minVal, float maxVal) {
return clamp((value - minVal)/(maxVal - minVal),0.0,1.0);
}
▸ Rotación de RGB
vec3 rotateRGB(vec3 color) { return vec3(color.g, color.b, color.r); }
8. Organización de la Librería
- Categorizar funciones por Matemáticas, Color, Geometría, Ruido, Animación.
- Mantener constantes globales:
PI,TAU,EPSILON. - Comentar cada función con uso, parámetros y rango esperado.
- Documentar combinaciones frecuentes:
warp + palette,SDF blend + oscillate. - Guardar snippets para reutilización rápida en proyectos threejs o p5js.
9. Tips de Creación y Expansión
- Crear tu propia función de ruido modulado para patrones únicos.
- Reutilizar operadores SDF para nuevas formas complejas.
- Mantener funciones puras y pequeñas: combinarlas es más fácil que hacer funciones gigantes.
- Documentar ejemplos visuales junto con cada función.
- Experimentar con animaciones cortas para validar comportamiento antes de integrarlas.
GLS y Fundamentos: Conceptos y Alternativas
Nota introductoria y de referencia sobre GLSL (OpenGL Shading Language), sus fundamentos y alternativas modernas en la industria del desarrollo de gráficos y juegos.
Pensada para Obsidian, estructurada y ampliable.
1. ¿Qué es GLSL?
GLSL (OpenGL Shading Language) es un lenguaje de programación de shaders diseñado para trabajar sobre la GPU, usado principalmente con OpenGL y WebGL.
Permite controlar:
- Vertex Shaders: transformaciones de vértices, matrices, deformaciones.
- Fragment Shaders: color de píxeles, iluminación, efectos visuales.
- Compute Shaders (GL 4.3+): procesamiento paralelo general, simulaciones físicas, efectos avanzados.
2. Fundamentos de GLSL
▸ Tipos de Datos
- Escalares:
float,int,bool - Vectores:
vec2,vec3,vec4 - Matrices:
mat2,mat3,mat4 - Samplers / Texturas:
sampler2D,samplerCube
▸ Variables
- uniform: constantes por frame (tiempo, resolución, mouse)
- attribute / in: entrada de vértices
- out: salida del shader
- varying / out: interpolación de datos del vertex al fragment shader
▸ Operadores y Funciones Clave
- Operadores aritméticos básicos:
+ - * / - Funciones matemáticas:
sin,cos,tan,pow,mod,fract - Funciones vectoriales:
dot,cross,length,normalize - Mezcla de valores:
mix,clamp,smoothstep
3. Pipeline Gráfico Básico
- Vertex Processing: cada vértice pasa por el vertex shader.
- Primitive Assembly: vértices forman triángulos, líneas o puntos.
- Rasterization: conversión de primitivas a fragmentos.
- Fragment Processing: cada fragmento pasa por el fragment shader.
- Output: color final al framebuffer.
4. Principios de Diseño de Shaders
- Mantener funciones puras sin estado global mutable.
- Separar transformaciones geométricas y procesamiento visual.
- Optimizar para ejecución masiva (GPU): minimizar ramificaciones (
if), loops pesados, operaciones costosas. - Modularizar: crear librerías de funciones matemáticas, de color y de forma.
5. Alternativas a GLSL
Dependiendo de la plataforma o motor, existen lenguajes y frameworks que pueden sustituir o complementar GLSL:
▸ HLSL (High-Level Shading Language)
- Lenguaje de shaders de Microsoft, usado en DirectX.
- Sintaxis similar a GLSL pero con diferencias en tipos y funciones.
- Compatible con motores como Unity (ShaderLab).
▸ Cg (C for Graphics)
- Desarrollado por NVIDIA.
- Sintaxis similar a HLSL, usado históricamente en juegos.
- Actualmente menos usado debido a la adopción de HLSL y GLSL.
▸ Metal Shading Language (MSL)
- Lenguaje de Apple para GPUs de iOS y macOS.
- Similar a C++ moderno.
- Usado en frameworks como MetalKit.
▸ SPIR-V
- Lenguaje intermedio usado por Vulkan.
- Permite escribir shaders en GLSL/HLSL y compilarlos a SPIR-V.
- Optimización y portabilidad multiplataforma.
▸ WGSL (WebGPU Shading Language)
- Nuevo lenguaje para WebGPU, futuro estándar web.
- Más seguro y predecible que GLSL en navegadores modernos.
6. Frameworks y Motores con Abstracción de Shaders
- Unity Shader Graph: nodo visual para crear shaders sin escribir código.
- Unreal Engine Material Editor: sistema visual basado en nodos.
- Godot Shader Language (GDScript + Shader): estilo GLSL simplificado.
- Three.js / Babylon.js: permiten usar GLSL directamente o wrappers de alto nivel.
7. Recomendaciones de Aprendizaje
- Comprender la pipeline gráfica antes de escribir shaders.
- Practicar GLSL básico: colores, gradientes, transformaciones de vértices.
- Experimentar con fragment shaders: efectos visuales simples.
- Explorar alternativas según plataforma: HLSL para DirectX, WGSL para WebGPU.
- Mantener un repositorio de funciones reutilizables: matemáticas, color, geometría.
8. Recursos y Documentación
- OpenGL Shading Language 4.60 Specification
- The Book of Shaders
- LearnOpenGL: Shaders
- WebGPU & WGSL
- Metal Shading Language Guide
9. Conceptos Clave de Comparación
| Lenguaje | Plataforma | Sintaxis | Características | |———–|————|———-|—————-| | GLSL | OpenGL/WebGL | C-like | GPU-first, portable, estándar web | | HLSL | DirectX | C-like | Integración en Unity/DirectX | | Cg | OpenGL/DirectX | C-like | Históricamente NVIDIA, legado | | MSL | Metal (Apple) | C++-like | Optimizado para GPUs Apple | | WGSL | WebGPU | C-like | Seguro, moderno, estándar web futuro | | SPIR-V | Vulkan | Intermedio | Compilación binaria, multiplataforma |
——
Shader Art 2025: Guía Completa
Guía práctica y conceptual para crear arte generativo con shaders en 2025. Incluye tendencias, técnicas, herramientas, workflows y ejemplos de implementación en tiempo real.
1. Introducción a Shader Art
- Shader Art es el uso de shaders (programas que corren en GPU) como medio artístico.
- Permite crear efectos visuales complejos y generativos: patrones, animaciones, deformaciones, iluminación procedural.
- En 2025, la tendencia combina IA, WebGPU/WGSL, compute shaders y motores gráficos para generar arte interactivo y de alta performance.
2. Principios Fundamentales
▸ Matemática y Computación Paralela
- Operaciones vectoriales y matriciales:
dot,cross,normalize, transformaciones de vértices. - Interpolación y blending de colores.
- Proceduralidad: ruido, SDF (Signed Distance Functions), fractales.
▸ Pensamiento en GPU
- Cada fragmento se procesa de forma independiente.
- Evitar dependencias globales y bucles pesados.
- Funciones puras y modularidad: reutilizar bloques de código.
▸ Pipeline Visual
- Vertex Shader: deformaciones, animaciones de vértices, movimiento procedural.
- Fragment Shader: color, iluminación, gradientes, efectos de postprocesado.
- Compute Shader: simulaciones de partículas, fluidos o generación procedural avanzada.
3. Tendencias 2025
- Integración IA + Shaders:
Uso de modelos de IA para generar texturas, colores y patrones en tiempo real sobre shaders. - WebGPU/WGSL:
Migración de shaders web desde WebGL a WebGPU para mayor seguridad, rendimiento y nuevas APIs. - Shaders Interactivos:
Arte en tiempo real controlado por usuario: mouse, gestos, audio o data externa. - Shaders Generativos:
Proceduralidad avanzada: fractales, geometría algorítmica y animaciones dinámicas. - Shaders híbridos:
Combinación de algoritmos matemáticos con texturas generadas por IA.
4. Herramientas Clave
▸ Plataformas
- Shader Academy: retos interactivos y cursos prácticos.
- Shadertoy 2025: colaboración global, inspiración y testing de fragment shaders.
- ISF (Interactive Shader Format): performance y VJ setups.
▸ Lenguajes y APIs
- GLSL: estándar para OpenGL/WebGL.
- WGSL: lenguaje principal de WebGPU.
- HLSL / ShaderGraph: motores Unity/Unreal.
- Compute Shaders: simulaciones complejas y efectos generativos.
▸ IA + Shader
- ShaderGPT: generación automática de shaders a partir de prompts.
- Neural shading pipelines: redes neuronales para relighting y efectos dinámicos.
5. Estilos y Técnicas
▸ Estética Procedural
- Fractales, ruido, patrones geométricos.
- Deformaciones en tiempo real para objetos o fondos.
▸ VJ / Arte Interactivo
- Visuales reactivos a música o entrada de usuario.
- Controles de parámetros en tiempo real.
▸ Combinación IA + Shader
- Texturas generadas por IA mezcladas con shaders matemáticos.
- Relighting y efectos de iluminación dinámica basada en IA.
▸ Flat y Low Poly
- Minimalismo y geometría simple.
- Colores sólidos, gradientes simples y rim lighting estilizado.
6. Workflow Recomendado
- Definir objetivo artístico: estilo, interacción, performance.
- Elegir tipo de shader: vertex, fragment, compute.
- Prototipar en herramientas interactivas: Shadertoy, Shader Academy.
- Integrar IA si aplica: generar texturas o patrones base.
- Optimizar: reducir loops innecesarios, usar vertex data y uniform variables.
- Exportar y reutilizar: modularizar funciones para pipelines repetibles.
7. Ejemplos de Implementación
▸ Fragment Shader Generativo
- Patrones ondulados y coloridos controlados por el tiempo y posición UV.
▸ Vertex Shader Interactivo
- Deformación de geometría con ruido procedural y feedback del mouse.
▸ Compute Shader Procedural
- Simulación de partículas y fluidos para efectos generativos en tiempo real.
8. Recursos y Referencias 2025
- Shader Academy
- Shadertoy
- WGSL & WebGPU
- The Book of Shaders
- ShaderGPT
- Interactive Shader Format (ISF)
9. Buenas Prácticas
- Mantener shaders modulares y reutilizables.
- Priorizar vertex shader para deformaciones y fragment shader para color.
- Optimizar para tiempo real en web o motores 3D.
- Documentar parámetros y efectos para interactividad y colaboración artística.
- Explorar combinaciones IA + procedural para resultados innovadores.
Raymarching: Fundamentos y Funcionamiento
Guía de referencia sobre raymarching, un método de renderizado basado en trazado de rayos sobre funciones implícitas.
Explicación conceptual, técnica, ventajas y usos en arte generativo y gráficos 3D.
1. ¿Qué es Raymarching?
- Raymarching es un algoritmo de renderizado que simula rayos que recorren el espacio 3D hasta encontrar una superficie.
- A diferencia del ray tracing clásico, no requiere geometría explícita; se basa en Signed Distance Functions (SDF) que describen superficies de forma implícita.
- Muy usado en arte generativo, demos y gráficos low poly o abstractos.
2. Conceptos Clave
▸ Ray
- Representado por un origen y una dirección:
ray(t) = origin + t * direction - Se recorre el espacio iterativamente hasta colisionar con una superficie.
▸ Signed Distance Functions (SDF)
- Funciones que devuelven la distancia mínima al objeto más cercano.
- Valor positivo fuera de la superficie, negativo dentro y cero en la superficie.
- Ejemplo: esfera centrada en
ccon radior:
float sphereSDF(vec3 p, vec3 c, float r){
return length(p - c) - r;
}
`
▸ Marching
- Se avanza por el rayo en pasos de tamaño igual a la distancia mínima devuelta por el SDF.
- Reduce iteraciones y evita penetrar objetos.
3. Pipeline Básico de Raymarching
- Definir cámara y rayos por píxel.
-
Para cada rayo:
- Evaluar la SDF del escenario en la posición actual.
- Mover el punto a lo largo del rayo la distancia indicada por SDF.
- Repetir hasta alcanzar un umbral mínimo o máximo número de pasos.
-
Una vez colisionado:
- Calcular normales: aproximando gradientes de SDF.
- Aplicar iluminación: Phong, Blinn-Phong o shading estilizado.
- Renderizar color final del píxel.
4. Cálculo de Normales
- Necesario para iluminación y sombreado:
vec3 estimateNormal(vec3 p){
float eps = 0.001;
return normalize(vec3(
sceneSDF(p + vec3(eps,0,0)) - sceneSDF(p - vec3(eps,0,0)),
sceneSDF(p + vec3(0,eps,0)) - sceneSDF(p - vec3(0,eps,0)),
sceneSDF(p + vec3(0,0,eps)) - sceneSDF(p - vec3(0,0,eps))
));
}
5. Iluminación y Sombras
- Iluminación directa: calcular dot product entre normal y dirección de luz.
- Soft shadows: marchar rayos hacia luz y acumular atenuación.
- Ambient occlusion: aproximar oclusión evaluando proximidad a otras superficies.
- Reflections / Refractions: raymarching secundario desde punto de colisión.
6. Ventajas de Raymarching
- Permite crear geometría compleja sin mallas explícitas.
- Ideal para efectos procedurales y abstractos.
- Facilita animaciones de deformaciones y morphing de formas.
- Compatible con arte generativo, fractales y SDF-based landscapes.
7. Limitaciones
- Costoso computacionalmente: cada píxel puede requerir muchas iteraciones.
- Difícil lograr alta performance en tiempo real sin optimización.
- Puede presentar artefactos si los pasos son demasiado grandes o SDF complejas.
8. Optimización
- Step size dinámico: usar SDF para determinar distancia a la superficie.
- Bounding volumes: descartar áreas donde no hay objetos.
- Raymarching en GPU: aprovechar paralelismo de fragment shader.
- Mipmapping y LOD: para efectos grandes y complejos.
9. Aplicaciones Comunes
- Arte generativo: fractales, patrones abstractos, deformaciones.
- Escenarios low-poly o surrealistas en 3D.
- Visualizaciones científicas: campos de distancia y volúmenes.
- Experimentos con postprocesado: glow, refraction, fog.
10. Recursos y Referencias
- Inigo Quilez: Raymarching Distance Fields
- The Book of Shaders: Raymarching Section
- Shadertoy Examples - Raymarching
- GPU Gems: Raymarching
——
Shaders para Juegos 3D Low Poly en Godot
Guía de referencia y conceptos para crear shaders específicos para juegos 3D low poly en godot, optimizados para estética simplificada y rendimiento en tiempo real.
Incluye fundamentos, tipos de shaders, técnicas y recomendaciones de implementación.
1. Conceptos Clave
▸ Estilo Low Poly
- Superficies planas, pocas caras, geometría simplificada.
- Uso de colores sólidos o gradientes simples.
- Iluminación estilizada, no necesariamente realista.
- Bordes duros o suavizados con técnicas como Flat Shading.
▸ Consideraciones de Rendimiento
- Minimizar cálculos por fragmento: preferir cálculos en vertex shader si es posible.
- Evitar texturas pesadas: usar colores sólidos o mapas simples.
- Reducir llamadas a GPU y overdraw.
- Aprovechar instancing para objetos repetidos.
2. Tipos de Shaders Recomendados
▸ Vertex Shaders
- Transformaciones básicas: rotación, escalado, animación procedural de vértices.
- Simulación de viento en hojas o banderas.
- Ondas suaves para agua o terreno.
Ejemplo:
shader_type spatial;
uniform float time;
void vertex() {
VERTEX.y += sin(VERTEX.x * 0.5 + time) * 0.2;
}
`
▸ Fragment Shaders
- Colores planos y gradientes simples.
- Sombras estilizadas usando fake lighting o vertex color interpolation.
- Contornos y resaltado de bordes con normals y view direction.
Ejemplo Flat Shading:
shader_type spatial;
void fragment() {
vec3 lightDir = normalize(vec3(0.5, 1.0, 0.3));
float NdotL = max(dot(NORMAL, lightDir), 0.0);
ALBEDO = vec3(0.8, 0.5, 0.3) * NdotL;
}
▸ Unlit Shaders
- Para colores sólidos sin iluminación, útil para estilo cartoon low poly.
- Recomendado para fondos o objetos secundarios.
3. Técnicas Especiales para Low Poly
▸ Vertex Color Mapping
- Asignar color directamente a vértices en Blender o Godot.
- Reduce necesidad de texturas.
- Permite gradientes suaves o colores por cara.
▸ Flat Shading
- Ignorar interpolación de normales: cada cara tiene un color uniforme.
- Fomenta estilo artístico low poly.
- Implementable en Godot con
NORMAL = normalize(cross(dFdx(VERTEX), dFdy(VERTEX)));.
▸ Fake Ambient Occlusion
- Usar un multiplicador basado en ángulo entre normal y dirección de luz.
- No requiere mapas de AO ni luz global compleja.
▸ Rim Lighting / Contour Glow
- Resalta silueta de objetos.
vec3 viewDir = normalize(CAMERA_POSITION - VERTEX);
float rim = 1.0 - max(dot(NORMAL, viewDir), 0.0);
ALBEDO += vec3(1.0, 1.0, 1.0) * rim * 0.2;
4. Texturas y Mapas
- Difuso: colores planos, degradados o pequeños detalles.
- Normal Map opcional: para detalles mínimos, no imprescindible.
- Mask/Specular Map: solo si se desea control de brillo limitado.
Tips:
- Mantener resolución baja.
- Evitar texturas complejas para conservar la estética low poly.
- Preferir paletas de color planas.
5. Implementación en Godot
▸ Shader Types
spatial→ para objetos 3D con luz y sombreado.canvas_item→ 2D, útil para proyecciones o efectos UI.particles→ efectos de partículas low poly.
▸ Integración
- Crear Material Shader y asignar al MeshInstance.
- Usar Uniforms para parámetros ajustables: colores, velocidad de animación, intensidad de rim.
- Aprovechar vertex colors para modular shaders sin agregar texturas.
▸ Reutilización
- Crear librería de funciones: flat shading, rim lighting, AO falso.
- Variables uniformes para ajustes rápidos de estilo artístico.
- Combinación de shaders para efectos de viento, deformación y color.
6. Ejemplos de Efectos Low Poly
▸ Agua o Líquido
- Vertex shader con oscilación simple.
- Fragment shader unlit o con gradiente.
▸ Cielo Estilizado
- Gradientes verticales simples.
- No usar texturas complejas, controlar color mediante uniform.
▸ Partículas
- Pequeños meshes low poly.
- Shaders unlit con colores sólidos o gradientes simples.
▸ Sombras
- Fake shadows usando vertex color y dirección de luz.
- Evitar sombras dinámicas complejas para rendimiento.
7. Recursos y Referencias
- Godot Shader Documentation
- Godot 3D Low Poly Tips
- Shader Examples for Low Poly Art
- Flat Shading in Godot
8. Recomendaciones
- Mantener shaders simples y modulables.
- Priorizar vertex shader para animaciones simples, fragment shader para color.
- Evitar iluminación compleja si el estilo busca simplicidad.
- Documentar combinaciones de efectos: rim + flat shading + AO falso.
- Guardar presets de shaders para reutilización en distintos meshes low poly.
Shaders para Juegos 2D
Guía de referencia sobre la aplicación de shaders en juegos 2D, enfocada en efectos visuales, rendimiento y técnicas comunes en motores como Godot, Unity o frameworks WebGL.
1. Conceptos Fundamentales
- 2D Shaders: programas que se ejecutan en la GPU y afectan cómo se renderizan sprites, tiles o fondos.
- Pueden modificar color, iluminación, deformaciones, partículas y efectos visuales.
- Tipos principales:
- Fragment shaders: alteran los colores y transparencia de los píxeles.
- Vertex shaders (menos comunes en 2D): deforman geometría de sprites o tiles.
- Canvas shaders: aplicados a todo el lienzo o layer completo.
2. Efectos Comunes en Juegos 2D
▸ Color y Postprocesado
- Saturación, contraste, tintado de sprites.
- Gradientes dinámicos y paletas de color.
- Pixelation y dithering para estilo retro o low-res.
▸ Distorsión y Animación
- Wobble, shake o deformaciones de agua.
- Efectos de viento en elementos como hojas o banderas.
- Scroll parallax con deformaciones suaves para fondos.
▸ Iluminación y Sombras
- Simulación de luz 2D: sombreado de tiles o sprites.
- Rim lighting para destacar personajes.
- Sombras proyectadas simples con offset y multiplicador de color.
▸ Transiciones y Feedback Visual
- Flash de daño, parpadeo de objetos.
- Efectos de fade, blur o glow.
- Contornos y outline estilizados.
3. Técnicas de Shader 2D
▸ Sprite Tinting
shader_type canvas_item;
uniform vec4 tint_color : hint_color;
void fragment() {
COLOR = texture(TEXTURE, UV) * tint_color;
}
`
▸ Pixelation / Retro Look
shader_type canvas_item;
uniform float pixel_size = 4.0;
void fragment() {
vec2 uv_pixel = floor(UV * SCREEN_PIXEL_SIZE / pixel_size) * pixel_size / SCREEN_PIXEL_SIZE;
COLOR = texture(TEXTURE, uv_pixel);
}
▸ Wave / Wobble Effect
shader_type canvas_item;
uniform float time;
void fragment() {
vec2 uv_wave = UV + vec2(sin(UV.y*10.0 + time)*0.01, 0.0);
COLOR = texture(TEXTURE, uv_wave);
}
▸ Outline / Contour
- Usando samplers desplazados o un postprocesado sobre el sprite.
4. Integración en Motores
▸ Godot
- Shader 2D:
canvas_item - Aplicable a Sprite, TileMap o Control nodes.
- Compatible con viewport shaders para efectos globales.
▸ Unity
- Shader Graph 2D para Sprite Renderer.
- Soporta URP 2D Renderer con custom shaders para luces, normales y efectos de postprocesado.
▸ Web / Three.js / Pixi.js
- Fragment shaders aplicados sobre planes o sprites.
- WebGL permite efectos en tiempo real sobre canvas HTML5.
5. Buenas Prácticas
- Mantener shaders ligeros para no afectar performance.
- Usar uniforms para parámetros variables y reutilizables.
- Modularizar efectos: color, deformación y postprocesado por separado.
- Priorizar vertex shader solo si deformación afecta pocos vértices; fragment shader para colores y pixeles.
- Testear en resoluciones objetivo del juego (retro vs HD).
6. Recursos y Referencias
- Godot 2D Shaders
- Unity 2D Shader Graph
- The Book of Shaders - 2D
- Shadertoy 2D Examples
- Pixelation & Retro Shader Techniques
—-
shader de cubo que se deforma y se descompone con animacion
#define PI 3.14159265359
#define PHI 1.618033988749895
// HG_SDF
void pR(inout vec2 p, float a) {
p = cos(a)*p + sin(a)*vec2(p.y, -p.x);
}
float vmax(vec3 v) {
return max(max(v.x, v.y), v.z);
}
float fBox(vec3 p, vec3 b) {
vec3 d = abs(p) - b;
return length(max(d, vec3(0))) + vmax(min(d, vec3(0)));
}
// Rotate on axis, blackle
vec3 erot(vec3 p, vec3 ax, float ro) {
return mix(dot(ax,p)*ax, p, cos(ro))+sin(ro)*cross(ax,p);
}
// Sign but returns -1 instead of 0
vec3 boolSign(vec3 v) {
return max(vec3(0), sign(v)) * 2. - 1.;
}
// Closest icosahedron vertex
vec3 icosahedronVertex(vec3 p) {
vec3 ap, v, v2, v3;
ap = abs(p);
v = vec3(PHI, 1, 0);
v2 = v.yzx;
v3 = v2.yzx;
if (distance(ap, v2) < distance(ap, v)) v = v2;
if (distance(ap, v3) < distance(ap, v)) v = v3;
return normalize(v) * boolSign(p);
}
// Closest dodecahedron vertex
vec3 dodecahedronVertex(vec3 p) {
vec3 ap, v, v2, v3, v4;
ap = abs(p);
v = vec3(PHI);
v2 = vec3(0, 1, PHI + 1.);
v3 = v2.yzx;
v4 = v3.yzx;
if (distance(ap, v2) < distance(ap, v)) v = v2;
if (distance(ap, v3) < distance(ap, v)) v = v3;
if (distance(ap, v4) < distance(ap, v)) v = v4;
return normalize(v) * boolSign(p);
}
// Second closest dodecahedron vertex
vec3 secondDodecahedronVertex(vec3 p, vec3 iv, vec3 dv) {
// Find which side of the icosahedron vertex -> dodecahedron vertex line we're on
float side = sign(dot(p, cross(iv, dv)));
// Rotate dodecahedron vertex around the dodecahedron face
return erot(dv, iv, PI * 2. / 5. * side);
}
// The model to explode
float object(vec3 p) {
pR(p.xz, 1.2);
pR(p.xy, .3);
float d = fBox(p, vec3(.25 - .02)) - .02;
d = max(d, -d - .05);
return d;
}
// https://iquilezles.org/articles/functions
float expImpulse( float x, float k )
{
float h = k*x;
return h*exp(1.0-h);
}
float map2(vec3 p) {
// Three closest vertices of a spherical pentakis dodecahedron
// or, three closest faces of a buckyball
vec3 a = icosahedronVertex(p);
vec3 b = dodecahedronVertex(p);
vec3 c = secondDodecahedronVertex(p, a, b);
float d = 1e12;
vec3 pp = p;
// Render the nearest three fragments to get
// a clean distance estimation
for (int i = 0; i < 3; i++) {
// Offset space
float t = mod((iTime - dot(a.xy, vec2(1,-1)) / 6.) / 3., 1.);
float t2 = min(t * 1.85, 1.);
float explode = 1. - pow(1. - t2, 10.); // expand
explode *= 1. - pow(t2, 5.); // contract
t2 = max(t - .53, 0.) * 1.2;
float wobble = sin(expImpulse(t2, 20.) * 2.2 + pow(3. * t2, 1.5) * 2. * PI * 2. - PI) * smoothstep(.4, .0, t2) * .15;
float anim = wobble + explode;
p -= a * anim / 2.8;
// Build boundary edge of face
float edgeA = dot(p, normalize(b - a));
float edgeB = dot(p, normalize(c - a));
float edge = max(edgeA, edgeB);
// Intersect with object
d = min(d, max(object(p), edge));
// Reset space for next iteration
p = pp;
// Cycle faces for next iteration
vec3 aa = a;
a = b;
b = c;
c = aa;
}
return d;
}
float map(vec3 p) {
if (iMouse.x > 0. && iMouse.y > 0.) {
pR(p.yz, (.5 - iMouse.y / iResolution.y) * PI / 2.);
pR(p.xz, (.5 - iMouse.x / iResolution.x) * PI * 2.);
}
return map2(p);
}
// compile speed optim from IQ https://www.shadertoy.com/view/Xds3zN
vec3 calcNormal(vec3 pos){
vec3 n = vec3(0.0);
for( int i=0; i<4; i++ )
{
vec3 e = 0.5773*(2.0*vec3((((i+3)>>1)&1),((i>>1)&1),(i&1))-1.0);
n += e*map(pos+0.0005*e);
}
return normalize(n);
}
// https://www.shadertoy.com/view/Xds3zN
float calcAO( in vec3 pos, in vec3 nor )
{
float occ = 0.0;
float sca = 1.0;
for( int i=0; i<5; i++ )
{
float h = 0.01 + 0.12*float(i)/4.0;
float d = map( pos + h*nor );
occ += (h-d)*sca;
sca *= 0.95;
if( occ>0.35 ) break;
}
return clamp( 1.0 - 3.0*occ, 0.0, 1.0 );
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 p = (-iResolution.xy + 2. * fragCoord.xy) / iResolution.y;
vec3 camPos = vec3(0,0,3.2);
vec3 rayDirection = normalize(vec3(p,-4));
vec3 rayPosition = camPos;
float rayLength = 0.;
float dist = 0.;
bool bg = false;
vec3 bgcol = vec3(.007);
vec3 col = bgcol;
for (int i = 0; i < 150; i++) {
rayLength += dist;
rayPosition = camPos + rayDirection * rayLength;
dist = map(rayPosition);
if (abs(dist) < .001) {
break;
}
if (rayLength > 5.) {
bg = true;
break;
}
}
if ( ! bg) {
vec3 albedo = vec3(1);
vec3 n = calcNormal(rayPosition);
vec3 lp = vec3(-.5,.5,.5);
float l = max(dot(lp, n), 0.);
vec3 ld = normalize(lp - rayPosition);
l += .02;
l += pow(max(0., 1. + dot(n, rayDirection)), 3.) * .05;
float ao = calcAO(rayPosition, n);
col = albedo * l * mix(1., ao, .8);
col = mix(col, bgcol, 1.0 - exp2(-0.2 * pow(rayLength - 1., 3.)));
}
col = pow(col, vec3(1./2.2));
fragColor = vec4(col,1);
}
explicacion gpt
¡Perfecto! Vamos a analizar este código paso a paso, enfocándonos en patrones, técnicas y cómo podrías implementarlo en Godot para tu juego. Este shader es un ejemplo avanzado de Ray Marching / Signed Distance Fields (SDF) con animaciones de explosión sobre una forma tipo pentakis dodecahedron. Voy a desglosarlo.
1. Patrones de código y técnicas utilizadas
a) Macros y constantes
#define PI 3.14159265359
#define PHI 1.618033988749895
- Se definen constantes matemáticas para uso posterior.
PIse usa para rotaciones,PHI(número áureo) para geometría de poliedros.- Patrón: definición global de constantes para mantener código limpio.
b) Rotaciones y transformaciones
void pR(inout vec2 p, float a) {
p = cos(a)*p + sin(a)*vec2(p.y, -p.x);
}
vec3 erot(vec3 p, vec3 ax, float ro) {
return mix(dot(ax,p)*ax, p, cos(ro)) + sin(ro)*cross(ax,p);
}
pRrota un vector 2D en el plano XY o XZ.erotrota un vectorpalrededor de un eje arbitrarioax.- Patrón: funciones genéricas de rotación para manipular geometría sin modificar la lógica de la escena.
c) SDF y geometría
float fBox(vec3 p, vec3 b)
float object(vec3 p)
fBoxdevuelve la distancia de un punto a un cubo de tamañob.objectdefine el modelo 3D “explodable” mediante SDF.- Técnica: Signed Distance Field (SDF) → cada punto del espacio devuelve la distancia mínima al objeto, lo que permite ray marching eficiente.
d) Geometría de poliedros
vec3 icosahedronVertex(vec3 p)
vec3 dodecahedronVertex(vec3 p)
vec3 secondDodecahedronVertex(vec3 p, vec3 iv, vec3 dv)
- Calcula los vértices más cercanos de icosaedros y dodecaedros a un punto
p. - Técnica avanzada de SDF: usa geometría de poliedros convexos para construir formas complejas de manera procedural.
e) Animaciones proceduralizadas
float expImpulse(float x, float k)
expImpulsegenera un impulso de animación suave, útil para efectos de “explosión” o “rebote”.- Patrón: funciones de interpolación para animaciones basadas en tiempo, muy común en shaders procedural.
f) Ray Marching
for (int i = 0; i < 150; i++) {
rayLength += dist;
rayPosition = camPos + rayDirection * rayLength;
dist = map(rayPosition);
if (abs(dist) < .001) break;
}
-
Patrón central: Ray Marching
- Se lanza un rayo desde la cámara.
- Se “camina” por el espacio sumando distancias mínimas devueltas por el SDF (
map). - Si la distancia es muy pequeña, se considera que el rayo ha golpeado el objeto.
-
Técnica: renderizado basado en distancia a objetos, no en geometría explícita.
g) Iluminación y AO
vec3 calcNormal(vec3 pos)
float calcAO(in vec3 pos, in vec3 nor)
calcNormalcalcula la normal mediante diferencias finitas sobre SDF.calcAOaplica Ambient Occlusion para sombreado más realista.- Patrón: shaders procedurales de iluminación usando información geométrica derivada de SDF.
h) Interactividad
if (iMouse.x > 0. && iMouse.y > 0.)
- El shader reacciona al movimiento del mouse para rotar la cámara.
- Patrón: inputs externos (mouse, tiempo) modifican las transformaciones del SDF.
2. Cómo trasladarlo a Godot
Godot usa GDScript + Shader Language (Godot Shading Language, GDSL) o VisualShader. Para implementar este tipo de efecto:
-
Node Setup
Viewportcon unShaderMaterialaplicado a unSprite3DoMeshInstancetipo plano (fullscreen quad).- Esto actúa como un render target para el shader tipo “ray marcher”.
-
Shader
- Copiar la lógica SDF y Ray Marching en un shader Godot tipo
canvas_itemospatial. -
Godot soporta GLSL muy similar, con algunos cambios:
vec2 fragCoord→SCREEN_UV * SCREEN_SIZE.iTime→TIME.iMouse→MOUSEomouse_position.
- Copiar la lógica SDF y Ray Marching en un shader Godot tipo
-
Animación
- Mantener la animación procedural basada en
TIME. - Para explotar objetos, podrías enviar un parámetro global (
shader_param) para controlar la explosión.
- Mantener la animación procedural basada en
-
Normal y AO
- La función
calcNormalse puede usar tal cual, aunque Godot permite sombreado normal calculado por el motor, así que se podría optimizar.
- La función
-
Optimización
- Reducir iteraciones de ray marching (
for) en Godot si buscas 60 FPS en tiempo real. - Considerar LOD o simplificación del SDF.
- Reducir iteraciones de ray marching (
3. Patrones de diseño observados
- Modularidad: funciones pequeñas (
pR,erot,fBox) reutilizables. - Animaciones basadas en tiempo:
expImpulsey modificaciones de SDF. - Iteración procedural: ciclo sobre los vertices para animar geometría.
- Ray Marching / SDF: patrón central para objetos complejos sin malla física.
- Interactividad: inputs externos modifican rotación y animación.
💡 Resumen: Este código es un ray marcher SDF procedural con animaciones de explosión basadas en vértices de dodecaedros y icosaedros. Los patrones son: modularidad, animación procedural, uso de SDF y técnicas de iluminación derivadas del SDF (normales y AO).
En Godot, podrías implementarlo como un shader 3D en un quad y controlar la explosión con shader_param. Es excelente para efectos de estilo “Shader Toy” dentro de un juego, aunque no sería un mesh físico manipulable (para eso habría que generar la geometría desde el shader o un mesh generator).
analisis de rendimiento y portabilidad
Sí, vamos a analizar rendimiento, alternativas y posibilidades de interacción en tiempo real para este tipo de shader. Esto es clave antes de implementarlo en un juego.
1. Consumo en tiempo real
Este shader ray marches un objeto complejo con múltiples iteraciones y animaciones procedurales. Factores que afectan el rendimiento:
- Iteraciones del rayo:
for (int i = 0; i < 150; i++) { ... }
Cada fragmento puede recorrer hasta 150 pasos, haciendo distancia a SDF y cálculos de normales/iluminación por paso.
-
Complejidad de SDF:
- Funciones como
dodecahedronVertexosecondDodecahedronVertexson costosas. - Animaciones de “explosión” recalculan transformaciones y rotaciones por cada iteración.
- Funciones como
-
Iluminación y AO:
calcNormalycalcAOson bucles adicionales por pixel.- Esto multiplica el costo por fragmento.
-
Pantalla completa: Si el shader se aplica a un quad fullscreen (como en Shadertoy), cada pixel ejecuta todas las iteraciones → muy costoso para 60 FPS en resoluciones altas.
Conclusión: En tiempo real, este shader probablemente sea demasiado pesado para resoluciones completas en GPU de gama media. Puede funcionar a baja resolución (p. ej. 640x360) y luego hacer upscale.
2. Alternativas más eficientes
-
Reducir iteraciones de ray marching
- Pasar de 150 → 50-80 pasos según la calidad aceptable.
-
Optimizar SDF
- Precalcular algunos vértices.
- Usar combinaciones simples de SDF en vez de cálculos de dodecaedro cada frame.
-
Baking
- Renderizar la animación fuera de tiempo real a textura animada (flipbook o sprite sheet).
- Usar como material en Godot, mucho más eficiente para tiempo real.
-
LOD (Level of Detail)
- Para distancias grandes, usar SDF simplificado.
- Para cerca de la cámara, aplicar shader completo.
-
Compute Shader / Offscreen Render
- Puedes usar un Viewport render target y solo actualizar la textura cada pocos frames.
3. Renderizado fuera de tiempo real
Sí, totalmente posible:
- Podrías usar Shadertoy + captura de video o Godot Viewport + ShaderMaterial para renderizar animaciones de alta calidad.
- Guardar frames a imágenes o video.
- Esto permite hacer efectos complejos sin preocuparte por FPS.
4. Interactividad en Godot
Sí, el shader puede ser interactivo, pero con ciertas limitaciones:
-
Puedes pasar inputs externos:
mouse_position→ controlar rotación de la cámara o la explosión.shader_param→ controlar intensidad de la explosión.
-
Limitación:
- Como todo se hace por pixel y no hay mesh físico, colisiones u objetos físicos no interactúan con el SDF.
- Es un efecto visual, no un objeto jugable.
✅ Resumen
| Aspecto | Tiempo real | Alternativa |
|---|---|---|
| FPS | Muy costoso a resolución alta | Reducir pasos de ray march / baja resolución |
| Interactividad | Sí, inputs de shader | Limitado a visualización |
| Uso en gameplay | Visual / efectos | No como mesh físico |
| Renderización offline | Sí | Flipbook o animación renderizada |
Si quieres, puedo hacer un plan concreto para Godot 4 donde:
- Sea interactivo con mouse/teclas
- Optimizado para 60 FPS en tiempo real
- Mantenga la estética de “explosión dodecaedro”
Esto te daría un shader usable directamente en tu juego.
¿Quieres que haga eso?
codigo mejorado por gpt
#define PI 3.14159265359
#define PHI 1.618033988749895
// -----------------------------
// Utility Functions
// -----------------------------
// 2D rotation
void pR(inout vec2 p, float a) {
p = cos(a)*p + sin(a)*vec2(p.y, -p.x);
}
// Max component of a vec3
float vmax(vec3 v) {
return max(max(v.x, v.y), v.z);
}
// Box SDF
float fBox(vec3 p, vec3 b) {
vec3 d = abs(p) - b;
return length(max(d, vec3(0.0))) + vmax(min(d, vec3(0.0)));
}
// Rotate around arbitrary axis
vec3 erot(vec3 p, vec3 ax, float ro) {
return mix(dot(ax,p)*ax, p, cos(ro)) + sin(ro)*cross(ax,p);
}
// Sign but returns -1 instead of 0
vec3 boolSign(vec3 v) {
return max(vec3(0.0), sign(v)) * 2.0 - 1.0;
}
// Exponential impulse function for animation
float expImpulse(float x, float k) {
float h = k*x;
return h*exp(1.0 - h);
}
// -----------------------------
// Geometry / Polyhedron
// -----------------------------
vec3 icosahedronVertex(vec3 p) {
vec3 ap = abs(p);
vec3 v = vec3(PHI,1,0);
vec3 v2 = v.yzx;
vec3 v3 = v2.yzx;
if(distance(ap,v2)<distance(ap,v)) v=v2;
if(distance(ap,v3)<distance(ap,v)) v=v3;
return normalize(v) * boolSign(p);
}
vec3 dodecahedronVertex(vec3 p) {
vec3 ap = abs(p);
vec3 v = vec3(PHI);
vec3 v2 = vec3(0,1,PHI+1.0);
vec3 v3 = v2.yzx;
vec3 v4 = v3.yzx;
if(distance(ap,v2)<distance(ap,v)) v=v2;
if(distance(ap,v3)<distance(ap,v)) v=v3;
if(distance(ap,v4)<distance(ap,v)) v=v4;
return normalize(v) * boolSign(p);
}
vec3 secondDodecahedronVertex(vec3 p, vec3 iv, vec3 dv) {
float side = sign(dot(p, cross(iv, dv)));
return erot(dv, iv, PI * 2.0 / 5.0 * side);
}
// -----------------------------
// Object / SDF
// -----------------------------
float object(vec3 p) {
pR(p.xz, 1.2);
pR(p.xy, 0.3);
float d = fBox(p, vec3(0.23)) - 0.02;
return max(d, -d - 0.05);
}
// -----------------------------
// Mapping / Scene
// -----------------------------
float map2(vec3 p) {
vec3 a = icosahedronVertex(p);
vec3 b = dodecahedronVertex(p);
vec3 c = secondDodecahedronVertex(p, a, b);
float d = 1e12;
vec3 pp = p;
for(int i=0;i<3;i++){
// Animation timing
float t = mod((iTime - dot(a.xy, vec2(1,-1))/6.0)/3.0, 1.0);
float t2 = min(t*1.85,1.0);
float explode = 1.0 - pow(1.0 - t2, 10.0);
explode *= 1.0 - pow(t2, 5.0);
t2 = max(t-0.53,0.0)*1.2;
float wobble = sin(expImpulse(t2,20.0)*2.2 + pow(3.0*t2,1.5)*2.0*PI*2.0 - PI)*smoothstep(0.4,0.0,t2)*0.15;
float anim = explode + wobble;
p -= a * anim / 2.8;
// Face boundary
float edgeA = dot(p, normalize(b - a));
float edgeB = dot(p, normalize(c - a));
float edge = max(edgeA, edgeB);
// Combine object and face
d = min(d, max(object(p), edge));
p = pp; // reset
vec3 aa = a; a=b; b=c; c=aa; // rotate vertices
}
return d;
}
float map(vec3 p) {
// Mouse-controlled rotation
if(iMouse.x>0. && iMouse.y>0.) {
pR(p.yz, (.5 - iMouse.y/iResolution.y)*PI/2.0);
pR(p.xz, (.5 - iMouse.x/iResolution.x)*PI*2.0);
}
return map2(p);
}
// -----------------------------
// Normal / AO
// -----------------------------
vec3 calcNormal(vec3 pos){
vec3 n = vec3(0.0);
for(int i=0;i<4;i++){
vec3 e = 0.5773*(2.0*vec3((((i+3)>>1)&1),((i>>1)&1),(i&1))-1.0);
n += e*map(pos + 0.0005*e);
}
return normalize(n);
}
float calcAO(vec3 pos, vec3 nor){
float occ=0.0;
float sca=1.0;
for(int i=0;i<5;i++){
float h=0.01+0.12*float(i)/4.0;
float d = map(pos + h*nor);
occ += (h-d)*sca;
sca *= 0.95;
if(occ>0.35) break;
}
return clamp(1.0 - 3.0*occ,0.0,1.0);
}
// -----------------------------
// Main
// -----------------------------
void mainImage(out vec4 fragColor, in vec2 fragCoord){
vec2 uv = (-iResolution.xy + 2.0*fragCoord.xy)/iResolution.y;
vec3 camPos = vec3(0,0,3.2);
vec3 rayDir = normalize(vec3(uv,-4.0));
vec3 rayPos = camPos;
float rayLength = 0.0;
float dist = 0.0;
bool bg=false;
vec3 bgcol=vec3(0.007);
vec3 col=bgcol;
// Ray marching
for(int i=0;i<150;i++){
dist = map(rayPos);
rayLength += dist;
rayPos = camPos + rayDir*rayLength;
if(abs(dist)<0.001){ break; }
if(rayLength>5.0){ bg=true; break; }
}
if(!bg){
vec3 n = calcNormal(rayPos);
vec3 light = vec3(-0.5,0.5,0.5);
float l = max(dot(light,n),0.0);
l += 0.02;
l += pow(max(0.0,1.0 + dot(n,rayDir)),3.0)*0.05;
float ao = calcAO(rayPos,n);
col = vec3(1.0) * l * mix(1.0,ao,0.8);
col = mix(col,bgcol,1.0 - exp2(-0.2*pow(rayLength-1.0,3.0)));
}
fragColor = vec4(pow(col,vec3(1.0/2.2)),1.0);
}
podriamos cambiar la forma geometrica y su descomposicion por otra? que implicaciones tendria?
¡Claro! Cambiar la forma geométrica base y su descomposición (cómo se calcula el SDF y los “vértices de referencia”) tiene varias implicaciones, tanto visuales como técnicas. Vamos a analizarlo con detalle.
1. Qué significa cambiar la forma geométrica
En tu shader original:
- La geometría base es un pentakis dodecahedron (dodecaedro con pirámides en cada cara) o una aproximación a un buckyball.
- Las funciones
icosahedronVertex,dodecahedronVertexysecondDodecahedronVertexcalculan los vértices más cercanos para determinar cómo se aplica la animación de explosión y las deformaciones. - La función
map2combina estas referencias para animar las “caras” y generar bordes.
Si cambias la forma geométrica:
- Tendrías que definir nuevas funciones que calculen vértices o caras relevantes.
- Las animaciones (
explode,wobble) dependen de cómo los vértices definen “subestructuras” de la forma. - Las SDF de la forma (la función
object) podrían necesitar una reescritura completa.
Ejemplos de formas alternativas:
| Forma | Implicaciones |
|---|---|
| Cubo / Box | Muy simple, bordes planos, fácil de SDF, animaciones simples. |
| Octaedro / Tetraedro | Menos vértices, más angular, “explosión” más marcada. |
| Icosaedro / Esfera aproximada | Más suave, requiere más vértices para deformaciones, más costoso. |
| Torus / Forma curva | Cambia completamente la lógica, las referencias de vértices ya no funcionan igual. |
| Forma personalizada procedural | Necesitas definir la SDF y la lógica de fragmentos por cara o vértice. |
2. Implicaciones técnicas
-
SDF diferente
- Cada forma tiene su propia SDF (
object(vec3 p)). - Para formas complejas, como polígonos irregulares o curvas suaves, el SDF puede ser más costoso de calcular.
- Cada forma tiene su propia SDF (
-
Referencias para animación
- Tu sistema actual calcula los 3 vértices más cercanos para deformar caras.
- Si cambias la forma, necesitarás un método equivalente para seleccionar puntos de control sobre la superficie, que define cómo se “explota” la figura.
-
Ray marching
- La eficiencia depende de la complejidad de la SDF.
- Formas más complejas → más cálculos por iteración → más costoso.
- Puedes optimizar usando bounding boxes, distance fields simplificados, o LOD.
-
Iluminación y AO
- Normales calculadas con diferencias finitas (
calcNormal) funcionan con cualquier SDF. - AO (
calcAO) también funciona, pero si la forma tiene detalles muy finos, necesitarás más pasos para un resultado limpio → más pesado.
- Normales calculadas con diferencias finitas (
-
Animación “explosión”
-
El concepto de “vértices más cercanos” se mantiene, pero hay que adaptar la lógica:
explodeywobblese aplican sobre puntos de control de la nueva forma.- En formas irregulares, quizá necesites múltiples puntos de control o una aproximación “por cara”.
-
3. Visuales y estilo
- Formas angulares (cubo, tetraedro, octaedro) → explosiones más duras y geométricas.
- Formas suaves (esfera, torus, icosaedro) → explosiones más orgánicas y redondeadas.
- Cambiar la forma puede hacer que la animación pierda el carácter “pentakis dodecahedron” que da un estilo de Shadertoy muy reconocible.
4. Cómo implementarlo en tu shader
- Reemplazar
icosahedronVertex,dodecahedronVertex,secondDodecahedronVertexpor nuevas funciones según la geometría. - Adaptar
map2para usar los nuevos puntos de control en la animación. - Ajustar
object(vec3 p)para la nueva SDF de la forma. - Revisar parámetros de animación (
explode,wobble) para que la deformación se vea natural en la nueva geometría.
💡 Consejo: Para probar rápido, puedes empezar con formas poligonales simples, como un cubo o tetraedro, y luego pasar a formas más complejas.
digamos que en vez de una explosion quiero una lluvia de meteoritos en la forma geometrica, seria un cambio de animacion que implicaciones tendria
Cambiar de una explosión de una geometría a una lluvia de meteoritos implica un cambio de concepto de animación y tiene varias implicaciones técnicas y visuales en tu shader. Vamos a desglosarlo:
1. Conceptualmente
-
Explosión (actual)
- Se centra en una forma fija que se deforma desde su centro hacia afuera.
- El shader calcula los vértices más cercanos para animar fragmentos de la figura (
explodeywobble). - Cada fragmento depende de la geometría de origen.
-
Lluvia de meteoritos (nuevo)
- Ahora cada “objeto” (meteorito) se mueve de manera independiente.
- No se trata de deformar una forma única, sino de multiples instancias de SDFs (cada meteorito) moviéndose a lo largo de la escena.
- Posiblemente la geometría de cada meteorito sea simple (esfera, cubo, icosaedro), o incluso variada.
2. Implicaciones técnicas
-
Posición de los meteoritos
- Necesitas un sistema de instancias o partículas dentro del shader.
- Por ejemplo, un array de posiciones iniciales y velocidades, calculadas procedimentalmente a partir de
iTimeyfragCoordpara no usar memoria externa.
-
Animación
- Cada meteorito se mueve a lo largo de una trayectoria (por ejemplo,
pos = basePos + velocity * iTime). - La función
mapahora debe combinar distancias de múltiples meteoritos:
- Cada meteorito se mueve a lo largo de una trayectoria (por ejemplo,
glsl
float map(vec3 p){
float d = 1e12;
for(int i=0;i<N;i++){
vec3 meteorPos = computePosition(i, iTime);
d = min(d, meteorSDF(p - meteorPos));
}
return d;
}
- Esto es más costoso si
Nes grande. Podrías limitar a 10–20 meteoritos activos simultáneamente para Shadertoy.
-
Rotación de meteoritos
- Cada meteorito podría rotar sobre sí mismo (
erot) para más realismo. - Esto es opcional, pero aumenta el coste por fragmento.
- Cada meteorito podría rotar sobre sí mismo (
-
Ray marching
- La distancia mínima a todas las instancias de meteoritos debe ser calculada.
- Esto multiplica la complejidad:
dist = min(dist, map_meteorito_i). - Más meteoritos → más iteraciones → más pesado.
-
Colisiones / efectos
- Puedes simular “colisiones con el suelo” o “desintegración” manipulando la SDF por posición.
- También se pueden hacer efectos de luz y brillo dinámico.
3. Visuales y estilo
- En vez de un solo objeto que se expande, verías varios objetos cayendo con trayectorias independientes.
-
Puedes variar:
- Tamaño y forma de cada meteorito.
- Velocidad de caída.
- Color y brillo.
- “Trail” usando AO o blur procedural.
4. Diferencias respecto a la explosión
| Aspecto | Explosión | Lluvia de meteoritos |
|---|---|---|
| Dependencia de geometría | Alta (vértices de forma) | Baja, cada meteorito independiente |
| Movimiento | Expansión radial | Trayectorias lineales o curvas |
| Animación | Centralizada | Distribuida / múltiple instancias |
| Complejidad | 1 SDF principal + deformación | N SDFs + cálculo mínimo por pixel |
| Interactividad | Rotación del objeto | Rotación o movimiento global, posibilidad de mouse para cámara |
💡 Consejo de implementación en Shadertoy/Godot:
- Genera posiciones iniciales y velocidades proceduralmente para no usar arrays grandes.
- Usa una SDF simple (esfera o cubo) para meteoritos si quieres rendimiento.
- Reduce el número de meteoritos o la resolución si quieres 60 FPS.
- Mantén la cámara interactiva (
iMouse) como en tu shader original.
Si quieres, puedo hacer un ejemplo de shader de lluvia de meteoritos basado en tu estructura original, con rotación de cámara y meteoritos cayendo sobre un “suelo” listo para Shadertoy.
¿Quieres que haga eso?
¿Te gusta este contenido? Suscríbete vía RSS