Builder puro hermano de prop_object/structure: compone txt2img + inject_lora (estilo opcional) + Image Rembg (alpha). Scaffold '{plant}, {view} view, {style}, single plant element, centered, plain background, game nature asset'. Negativo rechaza manufacturado/edificio/persona/bosque/maceta para mantener UN elemento vegetal orgánico aislado.
13 tests offline verdes + generación real e2e (golden 'a glowing mushroom' seed 7, prompt_id 8fb65a51, RGBA recortable centrado). Dos gotchas reales SD1.5+Rembg documentados (planta grande->paisaje; follaje claro->Rembg come hojas) con evidencia en reports/0170.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
29 KiB
Capability group: gamedev / gamedev-2d — assets 2D para Godot (generación + post-proceso + puente)
Cluster de funciones para producir y mover assets 2D de juego entre ComfyUI (generación) y Godot 4 (consumo). Tres capas:
- Builders de workflow 2D (
gamedev-2d, GPU): construyen el dict (API format) de los workflows ComfyUI para pixel-art, tiles seamless, isométrico, sprites de personaje y VFX en bucle. Son puros (no tocan GPU al construir); el coste GPU está al enviar concomfyui_submit_workflow. - Post-proceso determinista (
gamedev, CPU): pixelizar, recortar a alpha. - Puente de assets (
gamedev, CPU): coloca el resultado en un proyecto Godot con sus import settings.
Tags: gamedev (post-proceso + puente) y gamedev-2d (builders de workflow).
Filtro: mcp__registry__fn_search query="" tag="gamedev-2d".
Documento hermano del grupo comfyui (generación genérica de imágenes/video/3D).
Diseño del puente: docs/comfyui-godot-integration.md. Planes origen: reports/0135
(pixelart), reports/0139 (entornos/tiles/iso), reports/0137 (personajes/sprites),
reports/0140 (VFX), reports/0143 (ronda 2b: builders), reports/0147 (item icons),
reports/0149 (parallax background).
Builders de workflow 2D (gamedev-2d, puros — generación)
Construyen el dict API format listo para comfyui_submit_workflow. Cada uno compone
funciones existentes del registry (comfyui_build_txt2img_workflow, comfyui_inject_*,
comfyui_build_ipadapter_workflow) — no reinventan el grafo. class_types verificados
contra /object_info del server (8GB lowvram). Probados e2e en GPU: pixelart, seamless,
VFX (ver reports/0143).
| ID | Firma corta | Qué hace |
|---|---|---|
comfyui_build_pixelart_workflow_py_ml |
(positive, negative=…, *, ckpt_name="juggernaut_xl_v11…", pixel_lora="pixel-art-xl…", use_lcm=True, …) -> dict |
Fase 1 pixel-art: SDXL + LoRA pixel-art-xl (+ LCM 8 steps). El pixel-perfect es post (comfyui_pixelize_image). |
comfyui_build_seamless_tile_workflow_py_ml |
(positive, negative="", *, tiling="enable", copy_model="Make a copy", circular_vae=True, material_lora=None, …) -> dict |
Textura tileable: SeamlessTile (Conv2d circular) + CircularVAEDecode. Coste VRAM ≈0. |
comfyui_build_isometric_workflow_py_ml |
(positive, negative=…, *, iso_lora="isometric_game_assets_sd15…", grid_image=None, …) -> dict |
Asset iso 2:1: LoRA iso + ControlNet grid opcional. |
comfyui_build_sprite_sheet_workflow_py_ml |
(subject, *, ref_image=None, pose_skeleton=None, char_lora=None, transparent=True, …) -> dict |
UN sprite de personaje: IPAdapter-FaceID + LoRA + ControlNet OpenPose (Advanced, end<1) + Rembg. Varias poses → sheet. SD1.5. |
comfyui_build_vfx_spritesheet_workflow_py_ml |
(prompt, *, motion_model="mm_sd_v15_v2.ckpt", num_frames=16, closed_loop=True, lora=None, …) -> dict |
N frames AnimateDiff loop sobre negro (insumo de luma→alpha). 8GB: 16f@512² revienta, usar ≤8f@512² o bajar resolución. |
comfyui_build_item_icon_workflow_py_ml |
(item, *, style="game icon, clean, centered", checkpoint="dreamshaper_8…", size=512, transparent=True, lora=None, …) -> dict |
UN icono de item de inventario (espada/poción/anillo/libro/escudo): txt2img cuadrado + prompt scaffold de icono + LoRA estilo opcional + Rembg (alpha). Set coherente = mismo style/checkpoint/lora por item. SD1.5. |
comfyui_build_portrait_avatar_workflow_py_ml |
(character, *, style="character portrait", ref_face=None, checkpoint="dreamshaper_8…", size=512, facedetailer=True, lora=None, …) -> dict |
UN retrato/avatar de personaje (busto centrado, cara al espectador, fondo simple): txt2img + prompt scaffold de retrato + FaceDetailer (cara nítida) + LoRA estilo opcional; ref_face → IPAdapter-FaceID para rostro consistente entre retratos. Diálogo/perfil/selección. SD1.5. |
comfyui_build_emote_workflow_py_ml |
(character, expression, *, ref_face=None, style="character portrait", checkpoint="dreamshaper_8…", size=512, facedetailer=True, lora=None, …) -> dict |
UN emote/expresión facial del MISMO personaje (alegre/triste/enfadado/sorprendido/neutral…) para diálogo, retratos reactivos o emotes de chat: txt2img + prompt scaffold de emote (portrait of {character}, {expression} expression, emote, clean background) + FaceDetailer (conserva la expresión); ref_face → IPAdapter-FaceID para que varíe SOLO la expresión y el rostro sea el mismo. UNA expresión por llamada; set = mismas claves variando expression → comfyui_build_grid. Probado e2e en GPU (reports/0151). SD1.5. |
comfyui_build_parallax_background_workflow_py_ml |
(scene, *, style="game background, side-scroller…", layers=3, checkpoint="dreamshaper_8…", depth_node="DepthAnythingV2Preprocessor", width=1024, height=512, …) -> dict |
Fondo en capas para parallax 2.5D: genera el fondo apaisado (txt2img) + su depth map (DepthAnythingV2Preprocessor sobre el VAEDecode), dos SaveImage. El split en N bandas por profundidad es post (GAP: split_parallax_layers, aún no creada). Probado e2e en GPU (reports/0149). SD1.5. |
comfyui_build_normal_map_workflow_py_ml |
(image, *, method="normal", strength=1.0, resolution=512, bg_threshold=0.1, filename_prefix="normal_map") -> dict |
Normal/depth map de un sprite existente para iluminación dinámica 2.5D (Godot CanvasItem normal_map, Unity sprite normal). LoadImage → preprocesador controlnet_aux → SaveImage. method: normal (default, BAE-NormalMapPreprocessor, normal canónico azul/violeta usable directo en motor), normal_midas (MiDaS, único con strength→a, paleta no canónica), normal_dsine (DSINE), depth (DepthAnythingV2, height en gris). image debe estar en input/ de ComfyUI. Coste VRAM ≈0. Probado e2e en GPU (reports/0150). |
comfyui_build_ui_hud_workflow_py_ml |
(element, *, ui_style="fantasy game UI", checkpoint="dreamshaper_8…", size=512, transparent=True, lora=None, …) -> dict |
UN elemento de interfaz/HUD de juego (botón, marco/panel, barra de vida/maná/XP, icono de UI, cursor, viñeta de menú): txt2img cuadrado + prompt scaffold de UI ({element}, {ui_style}, game UI element, centered, clean, plain background…) + LoRA estilo opcional + Rembg (alpha). HUD coherente = mismo ui_style/checkpoint/lora por pieza, varía solo element. El texto/label lo pone el motor (negativo empuja a no text). Probado e2e en GPU (reports/0152). SD1.5. |
comfyui_build_status_effect_icon_workflow_py_ml |
(effect, *, ui_style="game status icon, bold symbol, flat", checkpoint="dreamshaper_8…", size=256, transparent=True, seed=0, lora=None, …) -> dict |
UN icono de estado / buff-debuff (veneno, quemadura, congelación, escudo, regeneración, aturdimiento, velocidad, sangrado, maldición): símbolo compacto que se superpone al HUD para indicar un efecto activo, optimizado para legibilidad a tamaño reducido (16-32 px) → {effect} status effect icon, {ui_style}, simple bold symbol, centered, readable at small size, plain background… + LoRA estilo opcional + Rembg (alpha). size por defecto menor (256, no 512) porque se muestra pequeño; el negativo rechaza intricate details/complex/cluttered para no perder legibilidad. DISTINTO de item_icon (objeto de inventario) y ui_hud (chrome grande de interfaz): aquí es un símbolo de estado. Barra coherente = mismo ui_style/checkpoint/lora, varía solo effect (color habla del tipo). El texto/contador lo pone el motor (negativo empuja a no text). Probado e2e en GPU con SD1.5 — poison 256×256 RGBA, símbolo verde flat centrado (reports/0162). SD1.5. |
comfyui_build_card_art_workflow_py_ml |
(subject, *, card_style="fantasy trading card art", checkpoint="juggernaut_xl_v11…", width=512, height=768, hires=True, seed=0, lora=None, …) -> dict |
LA ilustración central de UNA carta coleccionable (TCG): criatura/personaje/hechizo en formato vertical de carta (width<height, ~512×768), composición centrada + iluminación dramática ({subject}, {card_style}, dramatic lighting, detailed illustration, centered composition, full art…). hires=True → 2ª pasada de detalle (comfyui_build_hires_fix_workflow); si no, txt2img + LoRA estilo opcional. Genera SOLO la ilustración — el marco/título/stats los pone el motor/post (negativo rechaza card frame/border/text/stats/UI). Set coherente = mismo card_style/checkpoint/lora, varía solo subject. Probado e2e en GPU con SD1.5 (reports/0153); ⚠️ el path hires=True falla hoy por bug del builder comfyui_build_hires_fix_workflow (nodo UltimateSDUpscale pide batch_size) — usar hires=False hasta el fix. SD1.5/SDXL. |
comfyui_build_enemy_creature_workflow_py_ml |
(creature, *, variant=None, style="game creature, full body", checkpoint="dreamshaper_8…", size=512, transparent=True, seed=0, lora=None, …) -> dict |
UN enemigo/criatura de juego (goblin, esqueleto, slime, dragón, boss, elemental): figura de cuerpo entero centrada, fondo limpio recortable a alpha ({variant} {creature}, {style}, full body, centered, plain background, game asset…) → txt2img cuadrado + LoRA estilo opcional + Rembg (alpha). variant (ice/fire/elite/corrupted…) se antepone a la criatura para generar la familia del MISMO enemigo (misma creature/seed/style, varía solo variant); bestiario coherente = mismo style/checkpoint/lora, varía solo creature. El negativo empuja a UNA criatura entera sin recorte. Probado e2e en GPU con SD1.5 (reports/0154). SD1.5. |
comfyui_build_prop_object_workflow_py_ml |
(prop, *, style="game prop, isometric or side view", checkpoint="dreamshaper_8…", size=512, transparent=True, seed=0, lora=None, …) -> dict |
UN prop/objeto de escenario (barril, cofre, antorcha, planta, mueble, roca, fuente, estatua): objeto inanimado aislado a escala de escena y perspectiva de juego (iso/lateral), centrado, fondo limpio recortable a alpha ({prop}, {style}, game asset, single object, centered, plain background, scene prop, world object…) → txt2img cuadrado + LoRA estilo opcional + Rembg (alpha). Objeto de MUNDO, no icono plano de inventario (≠ item_icon, que es para una casilla de UI); este puebla el nivel. Atrezzo coherente = mismo style/checkpoint/lora, varía solo prop. El negativo excluye personas/criaturas (objeto inanimado). Probado e2e en GPU con SD1.5 (reports/0155). SD1.5. |
comfyui_build_vehicle_mount_workflow_py_ml |
(vehicle, *, view="side", style="game vehicle", checkpoint="dreamshaper_8…", size=512, transparent=True, seed=0, lora=None, …) -> dict |
UN vehículo/montura que el personaje USA o CONDUCE (caballo, dragón-montura, nave espacial, coche, barco, carro, grifo, mecha): el vehículo COMPLETO en vista lateral o isométrica, centrado, fondo limpio recortable a alpha, SIN jinete/conductor ({vehicle}, {view} view, {style}, full vehicle, centered, plain background, game asset, no rider, empty…) → txt2img cuadrado + LoRA estilo opcional + Rembg (alpha). Se genera VACÍO (el negativo rechaza person/rider/driver/passenger) para que el motor componga al personaje encima. DISTINTO de enemy_creature (sujeto a COMBATIR) y prop_object (atrezzo inanimado que decora): aquí el objeto se MONTA/USA; una montura viva que se cabalga (caballo, dragón) entra aquí, no en enemy_creature. view (side/iso) fija la geometría del parque móvil; set coherente = mismo view/style/checkpoint/lora, varía solo vehicle. Probado e2e en GPU con SD1.5 — armored war horse with saddle side 512×512 RGBA, vehículo centrado recortado a alpha (centroide 0.55/0.54, 4 esquinas transparentes, reports/0169). SD1.5. |
comfyui_build_topdown_sprite_workflow_py_ml |
(subject, *, direction="south", style="top-down game sprite, RPG", checkpoint="dreamshaper_8…", size=512, transparent=True, seed=0, lora=None, …) -> dict |
UN sprite en vista CENITAL (top-down) estilo RPG clásico/roguelike (Zelda, juegos cenitales): personaje/objeto visto desde arriba, centrado, fondo limpio recortable a alpha ({subject}, top-down view, overhead view, {direction} facing, {style}, centered, plain background, game asset…) → txt2img cuadrado + LoRA estilo opcional + Rembg (alpha). direction (south/north/east/west) para el sprite de movimiento: las 4 vistas del MISMO personaje = misma subject/style/seed, varía solo direction → montar con comfyui_build_grid. DISTINTO de sprite_sheet (vista lateral/frontal de plataformas): el negativo por defecto rechaza side/front/3-4/isometric/perspective para forzar la cenital. Con SD1.5 sin LoRA sale picado alto; cenital estricto pide LoRA top-down + cfg alto. Probado e2e en GPU con SD1.5 (reports/0156). SD1.5. |
comfyui_build_splash_art_workflow_py_ml |
(scene, *, mood="epic, cinematic", checkpoint="juggernaut_xl_v11…", width=1024, height=576, hires=True, seed=0, lora=None, …) -> dict |
LA ilustración grande de UN splash / pantalla de carga / key art en formato pantalla apaisado 16:9 (width>height, ~1024×576), composición cinematográfica ({scene}, {mood}, key art, game splash screen, dramatic lighting, cinematic composition, wide shot, epic scale, atmospheric…). hires=True → 2ª pasada de detalle (comfyui_build_hires_fix_workflow) para verse a pantalla completa; si no, txt2img + LoRA estilo opcional. Genera SOLO la ilustración — el título/logo/barra de carga los pone el motor/post (negativo rechaza text/title/logo/UI/frame/watermark), dejando aire para superponer el título. Set coherente = mismo mood/checkpoint/lora, varía solo scene. Probado e2e en GPU con SD1.5 + hires (1024×576 → 1536×864, 54s, reports/0159). SD1.5/SDXL. |
comfyui_build_world_map_workflow_py_ml |
(region, *, map_style="fantasy cartography, aged parchment", checkpoint="juggernaut_xl_v11…", width=768, height=768, hires=False, seed=0, lora=None, …) -> dict |
LA ilustración de la pantalla de mapa del juego: una lámina cartográfica en vista cenital de un continente/región/reino/mazmorra con aspecto de atlas fantasy (map of {region}, {map_style}, top-down cartographic view, illustrated game world map, labeled regions, decorative border, compass rose, fantasy atlas, no people…). Cuadrado por defecto (768×768; sube width para mundo apaisado, height para mazmorra en columna), hires=False por defecto (ponlo True para detalle fino de costas/relieve). Genera SOLO la ilustración — las marcas interactivas, los iconos pinchables, las rutas y el "estás aquí" los pone el motor SOBRE la lámina; la difusión dibuja labels/ornamentos DECORATIVOS pero NO garantiza ortografía ni posiciones usables como datos (el negativo rechaza photo/3d render/perspective/character/person para mantener la vista cenital plana). Atlas coherente = mismo map_style/checkpoint/lora, varía solo region. Probado e2e en GPU con SD1.5 — reino fantasy 768×768, lámina de pergamino con costas/montañas/regiones + borde ornamental + rosa de los vientos (prompt_id bf4861fc, reports/0167). SD1.5/SDXL. |
comfyui_build_decal_overlay_workflow_py_ml |
(decal, *, on_black=True, style="grunge decal, high detail", checkpoint="dreamshaper_8…", size=512, seed=0, lora=None, …) -> dict |
UN decal/overlay con alpha para superponer sobre superficies/paredes/sprites con blend mode del motor (sangre, grietas, suciedad, óxido, quemaduras, salpicaduras, arañazos, musgo): textura aislada sobre fondo PLANO ({decal}, {style}, single isolated decal, centered, on a solid pure black background, flat backdrop, sticker, no scenery, texture overlay, game asset…) → txt2img cuadrado + LoRA estilo opcional. on_black=True (defecto) pensado para extraer alpha con comfyui_matting_luma_to_alpha (luma=alpha, conserva el falloff de translúcidos — la técnica gamedev correcta, ≠ recorte binario). NO inyecta Rembg (el matting es luma→alpha de disco, no un nodo): el SaveImage sale directo del VAEDecode. Set coherente = mismo style/checkpoint/lora, varía solo decal/seed. ⚠️ "grunge" en style arrastra fondo gris en SD1.5 → para fondo negro plano usar un style sin connotación de fondo + reroll de seed; luma Rec601 penaliza el rojo → para sangre roja pasar luma_weights con más peso al rojo. Probado e2e en GPU con SD1.5 (reports/0160). SD1.5. |
comfyui_build_projectile_workflow_py_ml |
(projectile, *, direction="right", glow=False, style="game projectile, side view", checkpoint="dreamshaper_8…", size=512, transparent=True, seed=0, lora=None, …) -> dict |
UN proyectil orientado (flecha, bala, bola de fuego, rayo, misil, hechizo): sprite pequeño con orientación (apunta a la derecha por defecto, ángulo 0 — el motor rota el sprite), aislado, listo para instanciar. glow elige el camino a alpha: glow=False (defecto) = proyectil SÓLIDO con silueta → plain background + Rembg (alpha por recorte, como item_icon/topdown_sprite); glow=True = brillante/mágico → glowing, on black background sin Rembg (recortaría el halo), insumo de comfyui_matting_luma_to_alpha que el caller aplica luego (como vfx_spritesheet/decal_overlay). glow=True ignora transparent/rembg_model; el negativo por defecto NO rechaza "black background". direction se inserta como pointing {direction} (""/None = sin orientación). Set coherente = mismo style/checkpoint/lora, varía solo projectile/seed. Probado e2e en GPU con SD1.5 — fireball glow sobre negro + luma→alpha RGBA (reports/0161). SD1.5. |
comfyui_build_structure_workflow_py_ml |
(structure, *, view="isometric", style="game building", checkpoint="dreamshaper_8…", size=512, transparent=True, seed=0, lora=None, …) -> dict |
UN edificio/estructura de escenario (casa, torre, castillo, tienda, posada, ruina, muralla, puente, templo, faro): UN building COMPLETO y centrado a perspectiva de juego ({view} view, iso por defecto), fondo limpio recortable a alpha ({structure}, {view} view, {style}, full building, complete structure, single building, centered, plain background, game asset, architecture…) → txt2img cuadrado + LoRA estilo/iso opcional + Rembg (alpha). EDIFICACIÓN grande que ocupa varios tiles y define el escenario, no un objeto pequeño suelto (≠ prop_object, que es atrezzo que se deja sobre un tile); el negativo rechaza small object / single item / prop / furniture. view fija la perspectiva del mapa (iso/side/front/top-down/¾); LoRA iso fija mejor el ángulo 2:1. Set coherente = mismo view/style/checkpoint/lora, varía solo structure. Probado e2e en GPU con SD1.5 — medieval blacksmith shop iso 512×512 RGBA, edificio centrado recortado a alpha (centroide 0.54/0.53, reports/0164). SD1.5. |
comfyui_build_foliage_set_workflow_py_ml |
(plant, *, view="side", style="game foliage, stylized", checkpoint="dreamshaper_8…", size=512, transparent=True, seed=0, lora=None, …) -> dict |
UN elemento de vegetación/foliage de escenario (árbol, arbusto, hierba alta, flores, helecho, hongo, cactus, tronco caído, juncos, hiedra): UN elemento de naturaleza ORGÁNICA AISLADO y centrado a perspectiva de juego ({view} view, side por defecto), fondo limpio recortable a alpha ({plant}, {view} view, {style}, single plant element, centered, plain background, game nature asset, natural vegetation, organic, isolated plant…) → txt2img cuadrado + LoRA estilo opcional + Rembg (alpha). Vegetación que viste el terreno, distinta del objeto MANUFACTURADO suelto (≠ prop_object: barril/cofre/mueble) y del EDIFICIO (≠ structure: casa/torre); el negativo rechaza building / manmade object / barrel / furniture / person y multiple plants / dense forest / jungle / landscape (UN elemento, no un bosque) + pot / planter / vase (planta en maceta = prop_object). Recorte por Rembg (planta opaca de silueta definida), no luma→alpha. Set coherente = mismo view/style/checkpoint/lora, varía solo plant. ⚠️ dos gotchas reales SD1.5+Rembg: (1) plantas grandes (árbol) tienden a PAISAJE (cielo+campo) en lugar de fondo plano → re-roll de seeds buscando fondo uniforme (comfyui_batch_generate); (2) follaje verde claro sobre fondo claro → Rembg se come las hojas y deja solo tronco/ramas → preferir elementos de silueta compacta y color saturado (hongo, arbusto denso) o transparent=False + matting manual. Probado e2e en GPU con SD1.5 — golden a glowing mushroom seed 7 512×512 RGBA, hongo centrado recortado a alpha limpio (centroide 0.51/0.58, opaco 19%, prompt_id 8fb65a51); evidencia del gotcha del roble en reports/0170. SD1.5. |
comfyui_build_particle_texture_workflow_py_ml |
(particle, *, soft=True, style="particle texture, soft glow", checkpoint="dreamshaper_8…", size=256, seed=0, lora=None, …) -> dict |
UNA textura de partícula individual reutilizable (chispa, humo, polvo, destello/flare, gota, copo, hoja, círculo de energía) — el "ladrillo" que el sistema de partículas del motor (Godot GPUParticles2D, Unity VFX Graph) instancia a miles y anima (spawn/fade/color over lifetime). Aislada y centrada sobre fondo NEGRO (`{particle} particle, {style}, isolated on pure black background, <soft |
comfyui_build_title_lettering_workflow_py_ml |
(text, *, letter_style="epic fantasy metallic", checkpoint="juggernaut_xl_v11…", width=1024, height=512, transparent=True, seed=0, lora=None, …) -> dict |
EL texto/logo de título de un juego (el nombre del juego o una palabra) renderizado con un tratamiento de lettering (metálico, tallado en fuego/piedra/madera, neón, cristal, oro), formato apaisado (width>height, 1024×512 por defecto), fondo plano recortable a alpha (the word "{text}" as a game logo, {letter_style} lettering, stylized typography, centered, plain background…) → txt2img apaisado + LoRA estilo opcional + Rembg (alpha). El negativo NO rechaza texto (el lettering es el sujeto) y empuja contra el ruido textual (extra letters/jumbled text/deformed letters). El VALOR es el ESTILO del lettering, NO la fidelidad tipográfica: ⚠️ la difusión renderiza texto de forma imperfecta — letras de más, deformadas o mal escritas; mitigar con palabras CORTAS en MAYÚSCULA, re-roll de seeds (comfyui_batch_generate), SDXL > SD1.5 para texto, o pintar el texto real con una fuente en el motor. Una palabra que es un objeto concreto (DRAGON) → el modelo dibuja el objeto, no las letras — usar palabras abstractas o reforzar letter_style. Marca coherente = mismo letter_style/checkpoint/lora, varía solo text. Recorte por Rembg (logo sólido), no luma→alpha. Probado e2e en GPU: DRAGON/fire engraved SD1.5 1024×512 → ilustró dragones rojos (alpha OK, confirma el gotcha de palabra-objeto, prompt_id 6f3920b7); AETHER/epic fantasy metallic SDXL 768×384 → logo de texto metálico dorado legible con ortografía imperfecta + alpha (prompt_id 2a7fe8ba, reports/0165). SD1.5/SDXL. |
Funciones de post-proceso y puente (gamedev, CPU)
| ID | Firma corta | Qué hace |
|---|---|---|
comfyui_pixelize_image_py_ml |
(src, dst, *, downscale=8, colors=16, palette=None, dither=False, upscale_back=True) -> dict |
Pixel-perfect: downscale nearest + cuantización a N colores o paleta fija (game-boy/pico-8/nes). Fase 2 pixelart. Impura (I/O). |
comfyui_matting_luma_to_alpha_py_ml |
(image_path, *, out_path=None, gamma=1.0, black_point=0.0, premultiply=False, luma_weights=(.299,.587,.114)) -> dict |
Frame VFX sobre negro -> RGBA usando luminancia como alpha (translúcidos con additive blend). Impura (I/O). |
comfyui_export_asset_to_godot_py_pipelines |
(asset_path, kind, godot_project, *, name=None, reimport=True, godot_bin=None) -> dict |
Copia el asset a res://assets/<dir>/ por kind + escribe .import + filtro Nearest si pixelart + reimport headless. Pipeline impuro. |
godot_map_asset_dir_py_core |
(kind) -> str |
Mapea kind -> subcarpeta de res://assets/. Pura. |
godot_clean_asset_name_py_core |
(filename, *, override=None) -> str |
Normaliza el nombre <prefijo>_NNNNN_.<ext> a snake_case seguro para res://. Pura. |
Ejemplo end-to-end con builder (Fase 1 GPU → Fase 2 CPU → Godot)
Flujo completo pixel-art: construir workflow → generar en ComfyUI → pixel-perfect → Godot.
import sys, os
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
from ml.comfyui_build_pixelart_workflow import comfyui_build_pixelart_workflow
from ml.comfyui_submit_workflow import comfyui_submit_workflow
from ml.comfyui_wait_result import comfyui_wait_result
from ml.comfyui_fetch_output_image import comfyui_fetch_output_image
from ml.comfyui_pixelize_image import comfyui_pixelize_image
# 1. Construir (puro) + 2. generar (GPU)
wf = comfyui_build_pixelart_workflow("isometric tiny house, pixel, 32x32 style", use_lcm=True, seed=42)
pid = comfyui_submit_workflow(wf)["prompt_id"]
outs = comfyui_wait_result(pid, timeout=300)
fn = next(img["filename"] for o in outs.values() for img in o.get("images", []))
raw = comfyui_fetch_output_image(fn, dest_dir="/tmp")["out_path"]
# 3. pixel-perfect (CPU) -> 4. export Godot (ver ejemplo de abajo)
px = comfyui_pixelize_image(raw, "/tmp/house_pixel.png", downscale=8, colors=16)
VFX: comfyui_build_vfx_spritesheet_workflow(prompt, num_frames=8) → submit → fetch N frames
→ comfyui_matting_luma_to_alpha por frame → montar sheet RGBA con Image.alpha_composite
(NO comfyui_build_grid, que aplana el alpha).
Ejemplo canónico de post-proceso
Flujo: crudo generado en ComfyUI -> pixelizar -> exportar a Godot con Nearest.
import sys, os
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
from ml.comfyui_pixelize_image import comfyui_pixelize_image
from ml.comfyui_matting_luma_to_alpha import comfyui_matting_luma_to_alpha
from pipelines.comfyui_export_asset_to_godot import comfyui_export_asset_to_godot
OUT = os.path.expanduser("~/ComfyUI/output")
PROJ = os.path.expanduser("~/gamedev/projects/crossy_road")
# 1. Pixelizar un sprite crudo (SDXL+pixel-art-xl) a 16 colores
px = comfyui_pixelize_image(f"{OUT}/hero_00001_.png", "/tmp/hero_pixel.png",
downscale=8, colors=16)
# 2. Exportarlo a Godot como pixelart (carpeta sprites/, filtro Nearest, reimport)
exp = comfyui_export_asset_to_godot("/tmp/hero_pixel.png", "pixelart", PROJ)
print(exp["dest_res_path"], exp["pixelart_filter_set"], exp["reimported"])
# Rama VFX: frame de humo sobre negro -> RGBA -> carpeta vfx/
rgba = comfyui_matting_luma_to_alpha(f"{OUT}/vfx_loop_00007_.png", gamma=1.2, black_point=0.04)
comfyui_export_asset_to_godot(rgba["out_path"], "vfx", PROJ)
Fronteras (qué NO cubre)
- Montaje de spritesheet dedicado (grid RGBA + JSON sidecar para Godot/Unity):
no hay función propia todavía — el ejemplo VFX monta con
Image.alpha_compositeinline.comfyui_build_gridNO sirve (aplana el alpha sobre fondo oscuro). Pendiente de R4 (planreports/0140F2). - Pipelines one-shot (build → submit → wait → fetch → post en una call) para pixelart/sprite/VFX: pendientes. Hoy se encadena a mano (ver ejemplos). Candidatos a promoción a pipeline (issue 0087) cuando el patrón se repita.
- Sprite turnaround multi-vista (orquestar N poses con identidad fija + juez):
el builder
comfyui_build_sprite_sheet_workflowproduce UN frame; la orquestación multi-pose es pipeline pendiente (planreports/0137T2). - Paletas lospec por red (
load_lospec_palette): no incluido.pixelizeusa paletas fijas embebidas (game-boy/pico-8/nes) o lista de hex, sin HTTP. - TileSet / SpriteFrames
.tres: Godot no los deriva solos;export_asset_to_godotcopia la textura y avisa, pero no genera el recurso (paso manual o futura función).
Prerequisitos / notas
- Godot CLI para el reimport headless: autodetectado en PATH y en
~/godot/Godot_v4.7-stable_linux.x86_64. Si falta,export_asset_to_godotdeja el.importescrito y lo anota (no falla). - Filtro Nearest (Godot 4): se setea global en
project.godot(default_texture_filter=0), no por.import. La función lo asegura para pixelart. - CPU-only: Pillow + numpy del venv del registry. Cero VRAM, cero red.