Communitygithub.com

lowpoly-shorts

Crie curtas-metragens verticais de 30-60 segundos no estilo low-poly PS1 (personagens CC0, faces pixeladas, aparência granulada, legendas com destaque na palavra, efeitos sonoros sincronizados, voz de IA) inteiramente em código com Blender, a custo zero de renderização.

O que é lowpoly-shorts?

Esta skill permite que desenvolvedores e usuários do Claude Code criem vídeos 3D curtos no estilo PS1 low-poly sem usar geradores de vídeo tradicionais. O Claude escreve um script Blender por curta, renderiza na máquina do usuário, analisa os frames, corrige e constrói o som e legendas. O processo completo é descrito em um pipeline de 10 etapas, desde a criação do roteiro até a mixagem final, com foco em eficiência e baixo custo (zero dólar para renderização). A skill é compatível com Blender 4.2+, Python 3.10+ e utiliza personagens gratuitos do Quaternius. Inclui um loop de visualização rápida que permite ao usuário deixar notas e solicitar correções, renderizando apenas as cenas alteradas. A saída final é um vídeo 1080x1920 com efeitos PS1, legendas sincronizadas e áudio otimizado, tudo executado localmente sem depender de serviços externos de vídeo.

Funciona com✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/mr-render/lowpoly-shorts/tree/HEAD

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Curtas PS1 Low-poly

Tudo é código: o Claude escreve um script Blender por curta, renderiza na máquina do usuário, analisa os frames, corrige, e então constrói o som e as legendas. Nenhum gerador de vídeo.

Comprovado em examples/lift-rocket/ ("E se elevadores fossem tão rápidos quanto foguetes?", 34 s). Leia esse exemplo antes de escrever uma nova curta: ele é o modelo.

Requisitos (verifique primeiro, instale o que estiver faltando)

  • Blender 4.2+ (testado na 5.3). Encontre-o: blender no PATH, senão C:\Program Files\Blender Foundation\<ver>\blender.exe / /Applications/Blender.app/Contents/MacOS/Blender.
  • Python 3.10+ com numpy pillow soundfile faster-whisper; ffmpeg no PATH.
  • Personagens: Quaternius "Ultimate Modular Men" (CC0, grátis, quaternius.com). Descompacte em assets/quaternius-modular-men/ ou defina LOWPOLY_PACK para a pasta Individual Characters/Blends.
  • Uma voz TTS (ElevenLabs ou qualquer ferramenta que o usuário tenha). Opcional: o MCP earshot para verificar o som.

O pipeline (uma pasta por curta, copie examples/lift-rocket/ como início)

#EtapaArquivo / comandoConcluído quando
1Roteiroscript.mdPergunta-gancho + cadeia de consequências, cada uma pior e mais engraçada + números reais + bordão seco. 60-110 palavras para 30-40 s. Cada número verificado com uma fonte e escrito na lista de Fatos.
2Vozvo/takeA.mp32 takes, escolha aquele com tempos de palavra limpos. Voz criativa energética, não calma (calmo = feedback "chato").
3Tempos das palavraspython ../../scripts/words.py vo/takeA.mp3takeA_words.json não tem palavras de comprimento zero.
4Lista de cenastabela em script.mdUma cena por frase da voz, uma nova imagem a cada 1-3 s, cada cena vinculada a um tempo de palavra.
5Cenabuild.py (Blender)blender -b -P build.py -- frames --still 30,120,... renderiza imagens fixas; veja cada imagem antes da renderização completa.
6Visualização + notaspython ../../scripts/preview.py . render depois serveO usuário não tem notas em aberto (veja o loop de Visualização).
7Renderizaçãoblender -b -P build.py -- framesPNGs 360x640 EEVEE, f_0001.png...
8Sompython build_mix.pyEfeitos sonoros colocados nos quadros da imagem, voz por cima, fundo lo-fi, ducking. Gera mix_raw.wav + cues.json.
9Pós-processamentopython post.pyDither PS1, efeitos, legendas com destaque na palavra, chamadas de estatísticas -> out/ em 1080x1920.
10Multiplexaçãoveja abaixoshort.mp4, depois meça e verifique a sincronização.

Regra de quadro em todos os lugares: 24 fps, quadro 1 = t 0, F = lambda t: int(round(t * 24)) + 1.

Multiplexação:

ffmpeg -y -framerate 24 -i out/f_%04d.png -i mix_raw.wav -c:v libx264 -crf 16 -pix_fmt yuv420p \
  -af "loudnorm=I=-15:TP=-1.5:LRA=11,aresample=48000" -c:a aac -b:a 192k -shortest short.mp4

Troque a voz depois sem recortar a imagem: python ../../scripts/words.py vo/takeB.mp3 depois python ../../scripts/align.py vo/takeA_words.json vo/takeB.mp3 --end 34 (--end = onde o fundo da voz para; saída é end + 2 s de duração. Sem ele: última palavra + 1,5 s, o que dá um arquivo mais curto que a imagem) -> takeB_aligned.wav + takeB_aligned_words.json. Aponte o build_mix.py (variável de ambiente VO) e o post.py para eles.

Loop de visualização (antes da renderização completa)

Visualização rápida em baixa resolução no navegador; o usuário deixa notas na linha do tempo; o Claude corrige e re-renderiza apenas as cenas cujo conteúdo mudou. Cenas = os marcadores de câmera em build.py.

FaçaComando (da pasta da curta)
Renderizar a visualizaçãopython ../../scripts/preview.py . render (primeira execução: cada cena; depois: apenas cenas alteradas)
Abrir a página de notaspython ../../scripts/preview.py . serve -> http://127.0.0.1:8765
Ler as notaspython ../../scripts/preview.py . notes (agrupadas por cena, com números de quadro)
Após corrigiredite build.py, execute render novamente, depois python ../../scripts/preview.py . done 3 5 --reply "o que você mudou"
Forçar cenasrender --shots c_press,c_slam ou render --all
  • build.py deve aceitar --blend-only (construir a cena, salvar, não renderizar). Veja o exemplo.
  • Detecção de mudança: cada quadro de visualização recebe uma impressão digital (câmera ativa, transformação de cada objeto visível, pose de armadura, trocas de rosto, materiais, luzes, dados de malha). Uma cena re-renderiza apenas se um de seus quadros mudou. Cenas inalteradas mantêm seus quadros antigos.
  • Configurações em preview.json (opcional): scale 50 (%), step 2 (a cada 2 quadros), samples 1, audio (padrão mix_raw.wav, senão a VO), final = os comandos completos do pipeline. O botão "Aprovar e renderizar final" da página executa-os; notes imprime APROVADO quando o usuário clicou.
  • Corrija as notas uma a uma, responda a cada uma, re-renderize e diga ao usuário para não atualizar nada: a página recarrega o vídeo sozinha. Notas repetidas do mesmo tipo se tornam uma regra neste arquivo.
  • Medido no lift-rocket (RTX 3070 Ti laptop, 820 quadros): primeira visualização 76 s, uma cena alterada 13 s, nada alterado 12 s. A maior parte do tempo de renderização de um quadro é sobrecarga fixa, então menor resolução ajuda menos do que renderizar menos quadros.

Kit API (scripts/lowpoly_kit.py, importar dentro do Blender)

  • load_character(scn, "Suit") -> (armature, meshes, actions). Personagens: Adventurer, Beach, Casual_2, Casual_Hoodie, Farmer, King, Punk, Spacesuit, Suit, Swat, Worker.
  • Ações (no lugar, 24): Death, HitRecieve, HitRecieve_2, Idle, Idle_Neutral, Interact, Kick_Left/Right, Punch_Left/Right, Roll, Run, Run_Back/Left/Right, Walk, Wave, Gun_Shoot, Idle_Gun*, Idle_Sword, Sword_Slash, Run_Shoot.
  • add_faces(scn, arm, head, tag, kinds, spec, drop) antes de mover a armadura. Tipos: neutral, blink, side, shock, grimace, squint, dazed, xeyes. drop deleta os olhos/sobrancelhas 3D do pacote.
  • show_faces(faces, [(frame, kind), ...]): cortes secos, cada rosto se mantém até o próximo.
  • nla(arm, [(action, start, end, blend[, influence]), ...]): entradas posteriores em trilhas mais altas.
  • drive_root(arm, [(frame, x, y, yaw, ease), ...], last): yaw 0 aponta para -Y (a câmera padrão).
  • new_cam, aim, yaw_to, ps1_render_settings(scn, outdir).
  • Cenários: scripts/set_lift_lobby.py (executar com BUILD_ONLY=True, retorna box, uv_world, mat). Novos cenários seguem o mesmo padrão: caixas com texturas pixeladas (interpolation = "Closest").

Regras de aparência

  • Renderizar 360x640, filter_size 0, AgX Punchy, sombreamento plano; pós: cor de 15 bits + dither Bayer, x3 nearest.
  • Rostos são decalques planos de 32x28 pixels trocados com cortes secos; nunca anime um rosto suavemente.
  • Achatar sob força usando chave na escala da armadura (z para baixo, xy para cima). Batidas de comédia: rápido para dentro (2-3 quadros), segurar.
  • Legendas: 1-3 palavras, sem serifa pesada, branca com contorno preto, palavra atual amarela, terço inferior (y 1300 de 1920).
  • Chamadas de estatísticas: caixa vermelha arredondada, terço superior, aparecer em 4 quadros, uma por número real.

Regras de som

  • Cada efeito sonoro é colocado para que seu pico caia no quadro da imagem (at(name, frame, db, peak=...)).
  • A voz deve ganhar: VO normalizada para 0 dBFS, barramento SFX -11 dB, música -7 dB, mais sidechain duck enquanto a voz fala (SFX -5 dB, música -9 dB). A v1 da curta do elevador tinha SFX a -3 e música a 0: "Não consigo ouvir a narração".
  • Corte a música no batida de parada grande, traga-a de volta depois. Silêncio vende a piada.
  • Master: loudnorm -15 LUFS, pico verdadeiro -1.5 dBTP.
  • Verifique: earshot timeline no mp4 vs cues.json (alvo: cada cue dentro de 100 ms), measure para LUFS.

Bugs já encontrados (não repita)

  • Malhas de pacotes são enviadas ocultas na renderização: hide_render = False (o kit faz isso).
  • Malhas de porta já estão em seu local fechado: anime apenas o deslocamento, ou elas fecham com uma lacuna de 0,7 m.
  • Um teto mais baixo que ~2,75 m esconde displays de parede da câmera dentro de um carro do tamanho de um elevador.
  • Um personagem que não deve ser visto ainda: chave location.z = -50 até sua cena.
  • Tomada única do NLA passando para uma segura: defina o blend_out = 0 do clipe ou a pose aparece por um quadro.
  • Cenas reversas ficam pretas (teto não iluminado): adicione uma luz frontal e um pouco de emissão no teto. Renderize o ângulo reverso cedo.
  • faster-whisper em mp3 pode quebrar com uma incompatibilidade PyAV: words.py decodifica com ffmpeg primeiro.
  • Uma frase começando em -0,04 s dá uma fatia vazia no alinhamento: fixe com max(0.0, ...) (feito).

Custo (curta do elevador, RTX 3070 Ti laptop)

Renderizar 820 quadros em 92 s, pós 17 s, $0. Personagens, SFX, música: $0 (CC0 + sintetizados em código). Voz: ElevenLabs cerca de $0,10 por take, 2 takes por curta.

Antes de entregar

  • Olhe para uma folha de contato dos quadros finais (a cada ~2 s), não apenas das imagens fixas.
  • Meça o volume, verifique a sincronização, verifique as legendas em relação ao texto da VO (correções ortográficas vão em post.py FIX).
  • Diga ao usuário o que foi medido e o que não foi ouvido por um humano.

Habilidades Relacionadas