LTX 2.3 - Cozy Felt
Stylized text-to-video generation using VRGameDevGirl84's LTX 2.3 LoRAs + Workflow, adapted to run on Comfy Cloud. Creates adorable felt worlds and characters.
About
LTX 2.3 - Cozy Felt is a stylized text-to-video workflow that wraps VRGameDevGirl84’s LTX 2.3 LoRAs around the LTX-2.3-22B-DISTILLED-1.1 model to generate short, adorable "felt" animations from a prompt. The core generation is driven by a custom LTX node (ID 45d6b185-beee-4467-b4c2-debdf835cb35) configured to load the LTX2 video VAE (LTX2_video_vae_bf16.safetensors) for latent-space video sampling. You pick a LoRA from a dropdown, include its trigger word in your prompt (for example, F3ltCut0u7 for the cozy felt look), and the node produces a sequence of stylized frames.
The MarkdownNote node embedded in the canvas provides quick instructions and lists the LoRA trigger words so you don’t have to leave the workspace.
After diffusion, frames are assembled into a playable clip with VHS_VideoCombine, where you set the frame rate and output format. This separation (generate frames first, then encode) makes iteration fast and predictable: you can tweak prompts, LoRA strength, seed, frame count, or resolution on the generation node, then re-run only the combine step to change FPS or container.
The result is a reliable, beginner-friendly pipeline for creating soft, craft-like animations—great for cozy title cards, character snippets, or looping social posts. Note: the audio VAE (LTX2_audio_vae_bf16.safetensors) is listed in the assets but is not wired into this canvas by default.
What you provide
- Reading the workflow
Runs in ComfyUI. This workflow can't run on this page. Open it in Comfy Cloud with everything loaded, or download it for your own ComfyUI.
Try in CloudInside the workflow
A read-only preview of the node graph. Open it in Comfy Cloud or download it to edit the nodes.
Loading the graph
Open full-size workflow preview- Author
- Purz
Requires custom nodes
- Reading the workflow
Use this workflow from code
Generated from the workflow graph and inputs when possible; stored examples are shown otherwise. Review credentials and endpoints before running code, which may incur charges.
What you need
- Runs on
- Comfy Cloud
- Key
- COMFY_API_KEY
Needs a paid Cloud plan and credits.
# Python 3.10+: pip install comfy-sdk==0.4.0
import os
from comfy_sdk import Comfy
api_key = os.environ.get("COMFY_API_KEY", "").strip()
if not api_key: raise RuntimeError("Set COMFY_API_KEY")
os.environ.setdefault("COMFY_BASE_URL", "https://cloud.comfy.org")
client = Comfy(api_key=api_key)
workflow = client.workflows.from_json({
"5265": {
"class_type": "VHS_VideoCombine",
"inputs": {
"audio": [
"5292:5232:5169",
0
],
"crf": 13,
"filename_prefix": "Cozy_Felt_Style_LoRA\\testing\\video",
"format": "video/h264-mp4",
"frame_rate": [
"5292:5296",
0
],
"images": [
"5292:5232:5185",
0
],
"loop_count": 0,
"pingpong": False,
"pix_fmt": "yuv420p",
"save_metadata": True,
"save_output": True,
"trim_to_audio": False
},
"_meta": {
"title": "Video Combine 🎥🅥🅗🅢"
}
},
"5292:5217": {
"class_type": "EmptyImage",
"inputs": {
"batch_size": 1,
"color": 0,
"height": 1080,
"width": 1920
},
"_meta": {
"title": "Empty Image"
}
},
"5292:5218": {
"class_type": "PrimitiveInt",
"inputs": {
"value": [
"5292:5293",
1
]
},
"_meta": {
"title": "length"
}
},
"5292:5223": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"5292:5289",
0
],
"text": "F3ltCut0u7, felt cutout style, a cute chubby French bulldog with big round eyes and tiny perked ears, mid-burrow under a patchwork felt quilt with only its head and front paws poking out, the quilt rumpled and lifted in the air from its movement, layered felt cutout shapes forming the bulldog's content wrinkled face mid-yawn with tongue curled, visible stitched seams along its body, soft fuzzy felt fibers, embroidered stars on the quilt bunching into folds, a plush felt teddy bear tumbling sideways from being nudged, tiny felt nightstand with a glowing lantern, crescent moon and stitched stars visible through a felt window, soft cinematic lighting with warm lamplight glow, gentle layered shadows, handcrafted miniature diorama, sleepy storybook mood\n"
},
"_meta": {
"title": "Enhanced Prompt (Positive)"
}
},
"5292:5224": {
"class_type": "LTXVConditioning",
"inputs": {
"frame_rate": [
"5292:5296",
0
],
"negative": [
"5292:5259",
0
],
"positive": [
"5292:5223",
0
]
},
"_meta": {
"title": "LTXVConditioning"
}
},
"5292:5230": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "LTX2.3_Cozy_Felt_Style.safetensors",
"model": [
"5292:5288",
0
],
"strength_model": 1
},
"_meta": {
"title": "Load LoRA"
}
},
"5292:5232:5150": {
"class_type": "KSamplerSelect",
"inputs": {
"sampler_name": "euler"
},
"_meta": {
"title": "KSamplerSelect"
}
},
"5292:5232:5151": {
"class_type": "CFGGuider",
"inputs": {
"cfg": 1,
"model": [
"5292:5230",
0
],
"negative": [
"5292:5224",
1
],
"positive": [
"5292:5224",
0
]
},
"_meta": {
"title": "CFG Guider"
}
},
"5292:5232:5152": {
"class_type": "KSamplerSelect",
"inputs": {
"sampler_name": "euler"
},
"_meta": {
"title": "KSamplerSelect"
}
},
"5292:5232:5154": {
"class_type": "RandomNoise",
"inputs": {
"noise_seed": 45
},
"_meta": {
"title": "RandomNoise"
}
},
"5292:5232:5155": {
"class_type": "SamplerCustomAdvanced",
"inputs": {
"guider": [
"5292:5232:5171",
0
],
"latent_image": [
"5292:5232:5160",
0
],
"noise": [
"5292:5232:5154",
0
],
"sampler": [
"5292:5232:5152",
0
],
"sigmas": [
"5292:5232:5183",
0
]
},
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"5292:5232:5156": {
"class_type": "LTXVSeparateAVLatent",
"inputs": {
"av_latent": [
"5292:5232:5155",
1
]
},
"_meta": {
"title": "Separate AV Latent"
}
},
"5292:5232:5158": {
"class_type": "RandomNoise",
"inputs": {
"noise_seed": 45
},
"_meta": {
"title": "RandomNoise"
}
},
"5292:5232:5159": {
"class_type": "SamplerCustomAdvanced",
"inputs": {
"guider": [
"5292:5232:5151",
0
],
"latent_image": [
"5292:5232:5162",
0
],
"noise": [
"5292:5232:5158",
0
],
"sampler": [
"5292:5232:5150",
0
],
"sigmas": [
"5292:5232:5182",
0
]
},
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"5292:5232:5160": {
"class_type": "LTXVConcatAVLatent",
"inputs": {
"audio_latent": [
"5292:5232:5167",
1
],
"video_latent": [
"5292:5232:5187",
0
]
},
"_meta": {
"title": "Concat AV Latent"
}
},
"5292:5232:5162": {
"class_type": "LTXVConcatAVLatent",
"inputs": {
"audio_latent": [
"5292:5232:5170",
0
],
"video_latent": [
"5292:5232:5163",
0
]
},
"_meta": {
"title": "Concat AV Latent"
}
},
"5292:5232:5163": {
"class_type": "EmptyLTXVLatentVideo",
"inputs": {
"batch_size": 1,
"height": [
"5292:5232:5165",
1
],
"length": [
"5292:5218",
0
],
"width": [
"5292:5232:5165",
0
]
},
"_meta": {
"title": "Empty LTXV Latent Video"
}
},
"5292:5232:5164": {
"class_type": "ImageScaleBy",
"inputs": {
"image": [
"5292:5217",
0
],
"scale_by": 0.5,
"upscale_method": "nearest-exact"
},
"_meta": {
"title": "Upscale Image By"
}
},
"5292:5232:5165": {
"class_type": "GetImageSize",
"inputs": {
"image": [
"5292:5232:5164",
0
]
},
"_meta": {
"title": "Get Image Size"
}
},
"5292:5232:5167": {
"class_type": "LTXVSeparateAVLatent",
"inputs": {
"av_latent": [
"5292:5232:5159",
1
]
},
"_meta": {
"title": "Separate AV Latent"
}
},
"5292:5232:5169": {
"class_type": "LTXVAudioVAEDecode",
"inputs": {
"audio_vae": [
"5292:5291",
0
],
"samples": [
"5292:5232:5156",
1
]
},
"_meta": {
"title": "LTXV Audio VAE Decode"
}
},
"5292:5232:5170": {
"class_type": "LTXVEmptyLatentAudio",
"inputs": {
"audio_vae": [
"5292:5291",
0
],
"batch_size": 1,
"frame_rate": [
"5292:5298",
0
],
"frames_number": [
"5292:5218",
0
]
},
"_meta": {
"title": "Empty LTXV Latent Audio"
}
},
"5292:5232:5171": {
"class_type": "CFGGuider",
"inputs": {
"cfg": 1,
"model": [
"5292:5230",
0
],
"negative": [
"5292:5224",
1
],
"positive": [
"5292:5224",
0
]
},
"_meta": {
"title": "CFG Guider"
}
},
"5292:5232:5182": {
"class_type": "ManualSigmas",
"inputs": {
"sigmas": "1., 0.99375, 0.9875, 0.98125, 0.975, 0.909375, 0.725, 0.421875, 0.0"
},
"_meta": {
"title": "ManualSigmas"
}
},
"5292:5232:5183": {
"class_type": "ManualSigmas",
"inputs": {
"sigmas": "0.909375, 0.725, 0.421875, 0.0"
},
"_meta": {
"title": "ManualSigmas"
}
},
"5292:5232:5185": {
"class_type": "LTXVSpatioTemporalTiledVAEDecode",
"inputs": {
"last_frame_fix": False,
"latents": [
"5292:5232:5156",
0
],
"spatial_overlap": 4,
"spatial_tiles": 4,
"temporal_overlap": 4,
"temporal_tile_length": 16,
"vae": [
"5292:5287",
0
],
"working_device": "auto",
"working_dtype": "auto"
},
"_meta": {
"title": "🅛🅣🅧 LTXV Spatio Temporal Tiled VAE Decode"
}
},
"5292:5232:5187": {
"class_type": "LTXVLatentUpsampler",
"inputs": {
"samples": [
"5292:5232:5167",
0
],
"upscale_model": [
"5292:5286",
0
],
"vae": [
"5292:5287",
0
]
},
"_meta": {
"title": "LTXVLatentUpsampler"
}
},
"5292:5259": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"5292:5289",
0
],
"text": "blurry, low resolution, jpeg artifacts, noisy, oversharpened, overexposed, underexposed, flat lighting, neon lighting, modern objects, vehicles, technology, urban elements, sci-fi elements, cartoon, anime, 3d render, cgi, photorealistic, plastic materials, game engine look, bad anatomy, extra limbs, fused fingers, duplicate characters, floating objects, text, watermark, logo, daylight, bright colors, cheerful mood, monsters, action pose, clean surfaces, polished stone, unrealistic reflections, low detail textures, smooth gradients, no brush strokes"
},
"_meta": {
"title": "Enhanced Prompt (Positive)"
}
},
"5292:5286": {
"class_type": "LatentUpscaleModelLoader",
"inputs": {
"model_name": "ltx-2.3-spatial-upscaler-x2-1.0.safetensors"
},
"_meta": {
"title": "Load Latent Upscale Model"
}
},
"5292:5287": {
"class_type": "VAELoaderKJ",
"inputs": {
"device": "main_device",
"vae_name": "LTX23_video_vae_bf16.safetensors",
"weight_dtype": "bf16"
},
"_meta": {
"title": "VAELoader KJ"
}
},
"5292:5288": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "ltx-2.3-22b-distilled-1.1.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"5292:5289": {
"class_type": "LTXAVTextEncoderLoader",
"inputs": {
"ckpt_name": "ltx-2.3-22b-dev-fp8.safetensors",
"device": "default",
"text_encoder": "gemma_3_12B_it.safetensors"
},
"_meta": {
"title": "Load LTXV Audio Text Encoder"
}
},
"5292:5290": {
"class_type": "VAELoaderKJ",
"inputs": {
"device": "main_device",
"vae_name": "LTX23_audio_vae_bf16.safetensors",
"weight_dtype": "bf16"
},
"_meta": {
"title": "VAELoader KJ"
}
},
"5292:5291": {
"class_type": "LTXVAudioVAELoader",
"inputs": {
"ckpt_name": "ltx-2.3-22b-distilled-fp8.safetensors"
},
"_meta": {
"title": "Load LTXV Audio VAE"
}
},
"5292:5293": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "a * b",
"values.a": [
"5292:5295",
0
],
"values.b": [
"5292:5296",
0
]
},
"_meta": {
"title": "Math Expression"
}
},
"5292:5295": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 5
},
"_meta": {
"title": "seconds"
}
},
"5292:5296": {
"class_type": "Float",
"inputs": {
"value": 25
},
"_meta": {
"title": "Float"
}
},
"5292:5298": {
"class_type": "JWFloatToInteger",
"inputs": {
"mode": "round",
"value": [
"5292:5296",
0
]
},
"_meta": {
"title": "Float to Integer"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)Questions & answers
Yes. Each LTX 2.3 LoRA has a trigger keyword (e.g., F3ltCut0u7) that activates its style. Include it in the positive prompt along with your subject for consistent results.
Keep prompts simple, use a fixed seed, avoid rapid camera moves, and limit clip length (e.g., 24–48 frames). Increasing steps can help detail, while moderate guidance/CFG avoids jittery overcorrection.
Place the base model (LTX-2.3-22B-DISTILLED-1.1-GGUF) and LTX2_video_vae_bf16.safetensors in the paths expected by the core LTX node. If the node reports a missing file, update its model and VAE fields to your actual paths. The audio VAE is not used by default.
Use VHS_VideoCombine. Re-run only that node and change the FPS or format; it will re-encode the existing frames into a new video without redoing diffusion.