Communitygithub.com

pisakhov/x-motion-sumi

Use com a skill principal x-motion quando um filme deve parecer e soar como pintura a nanquim em movimento (papel, tinta de carbono, água, névoa, respiração, um acento em vermelhão).

O que é x-motion-sumi?

Esta skill define a direção de arte e receitas técnicas para criar animações que emulam a estética da pintura a nanquim (sumi-ê) em movimento. Ela estende a skill `x-motion`, que deve ser executada primeiro para estabelecer tese, roteiro e storyboard. A proposta central é que um único gesto por batida pareça inevitável, com a tinta se comportando como tinta (difundindo, sangrando, secando) sobre um grande campo de papel silencioso. A skill fornece uma paleta de cores específica (com um único acento em vermelhão), receitas para composição de materiais (papel, tinta seca e molhada) e um vocabulário de movimento com curvas de animação típicas. Também inclui uma paleta sonora minimalista com instrumentos como flauta de sopro e cordas dedilhadas, e técnicas de síntese como Karplus-Strong e reverberação. As receitas técnicas cobrem implementações em GLSL para composição de tinta (usando Beer-Lambert), pinceladas como campos polares, paisagens em camadas de profundidade e advecção inversa para tinta na água. A skill enfatiza a renderização determinística, sem uso de Math.random ou Date, e com verificação de busca reversa para garantir que o mesmo frame gere pixels idênticos.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/pisakhov/x-motion/tree/HEAD/skills/x-motion-sumi

Perguntar na sua IA favorita

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

Documentação

X Motion: Sumi

Tinta, papel, respiração. Este tema traduz a lógica material da pintura a nanquim no tempo: tinta de carbono diluída em muitos cinzas, papel fibroso e quente, bordas molhadas que sangram, cerdas secas que pulam, e o vazio como material principal. Ele estende x-motion; execute esse método primeiro (breve, tese, storyboard, loop de crítica) e use este arquivo para a direção de arte e as receitas.

Tese visual

Faça um gesto de cada vez parecer inevitável através da tinta se comportando como tinta (difundindo, sangrando, secando) em um grande campo de papel silencioso, para que o espectador sinta a quietude antes e depois do momento decisivo.

  • Um gesto por batida. Uma gota, uma pincelada, uma crista, um pássaro. Nunca dois eventos focais ao mesmo tempo.
  • O vazio carrega peso. 60 a 80 por cento do quadro permanece como papel intocado, névoa ou água. O espaço vazio é composto, não sobra.
  • Verdade material sobre ilustração. A aparência vem de simular como a tinta absorve luz e o papel absorve tinta, não de contornos ou preenchimentos planos.
  • Respeito e originalidade. Sem caligrafia, pseudo-escrita, caracteres reais ou falsos, sem adereços de fantasia, templo ou lanterna, sem emblema de sol-vermelho-mais-garça. Os selos são marcas geométricas abstratas.

Paleta

Trabalhe em luz linear; estes são âncoras hex sRGB.

FunçãoHexNotas
Papel (iluminado)#f1e9d8Washi quente; nunca branco puro
Papel (sombra)#e0d3baVinheta, dobra de luz, manchado
Papel (profundo)#cbbb9cApenas nas bordas do quadro ou em sombras de névoa
Tinta, força total#14120fCarbono quente; nunca #000
Tinta, lavagem média#5d5b57Ligeiramente frio contra papel quente
Tinta, lavagem pálida#a9a69fMontanhas distantes, nuvens difusas
Vermelhão#c8372dA única cor. No máximo uma marca, no máximo cerca de 1,5 por cento dos pixels
Vermelhão na névoa#d7735fVermelhão misturado em direção ao papel pela atmosfera

A tinta não é uma cor que você pinta; é uma absorção. Componha com Beer-Lambert: rgb = papel * exp(-densidade * absorver), com absorver ligeiramente maior no azul (por exemplo vec3(1.0, 1.04, 1.1)) para que lavagens finas pareçam ligeiramente frias e tinta densa pareça preto quente.

Luz e material

  • Papel é iluminado suavemente de um lado: manchado de baixa frequência (mais ou menos 3 por cento), fibras kozo visíveis (fios translúcidos longos e finos, 1 a 2 px de largura), e um dente fino no qual a tinta seca se agarra. Cozinhe uma vez; é estático.
  • Tinta molhada tem uma borda mais escura onde o pigmento migrou para a borda, um sangramento difuso nas fibras, e um brilho fraco que desaparece à medida que seca.
  • Tinta seca se quebra em faixas paralelas de cerdas e pula os pontos baixos do papel (limiar o dente).
  • Tinta na água é um volume retroiluminado: núcleos densos, folhas laminares vistas de perfil como linhas escuras finas, e um véu suave ao redor de tudo.
  • Atmosfera é da cor do papel. Distância e névoa elevam os valores em direção ao papel, nunca em direção ao azul ou branco.

Composição

  • Coloque o sujeito em um terço assimétrico; deixe uma grande região calma (topo ou um lado) como contrapeso.
  • Mantenha uma hierarquia de valores clara: um preto quase puro, alguns cinzas médios, todo o resto papel.
  • As bordas do quadro permanecem quietas. Uma vinheta suave em direção a #e0d3ba mantém o olho dentro.
  • O acento vermelhão fica longe da massa principal, pequeno, baixo e tardio. Ele responde ao gesto; não compete.
  • Verifique a miniatura: a silhueta do único gesto deve ser legível com 320 px de largura.

Vocabulário de movimento e tempo

VerboCaráterCurva típica
Respirar (segurar)Nada se move exceto luz ou névoa0,8 a 1,5 s de quietude antes do gesto
Cair / golpearDecisivo, rápido, sem ultrapassagemease-in, 0,3 a 0,6 s
DesenharPincel acelera depois liberapressão lenta, meio rápido, levantamento leve
Florescer / difundirRápido depois desaceleração exponencial1 - exp(-t / tau), tau 1 a 2 s
Sangrar / assentarPequeno crescimento após o eventosqrt do tempo desde o contato, limitado
DerivaCâmera ou névoa, constante e lentalinear ou ease muito longo, abaixo de 2 por cento do quadro por segundo
DissolverContraste cai, bordas alargam2 a 3 s no final, nunca um corte para preto
  • Ritmo é respiração: quietude, um evento decisivo, um longo assentamento. Não preencha o assentamento com novos eventos.
  • A câmera se move apenas para seguir o gesto (afundando com a tinta, deslizando pela névoa). Zoom-ins ficam abaixo de 8 por cento.
  • Sementes e campos de ruído evoluem lentamente: deslocamentos de campo abaixo de 0,05 unidades por segundo, ou parecem fervilhantes.

Paleta sonora e mixagem

O som é tão esparso quanto a imagem. O silêncio é uma deixa.

  • Materiais: respiração (ruído filtrado por passa-banda com uma varredura de filtro lenta), água (um chirp senoidal crescente para uma gota, bolhas abafadas), papel e pincel (ruído filtrado por passa-banda com cliques esparsos de grãos que crescem à medida que o pincel seca), vento (dois leitos de ruído descorrelacionados com curvas de rajada semeadas).
  • Instrumentos: flauta de sopro final (seno mais um pouco de 2º e 3º harmônicos, pitch inclinado para cima a partir de baixo, ruído de respiração limitado à banda da nota), corda dedilhada (Karplus-Strong renderizado para um buffer, slide de pitch opcional após o dedilhado), gongo baixo (parciais inarmônicas com pares batendo, parciais baixas soam por mais tempo).
  • Harmonia: algumas notas com intervalos abertos (quartas, quintas, nonas). Evite riffs pentatônicos "orientais" de estoque; deixe notas individuais falarem.
  • Espaço: uma longa reverberação sintética (3 a 5 s, cauda escurecida, 20 a 40 ms de pré-retardo). Instrumentos molhados, texturas mais secas.
  • Sincronia: o som da gota encontra o impacto; a respiração lidera um gesto por 0,3 a 0,8 s; o gongo encontra o selo; notas melódicas seguem eventos visuais por 0,1 a 0,3 s.
  • Alvos: cerca de -18 LUFS integrados, pico verdadeiro em ou abaixo de -1,5 dBFS, cauda abaixo de -60 dBFS no último quadro, sem cliques (cada mudança de ganho aumenta por pelo menos 5 ms).

Receitas de técnica

1. Cozinhe ruído e papel uma vez. Envie uma textura RGBA16F tileable de 256x256: RG contém um campo de curl (o gradiente rotacionado de um ruído de gradiente periódico), BA contém dois ruídos independentes. Cozinhe o papel com JS semeado (grão mais pinceladas de fibra do Canvas 2D) em uma textura RGBA8 com mipmaps; amostre-a a cada quadro em vez de computar fbm por pixel.

2. Composição de tinta (luz linear).

vec3 lin(vec3 c){ return pow(c, vec3(2.2)); }
vec3 inkOver(vec3 paperLin, float density){
  return paperLin * exp(-density * vec3(3.4, 3.55, 3.75));
}

3. Tinta na água por advecção inversa. Não simule. Descreva a tinta como alguns primitivos analíticos (gota, caule, anel de vórtice, lóbulos de pétala) cujas posições são funções de forma fechada do tempo, depois avalie-os em uma coordenada distorcida. A distorção são alguns passos ao longo de um campo de curl com amplitude crescendo com o tempo desde o impacto, que estica primitivos em gavinhas encaracoladas.

vec2 q = p;
for (int i = 0; i < 4; i++) {
  vec2 c = texture(uNoise, q * freq[i] + drift * t).rg;   // campo de curl
  q += amp[i] * growth * c;
}
float dens = primitives(q, t);              // núcleos gaussianos + véu amplo
dens += sheet(q) * veil;                     // ruído estriado: folhas de perfil
  • Mantenha a distorção de baixa frequência (escala base 1 a 3 ciclos por altura do quadro, uma terceira oitava fraca). A distorção de alta frequência transforma tinta em vermes se contorcendo.
  • O enrolamento vem de um redemoinho local (gire q em torno de cada núcleo de vórtice por um ângulo que cai como uma gaussiana), não de mais ruído.
  • Pétalas, lóbulos e véus precisam de bordas suaves (gaussiana, largura 0,2 a 0,3 do raio). Linhas de contorno escuras e finas dentro de uma forma leem como um mapa topográfico.
  • Julgue a silhueta, não o detalhe: uma forma radial de cinco lóbulos vista de frente parece uma água-viva ou estrela-do-mar. Incline-a (projete lóbulos 3D para uma câmera olhando para baixo cerca de 30 graus) antes que pareça uma flor.
  • Um rastro que permanece fino, nítido e opaco parece uma corda ou caule. Trate-o como uma esteira: alargue-o, suavize-o, enrole-o e desbote-o dentro de cerca de um segundo, o topo primeiro, para que a forma fique sozinha.
  • Absorva os núcleos de tinta com um coeficiente quente (mais azul do que vermelho, por exemplo vec3(3.2, 3.6, 4.2)) e as bordas diluídas com um neutro. Então os núcleos leem como preto sumi, não cinza plano.

4. Pincelada como um campo polar. Para um ensō, use r(theta) = R + wobble(theta). Por pixel pegue o ângulo, converta-o para progresso da pincelada u e a distância sinalizada através da pincelada d / width(u). Revele onde u < brushHead(t). Umidade, largura e secura são funções de u; sangramento é uma função de t - timeTheBrushPassed(u).

float lanes = texture(uNoise, vec2(across * 5.0, u * 0.35)).b;   // faixas de cerdas
float dryInk = step(dryness(u), lanes * 0.6 + tooth * 0.5);         // pula papel baixo
float rim = smoothstep(0.75, 1.0, abs(across)) * wet(u);            // escurecimento de borda

5. Profundidade em camadas para paisagens. Cada crista é um perfil de altura 1D na profundidade z. Por pixel, projete para mundo x, procure a altura, compare com a tela y dessa altura sob perspectiva. A tinta é mais forte na linha da crista e cai para baixo na névoa. Componha de longe para perto, misturando em direção ao papel por 1 - exp(-profundidade * k). Folhas de névoa ficam nos vales entre as cristas e derivam com o tempo. Desbote uma crista quando a câmera está prestes a passar por ela.

  • Componha de perto para longe com transmitância (acc += T * a * camada; T *= 1.0 - a;) e pare quando T estiver quase zero. Isso é exato e reduz o custo pela metade porque o quadro inferior para após uma ou duas camadas.
  • Compute linhas de crista com ruído de gradiente 1D analítico (hash mais fade quíntico), não com consultas de textura: texels bilineares mostram como dobras ao longo de uma longa crista.
  • A atmosfera precisa de uma curva íngreme (exp(-0.45 * profundidade)) antes que o alcance mais distante seja lido como um fantasma pálido em vez de mais um cinza.

6. Silhuetas pequenas (um pássaro, um selo) como cápsulas e caixas SDF dentro de um teste de caixa delimitadora, com uma borda anti-aliased de 1,5 px. Anime as asas com uma função de fase, não com física.

7. Blocos de construção de áudio.

// Karplus-Strong dedilhado com glide opcional, renderizado deterministicamente para um buffer
for (let n = 0; n < len; n++) {
  const d = sr / freqAt(n) - 0.5, r = w - d;
  const a = read(r), b = read(r - 1);
  y = exc[n] + g * 0.5 * (a + b); write(y); out[n] = y;
}

Impulso de reverberação: ruído estéreo semeado vezes exp(-t / decay) através de um passa-baixa de um polo cuja frequência de corte cai com o tempo. Cadeia mestre: compressor suave (taxa 2 a 3), depois um compressor rápido de alta taxa como um limitador, depois um ganho de compensação medido, depois um fade mestre linear que atinge zero cerca de 0,15 s antes do fim para que a cauda da reverberação desapareça.

  • Mixagem bit-exata. O Chromium soma as entradas de um nó em uma ordem não especificada. A adição de float só dá os mesmos bits para dois operandos, e os compressores amplificam o arredondamento de 1e-7 em diferenças audíveis entre chamadas. Dê a cada ponto de mixagem no máximo duas entradas encadeando nós de ganho:
function summer(ctx, target) {        // retorna add(node); cada ponto de mixagem recebe <= 2 entradas
  let open = target, count = 0;
  return node => { if (count === 1) { const j = ctx.createGain(); j.connect(open); open = j; count = 0; } node.connect(open); count++; };
}
  • DynamicsCompressorNode aplica seu próprio ganho de compensação automático, então abaixar o limite torna a mixagem mais alta. Ajuste a sonoridade com o ganho de saída.
  • Verifique o equilíbrio dos stems: renderize uma vez sem a melodia. Se o leito sozinho estiver dentro de 2 dB da mixagem completa, a melodia está enterrada.

Lista de verificação de renderização determinística

  • renderFrame(t) define cada uniforme a partir de t apenas; sem acúmulo, Date, performance.now ou Math.random.
  • Toda aleatoriedade vem de um PRNG semeado (mulberry32) ou hashes de textura cozidos no carregamento.
  • Papel, ruído e IR são construídos sincronamente no carregamento e nunca mudam.
  • Busca reversa dá pixels idênticos; teste t = 0 após um quadro tardio.
  • Custo do quadro medido em 1920x1080 em WebGL de software; fique abaixo de 1,5 s. Use caixas delimitadoras para pequenos detalhes e mantenha loops de distorção em quatro passos.
  • Grão é estático, abaixo de 2 por cento; sem ruído de tela cheia por quadro.
  • Linhas e filamentos têm pelo menos uma queda suave de 1,5 px.
  • Áudio usa buffers de ruído semeados, e cada ponto de mixagem tem no máximo duas entradas; duas chamadas devem retornar buffers byte-idênticos.
  • Modo de visualização faz loop com requestAnimationFrame; modo de renderização não desenha nada por conta própria.

Evite

  • Papel branco puro, tinta preta pura, cor saturada além da única marca de vermelhão.
  • Traços semelhantes a script, caracteres, pseudo-caligrafia, assinaturas, adereços culturais de estoque.
  • Vários gestos competindo; fundos ocupados; tinta que se move constantemente na mesma velocidade.
  • Brilho, reflexos de lente, aberração cromática, bokeh; a tinta é fosca.
  • Desfoque uniforme fingindo ser difusão; a difusão real tem núcleos nítidos e véus suaves ao mesmo tempo.
  • Sinos de vento, sinos em cada corte, pads constantes, whooshes, riffs pentatônicos de estoque.
  • Terminar em um corte para preto; deixe a imagem assentar ou dissolver em papel ou cinza.

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

Habilidades Relacionadas