---
name: comfyui_build_weather_overlay_workflow
kind: function
lang: py
domain: ml
purity: pure
version: 1.0.0
signature: 'def comfyui_build_weather_overlay_workflow(weather: str, *, on_black: bool = True, style: str = "weather overlay, atmospheric", checkpoint: str = "IMG_dreamshaper_8.safetensors", width: int = 1024, height: int = 576, seed: int = 0, lora: str | None = None, lora_strength: float = 1.0, negative: str | None = None, steps: int = 28, cfg: float = 7.0, sampler_name: str = "dpmpp_2m", scheduler: str = "karras", filename_prefix: str = "weather_overlay") -> dict'
description: "Construye el dict (API format) del workflow de UN overlay de clima/atmosfera a PANTALLA COMPLETA: una capa que cubre toda la vista y se superpone sobre la escena con un blend mode del motor — lluvia, niebla, nieve, rayos de sol (god rays), polvo, viñeta de tormenta. Cobertura uniforme de borde a borde, generada APAISADA a resolucion de pantalla (16:9, 1024x576 por defecto). on_black=True (defecto) la pone sobre NEGRO puro con el clima brillante encima, para extraer alpha por luminancia con comfyui_matting_luma_to_alpha y blend additive/screen; on_black=False = pelicula translucida semi-transparente (niebla, tinte) para multiply/overlay o alpha global. NO inyecta Rembg (el matting de una capa es luma-to-alpha o alpha global, no un nodo). Compone comfyui_build_txt2img_workflow + comfyui_inject_lora. Hermano de comfyui_build_decal_overlay/particle_texture/vfx_spritesheet_workflow; distinto: capa de cobertura TOTAL, no mancha localizada ni secuencia animada. Pura, sin red ni I/O. class_types verificados contra /object_info."
uses_functions:
  - comfyui_build_txt2img_workflow_py_ml
  - comfyui_inject_lora_py_ml
uses_types: []
returns: []
returns_optional: false
error_type: ""
tags: [comfyui, ml, gamedev-2d, weather, overlay, atmosphere, rain, fog, snow, godrays, fullscreen, alpha, blend, luma, workflow]
tested: true
test_file_path: python/functions/ml/comfyui_build_weather_overlay_workflow_test.py
tests:
  - test_golden_weather_on_black_recipe
  - test_golden_landscape_dims_default
  - test_edge_on_black_toggles_layer_mode
  - test_edge_weather_reflected
  - test_edge_style_in_prompt
  - test_edge_dims_reflected
  - test_edge_negative_isolates_layer
  - test_edge_lora_reflected
  - test_error_empty_weather
  - test_determinism
file_path: python/functions/ml/comfyui_build_weather_overlay_workflow.py
imports: []
params:
  - name: weather
    desc: "Descripcion del clima/atmosfera a generar como capa (ej. 'heavy rain', 'thick fog', 'falling snow', 'god rays', 'sun shafts', 'dust haze', 'storm vignette', 'sandstorm', 'ash fall', 'blizzard'). Se inserta en un prompt scaffold de capa de cobertura total. No puede estar vacio."
  - name: on_black
    desc: "Si True (defecto) genera la capa sobre fondo NEGRO puro con el clima BRILLANTE encima (estrias de lluvia, copos, haces de luz, motas), pensada para luma->alpha con comfyui_matting_luma_to_alpha y blend additive/screen en el motor (el negro desaparece, el clima brilla sobre la escena). False = pelicula TRANSLUCIDA semi-transparente (niebla densa, tinte de tormenta, bruma) para blend multiply/overlay o alpha global. keyword-only."
  - name: style
    desc: "Descriptor de estilo de la capa (ej. 'weather overlay, atmospheric', 'stylized rain, painterly', 'photoreal fog', 'anime sun rays'). Pasa el MISMO style + checkpoint + lora a todas las capas de un set para coherencia visual. keyword-only."
  - name: checkpoint
    desc: "Checkpoint del servidor. 'IMG_dreamshaper_8.safetensors' (SD1.5, holgado en 8GB lowvram) por defecto; 'IMG_juggernaut_xl_v11.safetensors' para SDXL (mas VRAM, subir width/height a 1344x768). keyword-only."
  - name: width
    desc: "Ancho de la capa en px (multiplo de 8). 1024 por defecto (16:9 con height 576: resolucion de pantalla apaisada). keyword-only."
  - name: height
    desc: "Alto de la capa en px (multiplo de 8). 576 por defecto. keyword-only."
  - name: seed
    desc: "Semilla del KSampler. Misma seed + mismos weather/style -> misma capa; variar seed da variantes del mismo tipo de clima. keyword-only."
  - name: lora
    desc: "LoRA de estilo opcional en models/loras. None = sin LoRA. keyword-only."
  - name: lora_strength
    desc: "Fuerza del LoRA sobre model y clip. Se clampa a [0.0, 2.0]. keyword-only."
  - name: negative
    desc: "Prompt negativo. None usa el negativo por defecto pensado para una capa de cobertura total (sin sujeto/objeto/escena/horizonte/profundidad/marco que rompan la pelicula atmosferica) MAS, si on_black=True, el refuerzo de fondo negro plano. keyword-only."
  - name: steps
    desc: "Pasos del KSampler. keyword-only."
  - name: cfg
    desc: "CFG del KSampler. keyword-only."
  - name: sampler_name
    desc: "Sampler del KSampler. keyword-only."
  - name: scheduler
    desc: "Scheduler del KSampler. keyword-only."
  - name: filename_prefix
    desc: "Prefijo del PNG en output/. keyword-only."
output: "dict en API format listo para comfyui_submit_workflow: base txt2img apaisada (16:9) con prompt scaffold de capa de clima ('{weather} overlay, {style}, full screen atmospheric layer, <particles/streaks on pure black background | translucent layer>, seamless full screen coverage, edge to edge, game VFX, ...') + el negativo rechaza sujeto/objeto/escena/horizonte/profundidad/marco que romperian la pelicula de cobertura (y refuerza fondo negro plano cuando on_black=True) + LoRA de estilo opcional. NO lleva Rembg: con on_black=True el PNG resultante se convierte a RGBA con comfyui_matting_luma_to_alpha (luma=alpha) en un paso posterior para blend aditivo. UNA capa; variar seed da variantes del mismo clima."
---

Construye el dict (API format) del workflow de UN overlay de clima/atmosfera a
**pantalla completa**: una CAPA que cubre TODA la vista del jugador y se superpone
sobre la escena del juego con un blend mode del motor — lluvia, niebla, nieve, rayos
de sol (god rays), polvo en suspension, viñeta de tormenta. No es un sujeto centrado
ni un efecto puntual: es una pelicula de cobertura uniforme de borde a borde, generada
APAISADA a resolucion de pantalla (16:9, 1024x576 por defecto). `on_black=True`
(defecto) la pone sobre NEGRO puro con el clima brillante encima, pensada para extraer
alpha por luminancia con `comfyui_matting_luma_to_alpha` y blendear additive/screen
(el negro desaparece, el clima brilla sobre la escena); `on_black=False` la genera como
pelicula translucida semi-transparente (niebla densa, tinte de tormenta) para blend
multiply/overlay o alpha global. NO inyecta Rembg (el matting de una capa es
luma-to-alpha o un alpha global, no un nodo). Compone `comfyui_build_txt2img_workflow`
+ `comfyui_inject_lora` (estilo opcional). Hermano de
`comfyui_build_decal_overlay_workflow` / `comfyui_build_particle_texture_workflow` /
`comfyui_build_vfx_spritesheet_workflow`. Pura, sin red ni I/O. class_types verificados
contra /object_info.

## Cuando usarla

Cuando necesites una CAPA de clima/atmosfera que cubra toda la pantalla y se superponga
sobre la escena del juego: lluvia cayendo sobre todo el nivel, niebla densa que tiñe la
vista, nieve, haces de luz volumetrica (god rays), polvo en suspension, un oscurecimiento
de bordes de tormenta. La capa se genera apaisada a resolucion de pantalla y se compone en
el motor con un blend mode (additive/screen para particulas brillantes sobre negro;
multiply/overlay o alpha global para una pelicula translucida).

Flujo tipico despues de generar:

1. `comfyui_build_weather_overlay_workflow("heavy rain", on_black=True)` -> dict.
2. `comfyui_submit_workflow` -> `comfyui_wait_result` -> `comfyui_fetch_output_image`
   (PNG de la capa de lluvia sobre negro).
3. `comfyui_matting_luma_to_alpha(png, gamma=..., black_point=...)` -> PNG RGBA donde la
   luminancia ES el alpha: estrias brillantes=opacas, negro=transparente. Blend additive
   en el motor encima de la escena.

Pasa el MISMO `style` + `checkpoint` + (`lora`) a todas las capas de un set de clima para
que combinen; varia `seed` para sacar variantes del mismo clima (varias capas de lluvia
distintas para alternar/loopear en el motor).

**Elige este builder y NO `comfyui_build_decal_overlay_workflow` ni
`comfyui_build_vfx_spritesheet_workflow` cuando** lo que quieres es una capa de cobertura
TOTAL de pantalla. Un decal es una mancha LOCALIZADA y recortable que se pega en un punto
de una superficie; un spritesheet es una SECUENCIA animada de N frames de UN efecto
puntual. El weather overlay es UNA pelicula estatica de cobertura full-screen que el motor
anima por scroll/loop/shader.

## Gotchas

- **on_black=True esta pensado para luma->alpha, no es opcional de adorno**: la capa se
  genera sobre NEGRO puro precisamente para que `comfyui_matting_luma_to_alpha` mapee la
  luminancia a alpha y conserve el falloff de las estrias/particulas (lluvia, nieve, haces
  de luz). Con additive/screen el negro desaparece y solo el clima brilla sobre la escena.
  Si extraes el alpha con un matting binario (rembg) pierdes el degradado. Para climas que
  OSCURECEN/tiñen toda la vista (niebla densa, tinte de tormenta) usa `on_black=False`
  (pelicula translucida) y blendea multiply/overlay o con un alpha global bajo.
- **NO inyecta Rembg a proposito**: a diferencia de los builders de sprite/prop/item, este
  NO lleva 'Image Rembg (Remove Background)'. El SaveImage toma directo del VAEDecode (capa
  sobre fondo uniforme) y el matting es un paso posterior de disco o un alpha del motor.
- **Es una funcion pura**: solo arma el dict. La generacion real (GPU) la hacen
  `comfyui_submit_workflow` + `comfyui_wait_result` + `comfyui_fetch_output_image`; el alpha
  lo hace `comfyui_matting_luma_to_alpha`.
- **La capa debe quedar de COBERTURA TOTAL, no un sujeto centrado**: si el modelo mete una
  escena/objeto/personaje/horizonte, deja de ser una pelicula de cobertura y rompe el blend.
  El positivo fuerza "full screen atmospheric layer, seamless full screen coverage, edge to
  edge, uniform across frame" y el negativo rechaza "solid object, single subject, character,
  building, landscape scene, horizon line, depth, frame, border". Si aun sale un sujeto, sube
  `cfg` o reroll de `seed`.
- **on_black con cielo de fondo**: con SD1.5 algunos climas (lluvia, niebla) tienden a pintar
  un cielo azul/gris de fondo aunque pidas negro, lo que arruina el luma->alpha. El negativo
  por defecto (cuando on_black=True) rechaza "blue sky background, gray/white background,
  background scenery". Si aun sale fondo no-negro, sube `cfg` y haz reroll de `seed`; los
  climas mas brillantes-sobre-negro (god rays, snow, sparks) salen mas limpios que los
  difusos (fog).
- **luma->alpha penaliza colores oscuros/saturados**: la luminancia Rec601 pesa poco el azul
  (0.114). Una capa de lluvia AZULADA sobre negro sale semi-transparente con los pesos por
  defecto. Para subir opacidad ajusta `luma_weights`/`gamma` en `comfyui_matting_luma_to_alpha`
  (es ajuste del paso de matting, no del builder). Para clima blanco/brillante (nieve, haces
  de luz, polvo claro) los pesos por defecto van perfectos.
- **Apaisado 16:9, no cuadrado**: por defecto 1024x576 (resolucion de pantalla). Para 21:9 u
  otra relacion, ajusta width/height (multiplos de 8). En 8GB lowvram SD1.5 aguanta 1024x576
  holgado; si subes a SDXL (juggernaut_xl) ve a 1344x768 y vigila OOM (baja resolucion si peta).

## Ejemplo

```python
import sys, os
sys.path.insert(0, os.path.join(os.environ["HOME"], "fn_registry", "python", "functions"))
from ml.comfyui_build_weather_overlay_workflow import comfyui_build_weather_overlay_workflow

# Una capa de lluvia full-screen sobre negro, lista para submit + luma-to-alpha.
wf = comfyui_build_weather_overlay_workflow(
    "heavy rain",
    on_black=True,
    style="weather overlay, atmospheric",
    seed=7,
)
# Pipeline completo de una capa de clima con alpha:
#   r = comfyui_submit_workflow(wf); comfyui_wait_result(r["prompt_id"])
#   png = comfyui_fetch_output_image(...)            # capa de lluvia sobre negro
#   rgba = comfyui_matting_luma_to_alpha(png, gamma=1.2, black_point=0.05)  # luma=alpha
# Capa translucida (niebla que tiñe la vista, blend multiply):
#   wf = comfyui_build_weather_overlay_workflow("thick fog", on_black=False)
# Variantes del mismo clima para loopear en el motor: mismo weather/style, cambia seed.
#   for s in range(4):
#       wf = comfyui_build_weather_overlay_workflow("falling snow", seed=s)
```

O lanzable directo con: `./fn run comfyui_build_weather_overlay_workflow` (imprime nodos + class_types del ejemplo).
