CULTIVA Studio · Houdini VFX Pipeline

Procedural Data-Flow VFX
SideFX Houdini 20.5

Pipeline completo para spot "IA Digital Neuro-Network" — 4K · 25fps · 5s · Redshift GPU
Tipo
HDA + PDG Batch
Renderer
Redshift GPU
Resolución
3840 × 2160
Variaciones
5 paletas de color
Output
.fbx + .abc + .exr
Grafo de Nodos — SOP/DOP/LOP
SOP Context — Generación de Partículas
scatter_src
Sphere (24 emisores)
wrangle_emit
VEX: velocidad radial
popnet
POP Solver (attractor)
wrangle_color
VEX: color + glow
trail_sop
Trail (fibra óptica)
polyextrude
Extrude trails
cultiva_neuro_HDA
HDA empaquetado
solaris_stage
USD / Solaris
redshift_rop
Render .exr 4K

TOP/PDG Context — Batch 5 Variaciones
csv_palettes
CSV 5 paletas
hda_processor
Actualiza parámetros
rop_render
Render paralelo
rop_geo
Export .abc + .fbx
thumbnail_gen
PNG preview
csv_manifest
Manifiesto assets
wrangle_emit — Velocidad radial de partículas
VEX
// Point Wrangle: Inicializa partículas con velocidad
// convergente hacia el attractor central

vector center = chv("attractor_pos");   // UI param
float  speed  = chf("base_speed");      // 1.0 – 8.0
float  chaos  = chf("chaos");           // 0.0 – 1.0

// Dirección desde punto hasta centro
vector dir = normalize(center - @P);

// Añadir perturbación noise para trayectorias orgánicas
vector noise_v = (curlnoise(@P * 2.3 + @Time * 0.4)
               - 0.5) * 2.0 * chaos;

// Velocidad base + perturbación
@v = (dir + noise_v) * speed;

// Masa inversa a la distancia (más rápido al acercarse)
float dist = length(center - @P);
@v *= fit(dist, 0, 15, 3.0, 0.8);  // acelera

// Lifetime aleatorio per-partícula
@life   = 0.0;
@nlife  = rand(@ptnum * 17.7);
@pscale = fit01(rand(@ptnum * 3.14), 0.008, 0.022);
wrangle_color — Color + glow por distancia
VEX
// Point Wrangle: Colorea partículas según
// distancia al centro y velocidad actual

vector center  = chv("attractor_pos");
vector col_far  = chv("color_far");    // Brand color
vector col_near = chv("color_near");   // White/bloom
float  glow_exp = chf("glow_exponent"); // 1.5–4.0

float dist = length(center - @P);
float t    = 1.0 - fit(dist, 0, 12, 0, 1);

// Mezcla de color basada en proximidad
@Cd = lerp(col_far, col_near, pow(t, glow_exp));

// Alpha = velocidad normalizada (trails más brillantes)
float spd = length(@v);
@Alpha = fit(spd, 0.5, 8.0, 0.2, 1.0);

// Emission strength para Redshift (HDR glow)
f@emission = pow(t, 2.0) * chf("emission_mult");

// Attr para shader (Redshift UserData)
i@variant = chi("color_variant");  // 0–4
Pipeline PDG — Batch 5 Variaciones de Color
📋
File Pattern → palettes.csv
Lee 5 filas: variant_id, color_far (RGB), color_near (RGB), emission_mult — genera 5 work items en paralelo
⚙️
HDA Processor → cultiva_neuro_HDA
Inyecta parámetros de color en el HDA; recalcula simulación POP y trails para cada variante
🎬
ROP Render → Redshift GPU
Renderiza frames 1–125 (5s × 25fps) por variante; GPUs múltiples si hay farm; output EXR multicapa
variant_00_####.exr variant_01_####.exr
📦
ROP Geometry → Export Alembic + FBX
Exporta geometría animada en .abc (Nuke compositing) y .fbx (Unity/Unreal + after effects)
neuro_v00.abc neuro_v00.fbx
🖼️
ImageMagick → Thumbnails PNG
Extrae frame central (frame 62) de cada variante → convierte EXR a PNG 800×450 + overlay de nombre
thumb_v00_lime.png thumb_v01_blue.png
📄
CSV Output → asset_manifest.csv
Genera catálogo con rutas de archivo, checksums, parámetros usados y tiempo de render por variante
asset_manifest.csv
Parámetros del HDA — cultiva_neuro_v1.0.hda
Parámetro Tipo Rango / Default Descripción
particle_count int 500 – 50000 / 8000 Número total de partículas emitidas por frame
emitter_radius float 1.0 – 30.0 / 12.0 Radio de la esfera de emisión (en unidades Houdini)
attractor_pos vector3 Posición del nodo central (por defecto origen {0,0,0})
base_speed float 0.5 – 12.0 / 4.5 Velocidad base de convergencia hacia el centro
chaos float 0.0 – 1.0 / 0.35 Cantidad de turbulencia curlnoise en las trayectorias
trail_length int 2 – 60 / 18 Frames de historia para el Trail SOP (efecto fibra óptica)
color_far color Color de partículas lejanas al centro (brand color)
color_near color Color de partículas cerca del centro (bloom blanco)
emission_mult float 0.5 – 10.0 / 3.5 Multiplicador de intensidad de emisión HDR para glow Redshift
glow_exponent float 0.5 – 6.0 / 2.2 Exponente de la curva de glow hacia el centro (pow(t, exp))
color_variant int (menu) 0 – 4 / 0 Índice de paleta PDG: 0=Lime, 1=Blue, 2=Purple, 3=White, 4=Rainbow
Paletas de Color — CULTIVA Brand
Verde Lima
#A8FF3E
variant_id: 0
Azul Eléctrico
#00D4FF
variant_id: 1
Morado Neón
#8B5CF6
variant_id: 2
Blanco Puro
#FFFFFF
variant_id: 3
Gradiente Rainbow
HSV animated
variant_id: 4
Automatización Python — Batch Setup
batch_setup.py — Inicializa PDG + inyecta paletas desde CSV
Python
import hou
import csv

# Ruta al HDA y al CSV de paletas
HDA_PATH    = "/job/cultiva/hda/cultiva_neuro_v1.0.hda"
PALETTES    = "/job/cultiva/data/palettes.csv"
OUTPUT_DIR  = "/job/cultiva/output/renders"

# Instalar HDA
hou.hda.installFile(HDA_PATH)

# Obtener nodo TOP de paletas en la red PDG
tops = hou.node("/tasks/cultiva_batch")
csv_node = tops.node("csv_palettes")
csv_node.parm("csvfile").set(PALETTES)

# Cargar paletas y verificar conteo
with open(PALETTES) as f:
    palettes = list(csv.DictReader(f))

print(f"✓ {len(palettes)} variantes de color cargadas")

# Cookear la red PDG completa
tops.cookWorkItems(block=True)

# Reporte de resultados
for item in tops.scheduledItems():
    variant = item.attribValue("variant_id")
    frames  = item.attribValue("frame_count")
    time_s  = item.attribValue("cook_time")
    print(f"  variant_{variant:02d}: {frames} frames · {time_s:.1f}s")

print(f"✓ PDG batch completado → {OUTPUT_DIR}")
Especificaciones Técnicas del Proyecto
🎥
Resolución
3840 × 2160
4K UHD · 25fps · 5s (125 frames)
Renderer
Redshift GPU
NVIDIA RTX 4090 · ~8min/frame
🧩
Partículas
8,000 / frame
24 emisores · trail 18 frames
📦
Outputs
3 formatos
.exr multicapa · .abc · .fbx
🔄
Variaciones PDG
5 paletas
Paralelo en GPU farm
🏗️
Pipeline
USD/Solaris
Solaris → Redshift → EXR → Nuke
Best Practices aplicadas al proyecto
1
VEX sobre Python para geometría — Todo el procesado per-partícula (velocidades, colores, alpha) corre en VEX multihilo; Python solo gestiona la lógica de pipeline y el setup inicial.
2
HDA para reuso en equipo — El asset cultiva_neuro_v1.0.hda expone solo los parámetros relevantes con UI limpia; el equipo de motion lo usa sin conocer los internals del SOP/DOP.
3
PDG para batch de variaciones — Las 5 paletas no se renderizan manualmente; el grafo PDG paraleliza el render en farm y genera thumbnails y manifiesto automáticamente.
4
Atributos como canal de datos@emission, @variant, @pscale viajan por la red de nodos y el shader Redshift los lee como UserData, manteniendo la pipeline art-directable.
5
Simulación cacheada a disco — El POP Solver escribe a /cache/popnet_####.bgeo.sc antes del render; re-simular cuesta ~12min, el playback desde cache es instantáneo.
6
USD/Solaris para lookdev no-destructivo — Los overrides de material y luz se aplican en capas USD; cambiar un color de emisión no requiere tocar el SOP ni re-simular.