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ção | Hex | Notas |
|---|---|---|
| Papel (iluminado) | #f1e9d8 | Washi quente; nunca branco puro |
| Papel (sombra) | #e0d3ba | Vinheta, dobra de luz, manchado |
| Papel (profundo) | #cbbb9c | Apenas nas bordas do quadro ou em sombras de névoa |
| Tinta, força total | #14120f | Carbono quente; nunca #000 |
| Tinta, lavagem média | #5d5b57 | Ligeiramente frio contra papel quente |
| Tinta, lavagem pálida | #a9a69f | Montanhas distantes, nuvens difusas |
| Vermelhão | #c8372d | A única cor. No máximo uma marca, no máximo cerca de 1,5 por cento dos pixels |
| Vermelhão na névoa | #d7735f | Vermelhã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
#e0d3bamanté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
| Verbo | Caráter | Curva típica |
|---|---|---|
| Respirar (segurar) | Nada se move exceto luz ou névoa | 0,8 a 1,5 s de quietude antes do gesto |
| Cair / golpear | Decisivo, rápido, sem ultrapassagem | ease-in, 0,3 a 0,6 s |
| Desenhar | Pincel acelera depois libera | pressão lenta, meio rápido, levantamento leve |
| Florescer / difundir | Rápido depois desaceleração exponencial | 1 - exp(-t / tau), tau 1 a 2 s |
| Sangrar / assentar | Pequeno crescimento após o evento | sqrt do tempo desde o contato, limitado |
| Deriva | Câmera ou névoa, constante e lenta | linear ou ease muito longo, abaixo de 2 por cento do quadro por segundo |
| Dissolver | Contraste cai, bordas alargam | 2 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
qem 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 quandoTestiver 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++; };
}
DynamicsCompressorNodeaplica 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 detapenas; sem acúmulo,Date,performance.nowouMath.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 = 0apó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.