Faber / timeline

Forma: a cabeça e o corpo

O objetivo

Queremos gerar assets 3D para um jogo. Primeiro um gato (o jogo é sobre um gato numa floresta; Stray serve só de referência de qualidade e de jogabilidade, o nosso gato precisa ser original), depois variações desse gato e, mais tarde, props. E por "gerar" entendemos um programa nosso, rodando nesta máquina, sem depender do modelo de IA de ninguém, que produza muitos personagens diferentes com a mesma qualidade, prontos para o jogo (malha leve, texturas e esqueleto para animação).

Com o tempo, a pergunta central do projeto virou esta: como descrever "uma boa forma de gato" de um jeito que um programa consiga variar sem estragar?

Esta timeline conta como chegamos até aqui: o que tentamos, o que descobrimos, o que deu errado e por quê. Cada passo vem com as imagens que usamos para julgar o resultado.

Por que é difícil

Bom, por quatro motivos principais.

  • Forma boa tem muita informação. Um gato bem esculpido tem milhares de detalhes (pálpebras, focinho, orelhas). Descrever isso com poucos números perde quase tudo, e o resultado fica com cara de massinha.
  • Correspondência. Para misturar ou variar gatos, o programa precisa saber que "este ponto aqui é o canto do olho" em todos eles. Se os pontos escorregam, a mistura sai torta.
  • A textura conta metade do visual. Os modelos de exemplo parecem ótimos em grande parte por causa da pintura (pelagem, olhos). Argila cinza sempre parece pior.
  • Jogo exige leveza. Milhões de triângulos não rodam. O asset final precisa ser uma malha leve, com o detalhe guardado em texturas.
Claude

1Aprender com milhares de modelos

05/11, 15:56 a 19:42abandonado

Inspirado no Pixel Loom: decompor milhares de modelos livres (Objaverse) em peças simples e treinar um pequeno GPT para escrever assets peça por peça. Resultado: cerca de 24 horas de processamento por conjunto de dados, Mac quente e lento. Arquivado.

Claude

2Props e gatos de "bolhas" procedurais

05/11, 20:04 a 20:31deu errado

Geradores de props (barril, caixa, poção, lanterna, espada) em estilo fantasia e cyberpunk, a partir de superquádricas; gatos e pessoas feitos de bolhas misturadas. Resultado: props aceitáveis; gatos e pessoas "longe de bons".

props props, gatos e pessoas de bolhas (as quatro últimas linhas)

Superquádrica: uma família de formas descrita por uma fórmula só, |x/a|^n + |y/b|^n + |z/c|^n = 1. Com n = 2 é uma esfera ou um elipsoide; aumentando n ela vira uma caixa de cantos arredondados; abaixo de 2, uma forma pontuda, tipo octaedro. Com poucos números (os tamanhos a, b, c e o expoente n) ela faz barril, caixa, frasco ou lâmina. Os props são montados com várias delas, e por isso ficam bons: objetos feitos pelo homem são formas simples. Um gato não é.

Claude

3Cabeça anatômica feita de matemática

05/11, 20:44 a 22:31

A cabeça do gato como uma função de distância (SDF): elipsoides e cápsulas somados e esculpidos (massa do crânio, focinho, órbitas, pálpebras), olhos reais renderizados no Cycles. Resultado: limpa, mas proporções chutadas: parecia um bicho de pelúcia.

cabeça feita à mão

O que é uma função de distância (SDF, "signed distance function"). Em vez de guardar a forma como uma malha (uma lista de triângulos), guardamos uma função matemática: para qualquer ponto do espaço ela responde a que distância esse ponto está da superfície, com sinal. Negativa dentro do objeto, positiva fora, zero exatamente na pele. Exemplos:

  • Esfera de centro c e raio r: distância(p) = |p - c| - r. No centro dá -r (dentro), na superfície dá 0, longe dá um número positivo.
  • Juntar duas formas (união): o menor dos dois valores, min(a, b). Um ponto está dentro da união se está dentro de qualquer uma.
  • Esculpir (subtrair B de A): max(a, -b). É assim que abrimos as órbitas e a linha da boca.
  • Mistura suave ("smooth min"): em vez de um canto vivo onde duas formas se encontram, uma transição arredondada de largura k, como argila alisada com o dedo. Foi o que deu o aspecto limpo da cabeça.

Para ver a forma, o programa testa a função numa grade fina de pontos e acha onde ela vale zero ("marching cubes"); isso vira uma malha de triângulos que o Blender renderiza. Por que saiu tão limpa: a superfície é definida em todo lugar pela matemática, então não existe buraco, dobra ou triângulo virado; cada detalhe é uma peça nossa, com nome. Por que parecia pelúcia: as peças são formas suaves e convexas (elipsoides, cápsulas), e a mistura suave arredonda tudo; osso, pálpebra e focinho de verdade têm planos, quinas e vincos que essas peças não fazem (medimos isso no passo 5). A SDF continua no código (faber/sdf.py, faber/cat_head.py).

Cycles: o motor de renderização "realista" do Blender. Ele simula raios de luz saindo da câmera e quicando nas superfícies até chegar às luzes (path tracing), por isso sombras, reflexos e o brilho da córnea saem naturais, mas leva segundos ou minutos por imagem. Usamos o Cycles nos renders desta cabeça, com olhos reais. As folhas de comparação usam o Eevee, o outro motor do Blender, que desenha como um jogo (muito mais rápido, menos fiel).

Claude

4Medir contra gatos reais

05/11 22:48 a 06/11 08:09

Modelos livres de gatos (uma Sphynx e outros) extraídos (número de enrolamento), alinhados por pontos de referência (nariz, olhos, orelhas; Procrustes) e comparados por silhueta e distância de superfície; os 25 números da cabeça ajustados por gradiente. A cabeça ficou mais perto dos gatos, mas a Sphynx é uma raça de orelhas enormes, e o alinhamento pelas orelhas deixava a cara inclinada 18 graus.

antes e depois do ajuste

As técnicas que entraram aqui:

  • Número de enrolamento (winding number), para extrair a cabeça dos modelos. Responde "este ponto está dentro ou fora do objeto?". Imagine-se de pé no ponto, olhando em todas as direções, e conte quanto do seu campo de visão é coberto pela superfície do objeto. Dentro de uma superfície fechada ela te envolve inteira: o número dá 1. Fora, as partes se cancelam: dá 0. O nome vem de quantas vezes a superfície "se enrola" em volta do ponto. A versão generalizada funciona até em malhas com buracos e peças soltas, comuns em modelos baixados: perto de um buraco dá algo como 0,5, e cortamos ali. Com isso a cabeça de cada modelo vira uma superfície limpa e fechada (tools/ref_head.py).
  • Procrustes, para alinhar. Um jeito de sobrepor dois conjuntos de pontos correspondentes (nariz, olhos, pontas das orelhas de dois gatos) achando a rotação, a escala e a translação que deixam um o mais perto possível do outro, sem deformar. O nome vem do mito grego de Procusto, que esticava ou cortava os hóspedes para caberem na cama. A conta é uma decomposição de matriz (SVD) e é exata, sem tentativa e erro.
  • Três réguas para comparar formas: silhueta (o contorno de frente, de lado e de cima), distância entre as superfícies e, mais tarde, sobreposição de volume. Cada uma enxerga coisas que as outras não veem; nenhuma enxerga os olhos.
  • Ajuste por gradiente: o computador mexe nos 25 números da cabeça aos pouquinhos, sempre na direção que diminui a diferença para as referências.

Lição: alinhar pela média das superfícies colocava a cabeça em orientações erradas (uma cabeça inclinada para trás "pontua" quase igual a uma olhando para a frente). Por isso alinhamos por pontos de referência e sempre olhamos a imagem antes de confiar num número.

Rafael

The after is looking promissing, lets finer anatomy.

Rafael
Desvio: passos 5 a 7

Deu errado. Saímos da cabeça do passo 4 para reconstruir a anatomia (crânio, músculo, pele) e depois para um gerador de variações a partir de gatos prontos. As variações chegaram a funcionar, mas a forma de base não: no passo 7 o veredito foi "resultados horríveis", e no passo 8 voltamos à cabeça do passo 4. O gerador de variações volta mais tarde, com uma timeline própria.

mostrar os 3 passosesconder os 3 passos
Claude

5A sobrancelha, e a anatomia de verdade: crânio, músculo, pele

06/11, 08:09 a 13:43

Uma "sobrancelha" (crista e vinco sobre o olho) adicionada à cabeça. Resultado: a região dos olhos não tinha profundidade. Uma bola de pele com furos não tem onde a sombra cair.

sobrancelha
Rafael

Our eyebrows results are completely poor, we need to redo it from scratch.

Rafael
Rafael

a partir daqui as coisas comecaram a dar errado

Rafael
Claude

O motivo fica claro agora: até o passo 4 o resultado era limpo porque a cabeça era uma forma só, nossa, e as referências só ajustavam proporções. Aqui começamos a querer detalhe fino (sobrancelha, profundidade do olho), e cada tentativa de buscar detalhe nos afastou da cabeça limpa: primeiro peças feitas à mão que não convenceram, depois o crânio do zero (logo abaixo), depois o detalhe vindo dos modelos dos outros, que trouxe buracos e dobras (passos 6 e 7). O passo 7 volta à ideia do passo 4: proporções vindas dos gatos, detalhe vindo de uma fonte limpa.

Anatomia de verdade: crânio, músculo, pele. Pesquisa nos livros (Goldfinger, Ellenberger) e num crânio de gato escaneado, colocado dentro da cabeça. Decisão: reconstruir do zero, camada por camada, como um escultor. Resultado: o crânio paramétrico chegou a 0,0114 de erro médio contra o scan, com fatias tipo tomografia e mapas de calor para diagnosticar. Mas continuava com cara de "massinha": medimos que faltava detalhe em todas as escalas pequenas.

fatias do crânio close do crânio

Ferramentas que entraram aqui: fatias (cortar as duas formas como numa tomografia) e mapas de calor (colorir onde elas discordam), para ver o porquê e não só o quanto. Lição: um número que bate não é um visual que bate. Ajustamos a "rugosidade" do crânio até ela bater com a do scan, e o resultado parecia metal martelado; o scan é liso entre os detalhes.

Rafael

Ok, you can proceed, but lets stop and think a bit. You have the models file with the exaclty shape I like. Why you can't scan this shapes and understand the exact position to create your own script? The purpose of the script is to generate variations of a good shape, because we'll be able to generate multiples characters following a good shape.

Rafael
Claude

6A virada: um gerador de variações a partir de gatos bons

06/11, 14:00 a 19:03

Até aqui a gente tentava descrever um gato: com números (os 25 parâmetros da SDF) ou com peças anatômicas. Com essa pergunta, tudo mudou. Dali em diante a forma boa passou a vir dos próprios modelos, e o nosso trabalho virou outro: fazer todos falarem a mesma língua e misturá-los.

Como funciona (é o método dos modelos morfáveis de rostos humanos e do SMAL, feito para animais):

  1. Um molde comum (template). Uma cabeça só, a da Tabby, com uns 29 mil pontos.
  2. Vestir cada gato com o molde. O molde é deformado aos poucos até cobrir a superfície de cada gato, como uma luva elástica. No fim, todo gato é descrito pelos mesmos 29 mil pontos em posições diferentes: o ponto 1234 é o canto do olho em todos eles. Isso se chama correspondência.
  3. Aprender as diferenças. Com todos nos mesmos pontos, dá para tirar a média (o gato médio) e as direções em que eles mais variam juntos (PCA): por exemplo, "orelhas altas e cabeça longa" contra "orelhas baixas e cabeça larga".
  4. Gerar. Um gato novo é a média mais um pouco de cada direção.

Resultado: pela primeira vez as cabeças tinham a qualidade de forma dos modelos que escolhemos como referência. Mas a luva não vestiu bem. Nas orelhas finas ela se dobrou (os "buracos" no Blender eram dobras com a face virada do avesso), e olhos e boca ficaram borrados na média, porque só nariz, pontas das orelhas e queixo estavam presos. Com três gatos, a variação também era pequena.

primeiro gerador

Textura. Como o template é a superfície da Tabby, a cor da textura da Tabby é lida em cada ponto do template; toda cabeça gerada herda a pelagem. Variações recolorem esse padrão com paletas tiradas de fotos reais de gatos (Wikimedia Commons) e máscaras (focinho branco, colorpoint, calico). Resultado: o maior salto visual até aqui.

pelagens

A pintura fica guardada em cada ponto do template (cores por vértice), e cada pelagem nova é a mesma estampa recolorida com três cores (escura, base, clara) tiradas de fotos de gatos. Lição: a textura é metade do resultado; julgar formas em argila cinza engana.

Por que as variações saíam distorcidas. Medimos: não era pose nem distância à superfície, era deslizamento: os pontos ficavam na superfície certa mas escorregavam por ela, se amontoando num lugar e esticando em outro. Mesmo ajustando a Tabby nela mesma, 24% dos triângulos distorciam mais de 2 vezes. Correções: puxar só na direção da normal, preservar o comprimento das arestas, template com triângulos uniformes (remesh do Blender). Resultado: distorção caiu pela metade (Tabby 24% para 9,5%; outros gatos 39% para 15%; média 20% para 10%).

O remesh voxel do Blender reconstrói a malha com triângulos do mesmo tamanho, que deformam por igual; antes, 10% dos triângulos do template eram finos como lascas e distorciam fácil.

Variações: misturar por região e controles com nome. Com três gatos, a PCA só tem duas direções simétricas, então toda cabeça gerada era um passinho perto da Tabby. Como todas as cabeças têm os mesmos pontos, dá para misturar por região: orelhas de um gato, focinho de outro, crânio de uma mistura dos três, com bordas suaves borradas ao longo da superfície (sem costura). As orelhas são achadas por serem finas (um raio atirado para dentro sai do outro lado em menos de 7 mm). Em cima disso, controles com nome: tamanho e abertura das orelhas, comprimento e largura do focinho, bochechas, tamanho do olho, altura do crânio, largura da cabeça. Um personagem é uma receita (mistura por região + controles + pelagem), sorteada ou desenhada. Resultado: cada cabeça do elenco parece um gato diferente. Limites: os olhos ainda vêm sempre da Tabby (os ajustes dos outros dois gatos têm órbitas ocas), e o controle de tamanho do olho mexe pouco porque a Tabby tem olhos semicerrados.

misturas por região controles elenco
Claude

7Mais gatos e os pontos do rosto

06/11, 19:16 a 22:14deu errado

Procuramos no Objaverse (1970 modelos com "gato", 801 miniaturas olhadas, 19 baixados) e escolhemos seis: orange, ginger, sculpt, grey, tuxedo e leo. Cada um foi alinhado ao referencial do gerador (nariz e pontas das orelhas, depois a superfície do rosto) e recebeu o template (2 minutos cada). Resultado: muito mais variedade de orelha e de formato de cabeça (9 direções de variação em vez de 2). Mas os olhos e a boca ainda escorregam no ajuste (só nariz, orelhas e queixo estão presos), então os olhos continuam vindo da Tabby e o focinho só dos gatos com ajuste limpo. Removemos espinhos (tufos de pelo modelados como geometria e a borda aberta atrás da cabeça). Piorou uma coisa: as superfícies ficaram mais irregulares. Próximo passo: prender olhos e boca com pontos de referência.

os nove gatos misturas elenco

Depois entraram mais três: um Bengal e um Sphynx comprados no Sketchfab, e o gato do jogo Murdered: Soul Suspect (a pose dele estava com a cabeça abaixada, mas a pose original do modelo, a de "repouso" do esqueleto, é um gato em pé, neutro, que também servirá para o corpo). O gato do Murdered é o primeiro, além da Tabby, com olhos limpos. Doze gatos dão 11 direções de variação.

doze gatos elenco com doze

Antes de misturar, cada gato é "endireitado" (virado para olhar reto para a frente) e todos passam por um Procrustes generalizado: o alinhamento é repetido contra a média de todos até estabilizar, para que a estatística aprenda forma, e não a pose em que cada modelo segurava a cabeça.

Forma grande dos gatos, detalhe limpo. A ideia veio de uma observação: a cabeça do passo 3 era limpa, sem os buracos de agora. O que a deixava limpa era que todo detalhe pequeno vinha de uma fonte só. Então separamos cada gato por escala: a forma grande (proporção do crânio, tamanho e posição das orelhas, comprimento do focinho) vem dos gatos; o detalhe pequeno (pálpebras, nariz, boca) fica sendo o do template, que é limpo. Na prática, a diferença de cada gato para o template é "borrada" ao longo da superfície antes da mistura. Resultado: cabeças limpas, sem órbitas ocas nem focinhos duplicados, e cada uma com suas proporções (as orelhas enormes do Sphynx, a cabeça redonda do Bengal). O preço: todas têm os olhos, nariz e boca da Tabby. Próximo passo possível: trocar a fonte do detalhe por uma cabeça nossa (a SDF do passo 4, ou uma esculpida com os livros) para o detalhe também ser nosso.

forma grande, detalhe limpo

Pontos do rosto e mais 22 gatos. Para prender olhos e boca no ajuste, usamos um detector de pontos de cara de gato treinado em fotos (CatFLW, 48 pontos: cantos e pálpebras dos olhos, nariz, boca, almofadas dos bigodes, orelhas). Cada gato é renderizado de frente com a própria textura, o detector marca os pontos e cada ponto é projetado de volta na superfície 3D. Funcionou em quase todos; nas esculturas brancas, sem textura, erra o nariz. Os livros deram a definição anatômica de cada ponto (docs/landmarks.md). Em paralelo, quatro subagentes alinharam os 23 gatos do Sketchfab (um era cópia do orange, ficou fora), e o gerador passou a ter 34 gatos.

Resultado: com os pontos presos, os buracos dos olhos do walker viraram pálpebras. Mas com o achatamento dos bigodes desligado, o template da Tabby ganhou caroços onde ficavam os fios, e todas as cabeças herdariam isso.

pontos do rosto nos gatos ajuste antigo e novo
Rafael

Resultado horríveis. Estou pensanod que tavlez vale a pena a gente voltar pra ca -> 3. Cabeça anatômica feita de matemática (05/11, noite) e tentar refinar isso

Rafael
Claude

8De volta à cabeça matemática, medida e ajustada ao gato médio

06/11, 22:14 a 22:36

Paramos o ajuste dos 34 gatos e voltamos à cabeça matemática do passo 3. Ela é limpa por construção: é uma função só, sem buracos, dobras ou caroços. O que faltava no passo 4 era medir o que importa: silhueta e distância de superfície não enxergam olhos nem boca. Agora temos os 48 pontos do rosto de 33 gatos. Tiramos a forma média deles (Procrustes generalizado: cada gato movido, girado e escalado sobre a média até estabilizar, para comparar forma e não tamanho ou pose) e passamos o mesmo detector na cabeça do passo 4, renderizada com olhos e nariz coloridos para ele reconhecer uma cara de gato.

Resultado: a cabeça do passo 4 já acerta quase tudo: largura e inclinação do olho, distância entre os olhos, largura e altura do nariz, queixo, distância entre as orelhas. Erra em quatro coisas (medidas em "distâncias entre os cantos externos dos olhos"):

  • Olho achatado demais: altura 0,59 da largura; nos gatos, 0,78 (gato de olho aberto tem olho mais redondo).
  • Boca estreita demais: 0,30 entre os cantos; nos gatos, 0,46 (o maior erro, fora da faixa de todos).
  • Boca um pouco alta, perto demais dos olhos.
  • Orelhas altas demais: 1,16 acima dos olhos; nos gatos, 0,91 (herança da Sphynx).

Decidimos também julgar as imagens no Cycles (o render realista, com sombras e oclusão de verdade, ver passo 3); o Eevee fica só para uso interno, como as imagens para o detector.

gato médio (azul) contra a cabeça matemática (laranja)

A cabeça matemática ajustada ao gato médio. Três rodadas de correção, medindo com o detector a cada uma: abertura do olho mais alta (0,075 para 0,100), boca mais larga e mais baixa (dois controles novos, mouth_w e mouth_y, com as linhas dos lábios assentadas sobre a pele), almofadas dos bigodes mais largas (controle novo pads_w), orelhas mais baixas e mais afastadas, focinho um pouco mais à frente. Para medir as pontas das orelhas, que ficam na borda da silhueta, usamos a posição 2D da imagem.

Resultado: 13 das 15 proporções dentro da faixa dos gatos (antes eram 9). No Cycles, as orelhas ficaram de gato doméstico e o olho mais redondo. O que ficou ruim: a boca larga virou um vinco comprido, quase uma costura em volta do focinho. E o aspecto de argila e a falta de profundidade nos olhos continuam (é o próximo passo).

antes (passo 4) e depois (gato médio), em Cycles
Claude

9Milhares de fotos de gatos reais, e a cabeça ajustada a elas

06/11, 22:36 a 22:51

A ideia: em vez de depender de poucos modelos 3D (vários estilizados ou feitos por IA), medir em fotos de gatos reais. O detector foi treinado justamente em fotos. Usamos o Oxford-IIIT Pet (2.371 fotos de gatos de 12 raças, com a raça anotada; baixado da cópia do Hugging Face, porque o servidor de Oxford estava a 150 KB/s) e ficamos com as 1.027 caras de frente: olhos à mesma distância do nariz e cabeça pouco inclinada. Foto dá proporção vista de frente, em 2D; a comparação com a cabeça matemática também foi feita "achatada", vista de frente.

Resultado: a cabeça de agora acerta largura do olho, distância entre os olhos, largura do nariz e largura da boca (a do passo 4 errava a boca). As fotos mostram o que ainda falta: olho ainda mais redondo (altura 0,86 da largura) e mais inclinado (20 graus), nariz e boca mais baixos, almofadas dos bigodes mais largas e orelhas mais afastadas. Por raça aparecem diferenças que viram "presets" de personagem: o Persa tem nariz estreito e orelhas baixas (cara achatada), o Siamês orelhas altas, o Sphynx boca estreita.

1.027 fotos de frente e a tabela

Ajuste da cabeça às fotos. Primeira tentativa: corrigir os números e medir com o detector, como antes. Mas mexemos bastante nas almofadas, na inclinação do olho e no queixo, e a medida quase não mudou. Motivo: numa cabeça de argila, sem pelo, bigodes ou manchas, o detector não tem pistas de onde terminam as almofadas ou onde está o queixo, e nesses pontos ele chuta a posição típica que aprendeu: mede a própria expectativa, não a nossa cabeça. Nos gatos reais ele é confiável; na nossa cabeça não precisamos dele, porque sabemos onde cada parte está (fomos nós que construímos). Então os pontos da cabeça passaram a ser calculados direto da fórmula (cantos do olho = pontas da janela em amêndoa, ponta da orelha = topo do cone, e assim por diante), e uma otimização por mínimos quadrados ajusta 12 números de uma vez, em menos de um segundo, para as proporções caírem na mediana das fotos. Criamos também o controle muzzle_y, que desce o focinho inteiro (nariz, boca, almofadas, queixo).

Cuidado aprendido: "canto da boca" na nossa fórmula (o fim da linha do lábio, lá atrás, embaixo da almofada) não é o mesmo ponto que o detector chama de canto da boca nas fotos (o canto visível de frente). Para olho, nariz e orelhas as definições batem; para boca e queixo, a tabela sozinha engana, e o juiz é o render.

Resultado (Cycles): olhos menores e inclinados como nos gatos (menos "assustados"), a costura da boca sumiu, orelhas afastadas. Mas as almofadas dos bigodes cresceram demais e viraram uma bola na frente da cara, quase um focinho de cachorro: a almofada é uma elipse simples, e ficar mais larga também a deixou mais estufada.

modelos 3D (em cima) e fotos (embaixo), em Cycles
Claude

10Almofadas dos bigodes que não viram bola

06/11, 22:51 a 22:54

A almofada era uma elipse virada para a frente: ao alargar, também estufava. Ganhou dois controles: pads_bulge (quanto ela estufa para a frente) e pads_turn (quanto ela gira em volta do focinho, acompanhando a curva da cara). Testamos duas combinações no Cycles e ficamos com a mais achatada e girada; depois o ajuste às fotos a alargou de volta, agora para os lados.

Resultado: o focinho perdeu a "bola" e ficou largo e liso, mais de gato. Continua a argila e a falta de profundidade nos olhos.

almofada original, achatada e girada, e reajustada às fotos
Claude

11Olhos dentro da cara, e por que a cabeça ainda não serve de base

06/11, 22:54 a 23:01

O globo ocular ficava à frente da superfície da cara: o olho saltava e parecia colado por cima, como bola de gude ("olho de pelúcia"). Três controles novos: eye_depth (o globo e a pálpebra empurrados para dentro da órbita), lid_fold (a espessura da dobra da pálpebra de cima, que faz sombra) e tear (o sulco que desce do canto interno do olho em direção ao nariz). Com o olho mais fundo, a pele da frente cobriria o olho; então a órbita é aberta no formato da amêndoa, um pouco maior que as pálpebras, e a borda da cara vira a parede da órbita, como faria um escultor.

Resultado (closes em Cycles): com o globo 0,45 raio mais fundo (D2), o olho fica dentro das pálpebras, com uma borda e uma sombra leve por cima: a primeira vez que ele parece encaixado na cara. Com 0,75 (D3) passa do ponto: dois anéis concêntricos, como óculos de natação. Ficamos com a D2 (params/sdf_head.json). O sulco ainda quase não aparece.

olhos: atual, D2, D3

Por que a cabeça ainda não serve de base. A D2 ficou boa, mas a cabeça ainda não era suficiente para servir de base. Colocamos a nossa cabeça ao lado de quatro gatos bons (Tabby, Bengal S1234, Siamês S634, Murdered), na mesma escala, de frente, três quartos e perfil, em Cycles.

O que aparece: as diferenças são de estrutura, não de detalhe. Nos gatos, a testa desce numa linha longa e quase reta até o nariz, e a cara inteira é uma cunha; a nossa é uma bola (o crânio) com um focinho pequeno grudado embaixo, o mesmo "boneco de neve" do crânio. Os gatos são mais longos do nariz à nuca; as orelhas deles ficam mais para trás e para os lados, atrás dos olhos; os olhos são amêndoas meio fechadas sob a sobrancelha; o focinho nasce da ponte do nariz; as bochechas têm um plano marcado. Ajustar números não resolve, porque nenhum número transforma uma esfera numa cunha: a lição do crânio (a forma só leu como crânio quando foi cortada pelo plano medido da testa ao nariz) vale aqui.

a nossa cabeça e quatro gatos bons, em Cycles
Claude

12As curvas-chave dos gatos bons, e as formas grandes ajustadas a elas

06/11, 23:01 a 23:22

Medimos, em 12 gatos de superfície limpa e realista (Tabby, orange, Bengal, Murdered, quatro Siameses, S1234, S1055, S1168, S1114), as curvas que definem a forma grande da cabeça, todas no mesmo referencial: o perfil do meio da cara (o corte no plano central, da nuca ao queixo), seis cortes horizontais (testa, sobrancelha, olho, nariz, boca, queixo) e a metade da silhueta de frente (a largura em cada altura). Cada curva é medida como "a que distância fica a pele" em cada direção a partir de um centro fixo, para tirar a mediana dos gatos ponto a ponto.

O que as curvas mostram: o nosso crânio é mais alto e vai mais para trás (a nuca é uma bola); a testa avança demais; a garganta desce numa papada redonda. De frente, os gatos mantêm a largura quase constante da sobrancelha até a mandíbula (bochechas largas embaixo), e a nossa afina para baixo como uma bola. Na altura do nariz, as nossas almofadas fazem "ombros" onde os gatos afinam liso; o nosso queixo é estreito e recuado. As medianas ficaram guardadas (data/head/curves.json) e servem de alvo para a reconstrução.

curvas dos 12 gatos (cinza), mediana (azul) e a nossa cabeça (laranja)

Reconstrução 1: as formas grandes ajustadas às curvas. A cabeça ganhou peças novas, todas desligadas por padrão (com elas desligadas, a cabeça é idêntica à anterior, conferido em 40 mil pontos): crânio mais curto atrás (skull_back), alcance da testa (forehead), um plano da testa ao nariz (dorsal), bochechas e mandíbula largas embaixo (jowl), queixo mais largo e à frente (chin_w, chin_fwd) e garganta (throat). Para cada raio das curvas medidas, a distância até a pele vem direto da função da cabeça: uma marcha de fora para dentro acha a pele, e um passo de Newton final deixa o resultado derivável em relação aos números, então um otimizador ajusta tudo por gradiente. Dois tropeços no caminho: a marcha só andava para dentro e atravessava a pele (só 1% dos raios acertava; corrigido, 100%), e as peças desligadas nunca se mexiam, porque desligadas não tocam a pele e o gradiente delas é zero (agora começam tocando).

Resultado: o erro médio das curvas caiu de 0,039 para 0,021 da largura da cabeça: crânio mais baixo e curto, bochechas de baixo mais cheias, focinho maior. Mas no render a diferença é pequena: ainda parece um brinquedo de vinil. O que denuncia não está nas curvas medidas (perfil e cortes horizontais): olhos redondos de óculos, onde os gatos têm pálpebra cobrindo parte do olho; orelhas grandes e finas no alto, onde as dos gatos são menores, de base grossa e mais para trás; nenhuma ponte do nariz (nos gatos, um plano longo e reto até o nariz); nenhum plano marcado de maçã do rosto e sobrancelha. E os furos das narinas apareceram com o focinho maior.

antes e depois da reconstrução 1, com quatro gatos
Claude

13Pálpebras: de óculos para amêndoa

06/11, 23:22 a 23:27

Para julgar detalhes do rosto, a folha de comparação ganhou um modo close (cada cabeça sozinha, de perto, de frente e em três quartos, em Cycles). Nos gatos, a abertura do olho é uma amêndoa de cantos pontudos, bem mais baixa que larga, e a pálpebra é uma borda fina que acompanha o globo; na nossa, uma oval quase redonda com um aro grosso e saltado, como óculos. Três controles novos: eye_pointed (a amêndoa desenhada como artistas desenham olho de gato: a região dentro de dois arcos de círculo que se encontram nos cantos), lid_drop (a pálpebra de cima descendo sobre o olho) e lid_thick (a espessura da pálpebra). Uma decisão: as fotos pediam olho mais redondo (gato em foto costuma estar alerta), mas os modelos, inclusive a Tabby, têm olho de gato relaxado, semicerrado; seguimos os modelos, e o controle permite abrir mais depois. Corrigimos também uma fresta que aparecia em volta do olho (a órbita aberta era 18% maior que as pálpebras): controles socket e lid_blend.

Resultado: a versão lid4 tem olho em amêndoa, pálpebra fina que se funde na cara sem fresta, olho menor e meio coberto, muito perto do Murdered e do Siamês.

óculos (rebuild1) e amêndoas (lid1, lid2) lid2, lid3, lid4: a fresta some na lid4
Claude

14Nariz: ponte reta, ponta arredondada, boca sem furos

06/11, 23:30 a 07/11, 00:05

Primeiro medimos, porque o perfil do meio da cara já batia com a mediana dos gatos até o nariz e mesmo assim o nariz parecia errado. A nova medida é um mapa de relevo visto de frente: numa grade sobre o focinho (passo de 0,01, de baixo dos olhos até o queixo), um raio vindo da frente marca onde encontra a pele, em cada um dos 12 gatos bons (ferramenta nova tools/fit_muzzle.py). Três cuidados que fizeram diferença:

  • Alinhar pela ponta do nariz antes da mediana. Cada gato tem o nariz numa altura um pouco diferente (de -0,04 a -0,15); a mediana sem alinhar borra o nariz numa lombada mole.
  • Comparar a forma, não a altura. Entre gatos a altura da pele varia 0,06 a 0,09, enquanto o nariz é uma forma de 0,01 a 0,02. Então a medida é quanto cada ponto cai em relação ao meio da sua linha (a seção transversal), e o perfil é medido a partir da ponta do nariz de cada gato.
  • Deixar o canto do olho fora, porque ali a diferença é o olho, não o nariz.

O que as medidas mostraram e o que construímos (peças novas em cat_head.py, todas desligadas por padrão):

  • ponte: nos gatos ela tem o topo plano (cerca de 0,045 para cada lado) e lados que caem de repente; a nossa era um cilindro redondo. Agora é uma faixa de seção retangular com cantos arredondados, que afina em direção ao nariz (bridge_flat, bridge_w, nose_w);
  • plano ao lado da ponte: o lado do maxilar, que nos gatos é cheio até a bochecha (snout_side);
  • couro do nariz: era uma bolinha; virou uma ponta arredondada com contorno de triângulo (um elipsoide cortado pelo triângulo, leather, leather_s). As narinas agora são cortadas depois do couro (antes ele as enchia de volta);
  • os "furos": não eram narinas. Era o corte da boca, um tubo enterrado sob a pele que só aflorava em alguns pontos. Virou uma fenda aberta para a frente que segue a pele ponto a ponto (mouth_slot), e não tem como virar túnel;
  • abaixo do nariz: nos gatos a pele recua 0,03 a 0,04 logo abaixo da ponta e as almofadas ficam um pouco à frente do centro; ganhou um sulco largo e raso no meio (philtrum), e o queixo voltou para trás.

O ajuste move só essas peças. O erro médio da forma da seção caiu de 0,028 para 0,009, e o perfil a partir da ponta bate até 0,01 em quase toda a altura.

Resultado: a cara lê bem mais como gato: uma ponte reta e plana dos olhos até uma ponta de nariz arredondada, a boca uma linha limpa. Ainda falta: o nariz dos gatos tem mais volume no três-quartos, com uma reentrância mais funda sob a ponta; e as almofadas atuais não conseguem fazer a região sob o nariz (o ajuste as empurrou para os limites), então ali o que existe é o sulco. A cabeça inteira mostra que a próxima são as orelhas.

nariz antes (lid4) e depois (nose4), de frente, três-quartos e perfil cabeça inteira antes e depois, ao lado dos gatos
Claude

15Orelhas: menores, mais baixas e fundidas no crânio

07/11, 00:05 a 00:11

Medida primeiro, de novo. Uma ferramenta nova (tools/head_outlines.py) tira o contorno de cada um dos 12 gatos de frente e de lado e empilha: cada ponto da imagem ganha a fração de gatos que o cobrem, e a linha dos 50% é o contorno mediano. Dele saem números da orelha: a ponta, o "entalhe" (onde a borda de dentro da orelha encontra o alto da cabeça), a largura da base e a altura.

orelha (contorno de frente)gatos (mediana)10% a 90%antesdepois
altura0,2000,168 a 0,2460,3120,192
largura da base0,2600,193 a 0,3410,4000,248
ponta, para o lado (x)0,3680,322 a 0,3920,4880,400
ponta, altura (y)0,5600,512 a 0,6220,6560,552
borda de fora na base (x)0,4440,401 a 0,4870,5680,416

As nossas estavam 55% mais altas e com a base 50% mais larga, com a ponta muito para fora. Nos gatos a borda de fora da orelha continua a linha do lado da cabeça, quase na vertical, e de lado a orelha nasce mais atrás no alto da cabeça.

O ajuste (tools/fit_ears.py) usa o contorno diferenciável que já tínhamos (faber/silhouette.py): só as orelhas se mexem, então só elas são traçadas a cada passo, sobre o contorno do resto da cabeça, que é calculado uma vez. O alvo é o mapa dos gatos (um ponto que metade dos gatos cobre é puxado para 0,5). A sobreposição com o contorno mediano, na região das orelhas, foi de 0,59 para 0,93 de frente e de 0,71 para 0,88 de lado. A base da orelha afundou no crânio, que é o que queríamos.

A silhueta certa ainda deixava a orelha como uma concha de borda fina e afiada até a base, com uma aresta onde encontrava a testa. Três controles novos: quão suave a orelha se funde no crânio (ear_blend), a espessura da borda (ear_rim) e a altura onde a concha começa (ear_cup_base, base maciça abaixo dela). Escolhida a versão ears3. Uma decisão: as fotos (passo 11) puxavam as pontas das orelhas mais para cima e para fora, porque nas fotos o gato costuma estar alerta e as orelhas aparecem em perspectiva. Seguimos os modelos 3D, como nos olhos, e o ajuste pelas fotos não mexe mais nas orelhas.

Resultado: é o passo que mais mudou a leitura da cabeça. Com orelhas do tamanho e no lugar certo, de base grossa, ela parece um gato, não um morcego.

contornos dos 12 gatos (cinza, linha azul) com a nossa antes e depois orelhas antes, ajustadas ao contorno, e com base fundida (ears3)
Claude

16Planos da cara: menos vincos, bochecha lisa

07/11, 00:11 a 00:39

A ideia era criar planos: a frente da cara (testa, sobrancelha, em volta dos olhos) virando para o lado da cabeça numa aresta suave. Primeiro medimos de novo as curvas (passo 12) com a cabeça nova. Testa, sobrancelha, nariz e perfil já estavam dentro da variação dos gatos; a sobrancelha só 0,027 mais cheia nos lados.

Duas tentativas que não deram certo, e por quê:

  • Um plano de corte na têmpora (o lado do crânio entre olho e orelha), deixando a maçã do rosto saltar embaixo. As medidas não pediram o corte (o ajuste o levou a zero), e onde ele terminava ficava um degrau duro na bochecha. Removido.
  • A largura da silhueta de frente no ajuste das formas grandes. Abaixo de y = -0,15 a largura dos gatos inclui o pescoço, cortado num lugar diferente em cada modelo; o ajuste inflou a massa da mandíbula num calombo atrás da boca. Agora essa medida só vale acima de -0,15.

Olhando a comparação de novo, o que impedia os planos na nossa cara eram vincos que os gatos não têm: o sulco do canto do olho descendo para o nariz, a borda do plano ao lado da ponte, a borda de cima das almofadas e um crescente onde a massa do focinho encontra a bochecha (a "linha do sorriso"). Nos gatos a bochecha é um plano largo e liso até as almofadas. Três controles novos de suavidade da junção (snout_blend, pads_blend, muzzle_blend), o sulco do olho desligado e a dobra da pálpebra mais leve. Suavidade demais incha o focinho e enterra o nariz (as narinas voltaram a aparecer como furos), então ficou um meio-termo, e as peças do focinho foram reajustadas em cima dele. As medidas não pioraram: forma do focinho 0,009, curvas 0,0168 (antes 0,0165).

Resultado: a cara ficou limpa, sem as rugas de gato sphynx, com a bochecha descendo lisa até as almofadas. params/sdf_head.json agora é esta cabeça (sdf_planes). A última imagem mostra a cabeça antes das quatro partes e depois.

antes e depois dos vincos, de perto a cabeça antes das quatro partes (rebuild1) e depois (planes), ao lado dos gatos
Claude

17Olhos: medidos no relevo, sem a sombra de óculos

07/11, 06:39 a 07:24

De frente, os olhos pareciam grandes e redondos demais perto do Bengal e do Murdered. As proporções das fotos não enxergavam isso, porque são medidas em "distâncias entre os cantos dos olhos": um olho largo demais e também afastado demais mantém a proporção. Os 12 gatos bons estão no nosso referencial e na mesma escala, então dá para medir o olho em tamanho absoluto, como fizemos com as orelhas. Ferramenta nova: tools/fit_eyes.py.

Primeira medida, pelos pontos do rosto (passo 7). Os cantos do olho batem bem nos modelos com textura. A nossa abertura era mais larga que a de todos os 12 gatos (0,211; os gatos vão de 0,142 a 0,195, mediana 0,167) e ficava 0,027 mais para fora. Mas, ao ajustar a altura pelos pontos das pálpebras, o olho ficou mais redondo, não menos. Motivo: as pálpebras do detector marcam o olho pintado na textura, não a abertura na forma. Em argila, o olho do Murdered é uma amêndoa mais baixa e o do Bengal é uma fenda.

Segunda medida, no relevo. Uma linha vertical pelo centro do olho, vista de frente: a que profundidade está a pele em cada altura. Onde a pálpebra encontra o globo, a linha faz um "dente" para dentro. Os dois dentes mais fortes, acima e abaixo do centro, são as bordas das pálpebras. Desse perfil saem quatro números, medidos nos 12 gatos:

medidagatos (mediana)10% a 90%antesdepois
altura da abertura0,0820,073 a 0,1040,1020,110
quanto a pálpebra de cima fica à frente do globo-0,003-0,010 a 0,0110,046-0,003
nitidez da borda de cima / de baixo1,8 / 2,6até 5,1 / 5,226 / 355,3 / 5,7
fundo do olho atrás da linha da cara0,0240,014 a 0,0330,0570,028
largura do olho que se vê0,1670,148 a 0,1740,1540,167
centro do olho, para o lado (x)0,1670,159 a 0,1840,1940,167

Esse era o problema de verdade: nos gatos, o globo continua a curva da cara, com só um dentinho em cada pálpebra. O nosso ficava 0,046 atrás da pálpebra de cima, dentro de uma órbita com parede, o fundo do olho tinha o dobro da profundidade dos gatos e a borda era um degrau 5 a 10 vezes mais marcado. O anel de sombra em volta é o "óculos" que fazia o olho parecer grande: a parte do globo que se via era até um pouco menor que a dos gatos. A abertura ficou um pouco mais alta que a mediana (0,110 contra 0,082 a 0,104), o preço de ter a largura visível certa com bordas macias. O perfil da nossa cabeça é calculado direto da função, atirando raios que andam pela distância até achar a pele (sem malha, um segundo por cabeça), e uma busca aleatória seguida de refinamento ajusta os números das pálpebras, porque os dentes mudam aos saltos e não dão gradiente.

O caminho até a versão final, com o que cada tentativa ensinou:

  • eyes2: o globo vai para a superfície (eye_depth 0) e o tamanho de olho medido no crânio (raio 0,10, era 0,12). Lê como gato, mas com uma rachadura escura em volta: a cara era escavada 0,006 em volta do globo e a pálpebra ficou mais fina que isso.
  • A forma da amêndoa não pode sair da medida do relevo: solta, a busca fechou o olho numa fenda. Agora ela é fixada pelos modelos: arco de cima mais alto que o de baixo (lid_low 0,65, controle novo), como no Siamês e no Murdered.
  • eyes7: com o globo na superfície, a cara cobria os lados do globo e o olho visível ficava pequeno e redondo (largura visível 0,106). O corte da órbita só existia com o globo afundado; o controle novo socket_open abre a órbita também com o globo na superfície.
  • eyes8: a fresta entre globo e pálpebra (0,0012) era menor que a grade da malha (0,004) e virava um serrilhado escuro. A solução é a dos escultores: a pálpebra entra um pouco no globo (lid_gap negativo), e a borda visível passa a ser a interseção dos dois, sem fresta.
  • eyes9: a dobra da pálpebra muito fina virava uma lâmina, cuja ponta a união suave transformava num carocinho sobre o canto do olho; agora ela fica entre 0,5 e 1.

Todos os controles novos (socket_open, socket_blend, lid_gap, lid_low, lid_edge) reproduzem a cabeça anterior quando ficam no padrão (diferença zero em 200 mil pontos).

Resultado: os olhos ficaram no tamanho e no lugar dos gatos, encaixados na cara sem o anel de sombra, com a pálpebra macia, muito perto do Murdered. params/sdf_head.json agora é a eyes9. A alternativa eyes8c (amêndoa um pouco menor, mais perto do Siamês) ficou guardada, caso seja preciso voltar a ela.

antes, eyes8c e eyes9, de perto, com Murdered, Siamês e Tabby cabeça inteira antes e com os olhos novos, ao lado dos gatos
Claude

18Nariz: o couro largo e redondo, com narinas

07/11, 07:24 a 07:56

No close do nariz, os gatos têm na ponta uma massa larga e redonda (o couro do nariz), que continua a ponte sem vinco, com as narinas como vírgulas escuras nos cantos de baixo e uma sombra forte embaixo. O nosso era um triângulo pequeno desenhado por sulcos, um "Y". O relevo do focinho com grade de 0,01 (passo 14) não via isso: ali o nosso já batia com os gatos em cerca de 0,01, e essas formas medem de 0,005 a 0,02.

Medida mais fina. Uma ferramenta nova (tools/fit_nose.py) mede o relevo só em volta da ponta do nariz, com grade de 0,0025, cada gato alinhado pela própria ponta e medido a partir dela. Desenhado como argila iluminada, o mapa mostra na hora um sulco ou uma narina, onde os números são difíceis de ler.

Uma armadilha. O primeiro ajuste comparava o nosso mapa com a mediana dos mapas dos gatos, e piorou o nariz. Cada gato tem as narinas e a borda do couro num lugar um pouco diferente, então a mediana dos mapas é um nariz liso, sem narina nenhuma, e o nariz antigo, de sulcos rasos, pontuava melhor (0,0044) que um nariz com narinas de verdade (0,0047). É a lição do crânio de novo: um número que bate não é um visual que bate. A correção foi reduzir cada gato a medidas (largura da ponte e do couro em várias alturas, posição e profundidade das narinas, perfil do meio, sulcos) e tirar a mediana das medidas, não dos mapas.

medidagatos (mediana)10% a 90%antesdepois
meia largura da ponte, 0,02 acima da ponta0,0420,036 a 0,0510,0430,038
meia largura do couro na ponta0,0400,026 a 0,0620,0330,040
meia largura do couro, 0,02 abaixo da ponta0,0330,014 a 0,0650,0180,038
narina, distância do meio0,0310,020 a 0,0500,0180,027
narina, profundidade0,0100,001 a 0,0200,0040,015

O couro novo (leather = 3) é um escudo: um elipsoide achatado na frente, que afina um pouco embaixo e se inclina com a base para trás (a sombra de baixo), unido à ponte sem vinco. Cada narina é uma vírgula vista de frente: uma covinha e uma cauda que desce para fora e entra sob o couro (nostril_curl), onde fica na sombra. A profundidade das narinas ficou fora do ajuste: nos gatos com narina esculpida (Tabby, Murdered, Siamês) ela é de cerca de 0,02, mas metade dos gatos só tem a narina pintada na textura, e com a mediana (0,010) as nossas sumiam no Cycles.

Na primeira versão (nose5b), a ponte afinava logo acima do couro (meia largura 0,0325, abaixo de todos os gatos) e o couro parecia uma bola na ponta de um palito. Com a largura da ponte entre as medidas, o ajuste a deixou mais estreita entre os olhos e mais larga perto do nariz: uma faixa uniforme até a ponta, como nos gatos (nose6). O relevo do focinho do passo 14 não piorou (0,009), e todos os controles novos só agem com leather = 3, então as cabeças antigas não mudam.

Resultado: o nariz lê como de gato no três-quartos e de perfil: uma ponte reta que termina numa ponta redonda, com narinas e a sombra embaixo. params/sdf_head.json agora é a nose6.

relevo do nariz, iluminado como argila: mediana dos gatos, antes, nose6 e cada gato nariz antes, nose5b e nose6, de frente, três-quartos e perfil cabeça inteira antes e com o nariz novo, ao lado dos gatos
Claude

19Boca: mais perto do nariz, lábio de baixo sob as almofadas

07/11, 07:56 a 08:15

Este passo mudou o jeito de trabalhar. Nos olhos e no nariz, a maior parte do tempo foi gasta em voltas de "medir, ajustar, renderizar, descobrir que a medida não via o problema". Agora: primeiro olhar (variantes feitas à mão, lado a lado num único close, cerca de 1,5 minuto), depois medir só o que o olhar apontou, e ajustar por último.

A primeira olhada. Nos gatos, logo abaixo do nariz vem um filtro curto e a boca; as almofadas dos bigodes são volumes redondos dos dois lados, e a linha do lábio é curta e se esconde embaixo delas. A nossa tinha uma área lisa e comprida sob o nariz e uma linha de "sorriso" larga, bem embaixo. Os pontos do rosto dos 12 gatos deram os números (medidos a partir das narinas, para baixo):

gatos (mediana)10% a 90%nossa
centro do lábio de cima0,0890,074 a 0,104cerca de 0,13
cantos da boca0,1200,092 a 0,133cerca de 0,16
meia largura da boca0,1140,109 a 0,1280,14

Ou seja, a boca estava 0,04 baixa demais e 20% larga demais. Isso desfaz o ajuste pelas fotos do passo 9, que usava um "canto da boca" diferente do nosso (o cuidado já anotado ali).

Duas rodadas de variantes à mão. Na primeira, subir e estreitar a boca (mouth_y, mouth_w) acertou a direção, e o corte em fenda (mouth_slot) desenhou uma linha mais limpa. Duas variantes erraram por um engano nosso: pads_x já era 0,4 (almofadas perto do meio), e com 0,8 elas acabaram afastadas. O que a rodada mostrou de mais importante estava no perfil e no três-quartos: nos gatos, as almofadas fazem uma marquise sobre a boca. A linha do lábio fica na sombra embaixo delas, e o lábio de baixo recua antes de o queixo voltar um pouco para a frente. Daí veio uma peça nova: um corte que empurra o lábio de baixo para trás, sob as almofadas (lip_under, desligado por padrão). Na segunda rodada, ele largo demais fez uma "gaveta" atravessando a boca inteira; nos gatos, a sombra se concentra no meio.

Só então, a medida. O relevo visto de frente (o do passo 14, com grade de 0,01) diz o quanto cada ponto fica atrás da ponta do nariz. Aqui a mediana dos mapas serve, porque essas formas são largas e ficam quase no mesmo lugar em todos os gatos (ao contrário das narinas). Ela mostrou três coisas: abaixo da boca, os gatos recuam aos poucos (0,06 a 0,078 atrás da ponta) e o nosso ficava em 0,05; o queixo já estava certo (puxá-lo para trás, como nas variantes, errava por 0,03); e o corte da segunda rodada passava do ponto em 0,03. Uma ferramenta nova (tools/fit_mouth.py) ajusta o corte (profundidade, largura, altura) e o queixo a essa parte do relevo. No caminho, apareceu um erro de definição: com lip_under em 0, o corte ainda existia. Agora 0 é praticamente nada (0,0025).

Resultado: a linha do meio, 0,13 abaixo da ponta do nariz, ficou 0,072 atrás dela (gatos 0,070; antes 0,048), e o erro na janela da boca e do queixo caiu de 0,0067 para 0,0046 (o relevo do focinho inteiro, de 0,009 para 0,0083). Nos renders, a boca fica logo abaixo do nariz, com uma sombra no centro, sob o lábio de cima, e de perfil aparece um degrau curto sob o nariz no lugar da rampa comprida. params/sdf_head.json agora é a mouth_i. Ainda falta: no três-quartos, a linha do lábio é um sulco nítido que vai longe para o lado, enquanto nos gatos ela some sob as almofadas.

boca antes, só levantada (mouth_b) e com o lábio de baixo sob as almofadas (mouth_i) cabeça inteira antes e com a boca nova, ao lado dos gatos
Claude

20Linha do lábio e almofadas dos bigodes

07/11, 08:15 a 08:31

Do jeito novo outra vez: primeiro olhar, depois medir, por último ajustar.

Olhar. Cinco variantes feitas à mão num único close. Dois controles novos para a linha do lábio, desligados por padrão: lip_fade (o sulco fica mais raso até sumir no canto, sob a almofada) e lip_droop (a linha desce antes de abrir para o lado, o "Y" invertido dos gatos). As outras variantes deixavam as almofadas mais estufadas e com junção mais firme, e pareciam mais redondas, mais perto do Siamês.

Medir. O relevo (o do passo 19, entre o nariz e a boca) contradisse em parte o que tínhamos visto, e isso foi útil. As almofadas mais estufadas pareciam redondas, mas a região inteira afundava de 0,006 a 0,01 atrás dos gatos, porque a junção mais firme encolhe o volume. Nos gatos, as almofadas são mais largas e cheias nos lados, e o centro, o filtro, fica quase rente a elas (só 0,004 atrás). O nosso centro era um sulco de 0,015, e esse corte fundo deixava o lábio de cima com cara de rachado.

Ajustar. O modo novo --part pads de tools/fit_mouth.py ajusta as almofadas e o filtro a essas linhas do relevo. Saíram almofadas mais redondas (pads_bulge 1,2), mais afastadas e cada uma mais estreita, um pouco para trás, e o filtro com metade da profundidade. O "redondo" voltou, só que com outra combinação, e agora com o volume no lugar. O erro na janela das almofadas caiu pela metade (de 0,0047 para 0,0023), e o do focinho inteiro de 0,0083 para 0,0072.

Resultado: de frente, duas almofadas redondas dos lados de um filtro raso, e a linha do lábio sumindo sob elas; no três-quartos, o volume da almofada e o canto da boca escondido embaixo, como no Murdered. params/sdf_head.json agora é a lip_f. Duas almofadas bateram no limite permitido (pads_bulge e pads_x): se quisermos almofadas ainda mais marcadas, o próximo passo é a forma delas, não os números.

antes, a variante e (estufada) e a lip_f, de perto cabeça inteira antes e com a lip_f, ao lado dos gatos
Claude

21Queixo: a "polpa" era um artefato da mediana

07/11, 08:31 a 08:42

Uma polpa tinha voltado logo abaixo da boca. E era mesmo um erro. Variantes lado a lado confirmaram a causa. O ajuste da boca (passo 19) tinha estreitado o queixo de 0,84 para 0,55 e mantido ele para a frente, e um queixo estreito e saliente vira uma bolinha. Com o queixo mais largo e um pouco para trás, ela sumia.

Por que a medida pediu isso: nenhum gato tem essa bolinha. Em cada um deles, a pele abaixo da boca só vai ficando mais para trás. Mas em y -0,29 a cabeça de dois gatos acaba (Murdered e Bengal S1234, os dois bem fundos ali), e a mediana dos que sobram fica mais rasa, o que parece um queixo voltando para a frente. O ajuste obedeceu. É a mesma família de armadilha das narinas: a mediana muda de significado quando muda quem entra nela. A correção ficou na ferramenta: numa janela, só votam os gatos que têm pele na janela inteira.

Com a mediana corrigida, o ajuste ainda tentou estreitar o queixo e empurrá-lo para a frente. Os números batiam, mas a bolinha voltava (um queixo estreito chega à profundidade do meio dos gatos, e um largo também, só que sem virar ponta). Então a largura do queixo ficou presa em 0,95 ou mais. Resultado: um queixo largo, um pouco para a frente, com um volume liso sob a boca, como a mandíbula do Siamês, e o erro na janela caiu de 0,0091 para 0,0035. A alternativa sem volume nenhum (queixo largo e mais para trás) ficou guardada em params/sdf_chin_back.json, caso seja preciso voltar a ela.

antes (polpa), queixo para trás à mão e o ajustado (sdf_chin), de perto
Claude

22Pescoço e nuca: grossos e inclinados para trás

07/11, 08:42 a 08:48

Até aqui nenhuma folha mostrava o pescoço dos gatos: o recorte do gerador para logo abaixo do queixo. Mas os 12 arquivos têm pescoço e corpo, então uma ferramenta nova (tools/compare_necks.py) carrega cada gato com a mesma colocação e uma caixa maior, e desenha a nossa cabeça e os gatos de perfil e de trás, em três-quartos, na mesma escala.

Olhar. Nos gatos o pescoço é grosso, e a linha do alto da cabeça continua quase reta, descendo e indo para trás, até o pescoço, sem dente. O nosso era um cilindro fino sob a parte de trás do crânio, com um dente onde os dois se encontravam: uma bola em cima de uma coluna. De trás é mais claro ainda: atrás das orelhas, o pescoço dos gatos é quase tão largo quanto a cabeça. O pescoço tinha um único controle (throat, a grossura); ganhou outros quatro, desligados por padrão: o ponto de cima mais para trás e para cima (neck_top_y, neck_top_z), a inclinação para trás (neck_tilt) e a junção com o crânio (neck_blend, que preenche o dente). Três variantes à mão, lado a lado.

Medir. A linha da nuca, no meio, vista de trás: em cada altura, até onde vai a pele. Abaixo de y ≈ -0,05 os raios começam a bater no corpo, nas patas ou no fim da caixa de cada modelo, o que depende da pose (sentado, andando) e não do pescoço; então só conta a nuca de verdade (y de 0,30 a -0,05), e só os 10 gatos com linha limpa ali.

altura y0,300,150,00-0,05
gatos (mediana)-0,26-0,44-0,62-0,66
antes-0,22-0,33-0,40-0,42
variante c-0,26-0,46-0,62-0,68

A nossa nuca ficava até 0,22 à frente dos gatos (o dente). A variante c acompanha os gatos com erro médio de 0,014 (antes 0,134). A garganta, embaixo do queixo, depende da pose de cada modelo, então ficou de fora: ela vai seguir a pose de repouso quando fizermos o corpo.

Resultado: a nuca desce lisa do alto da cabeça para um pescoço grosso, inclinado para trás, como no Tabby e no Murdered; a cabeça deixou de ser uma bola em cima de uma coluna. params/sdf_head.json agora é a neck_c.

pescoço antes e variantes b, c, d, de perfil e de trás, ao lado dos gatos com pescoço cabeça inteira antes e com o pescoço novo, ao lado dos gatos
Claude

23Olhos mais baixos e orelhas sem "janela"

07/11, 08:48 a 09:15

Olhando a cabeça inteira, as orelhas ainda incomodavam um pouco, os olhos estavam um pouco grandes, a região de queixo, nariz e boca estava um pouco diferente, e a boca vai precisar abrir, porque os gatos vão falar na história. Este passo cuida dos olhos e das orelhas; a boca que abre é o próximo.

Olhos. Na mesma escala, o nosso olho não era mais largo que o dos gatos (o do Murdered é até mais largo); era mais alto, mais redondo. A altura da abertura estava em 0,110, acima de todos os gatos (de 0,073 a 0,104), o preço que tínhamos aceitado no passo 17. Duas rodadas de variantes à mão: abaixar só um pouco quase não mudava; a sf (abertura mais baixa, pálpebra de baixo mais achatada, um pouco mais larga) virou uma amêndoa comprida como a do Murdered e a do Siamês, e caiu na mediana dos gatos (abertura 0,086 contra 0,082, largura visível 0,169 contra 0,167).

Orelhas. De perto e de perfil, a nossa orelha mostrava uma grande janela oval: o corte da concha atravessava a parede de lado perto da base, como uma colher. Nos gatos, a parede do lado fica inteira e a cavidade abre para a frente. Também em duas rodadas: girar a orelha para a frente e achatá-la não fechava a janela, porque a causa era o corte. Parede mais grossa (ear_rim), corte mais para a frente (ear_cup), concha começando mais alto (ear_cup_base); a variante que fechava tudo (h) perdia a cavidade vista de frente, então ficamos no meio (i). Achatar e girar mudou o contorno, então o ajuste das orelhas do passo 15 (tools/fit_ears.py) reajustou a forma de fora aos contornos dos gatos: sobreposição de frente de 0,928 para 0,932, de lado de 0,871 para 0,852. Ficou mais perto do Murdered, mas a diferença de fundo é de construção: a nossa é um cone com uma concha escavada; a do gato é uma aba fina dobrada em cone na base. Se ainda incomodar, o próximo passo nas orelhas é refazê-las como aba dobrada.

olhos: antes, sd, se e sf, de perto orelhas: antes, g e ears_j, de frente, três-quartos e perfil
Claude

24Uma boca que abre: os lábios separados e o rig da mandíbula

07/11, 09:15 a 09:55

Os gatos vão falar, então a boca precisa abrir. Um controle novo, jaw_open (o ângulo, em radianos), faz a mandíbula girar numa dobradiça logo abaixo e à frente da orelha, onde fica a articulação da mandíbula de um gato. Com ele em 0, a cabeça é exatamente a de antes (conferido em 50 mil pontos).

Como funciona. Do mesmo jeito que o "skinning" de animação: cada ponto da cabeça fechada tem um peso, e com a boca aberta ele gira em volta da dobradiça pelo ângulo vezes esse peso. Para saber o que aparece em cada ponto da cabeça aberta, esse movimento é invertido por iteração (algumas passadas bastam, porque a dobra é suave). Uma superfície separa o lábio de cima da mandíbula: na frente, segue a linha do lábio e passa por baixo da marquise das almofadas; dos cantos da boca para trás, vai até a dobradiça. A boca só abre dentro dela, entre os cantos e na frente deles. Fora disso, a bochecha e a mandíbula dobram juntas, e a pele estica em vez de rasgar. Enquanto a boca está aberta, um oco por dentro (a cavidade da boca) deixa o céu da boca com a parte de cima e o chão com a mandíbula.

O caminho, com os erros. Cada versão errada foi diagnosticada num corte pelo meio da cara (cabeça fechada, cabeça aberta e a linha de separação):

  • medir o peso de cada ponto onde ele aparece, e não na cabeça fechada: a mandíbula virou uma placa fina, depois um pedaço solto, depois uma rachadura ao longo da bochecha até a orelha. A solução foi a do skinning: os pesos pertencem à cabeça fechada;
  • um peso que sumia rápido demais com a profundidade, para o pescoço ficar parado: o alto da mandíbula descia mais que o fundo, e ela dobrava sobre si mesma. Uma deformação não dobra se a distância em que o peso some for maior que o deslocamento que ela causa;
  • pesos diferentes nos dois lados da separação, abaixo dela: uma fenda no canto da boca;
  • abrir "na frente do canto" olhando só a profundidade: a cara inteira se abria na largura, até as bochechas. A boca também é limitada dos lados pelos cantos.

Onde está: com 11 graus a boca abre como boca, com o interior escuro, e a mandíbula continua presa à bochecha. Ainda há bordas serrilhadas nas paredes laterais da abertura e uma costura leve na bochecha, ao lado de cada canto.

boca fechada, aberta 0,20 e 0,35 radiano, ao lado do Murdered
Rafael

vai de rig, segue com os lábios separados

Rafael
Claude

Lábios separados e o rig da mandíbula. No jogo, quem abre a boca é o rig, com um osso de mandíbula na malha exportada, como em qualquer personagem de jogo. Então a cabeça matemática não precisa ficar perfeita aberta. Ela precisa entregar três coisas: a boca fechada com os lábios realmente separados (não grudados numa peça só), o interior da boca, e os pesos e a dobradiça para o osso.

Lábios separados. Um controle novo, mouth_gap, abre uma fenda fina ao longo da linha do lábio, só dentro da boca, ligando com a cavidade, que agora existe também com a boca fechada. A malha é feita por "marching cubes", que grudam duas superfícies mais próximas que umas duas células da grade, então a fenda tem 0,010 e a malha do jogo é feita numa grade mais fina (0,003). Antes do render, o corte pelo meio mostrou três erros, cada um com a sua causa:

  • no meio, a cavidade furava os lábios: ela estava medida a partir da pele da linha do lábio, mas o lábio de baixo fica recuado sob as almofadas. Agora termina 0,035 atrás do lábio de baixo;
  • uma rachadura vertical na mandíbula, no canto da boca: a fenda seguia a separação quando ela mergulha para sair da cabeça. Agora a fenda só existe onde a separação ainda está na linha do lábio;
  • perto dos cantos a fenda não chegava à cavidade, porque a linha do lábio desce (o "Y" invertido) e a cavidade não. Agora a cavidade acompanha a linha do lábio e é mais larga.

O teste do rig. Uma ferramenta nova (tools/rig_head.py) faz a malha fechada, dá a cada vértice o peso da mandíbula (o mesmo campo de pesos da abertura, que vive na cabeça fechada) e gira a mandíbula como um motor de jogo faria (skinning linear: cada vértice anda em direção à posição girada na proporção do seu peso). Três rodadas até ficar bom:

  • a abertura era um retângulo de paredes retas e fios atravessavam a boca: o peso pulava de 1 para 0 em 0,03 no canto, e a fenda era estreita demais em alguns pontos;
  • com a fenda mais larga, os lábios arredondados e o peso do lábio de baixo caindo em direção aos cantos (lente), apareceram "cortinas" verticais ao lado da boca: logo depois do canto, onde não há fenda, o peso era 0 logo abaixo da linha do lábio e quase 1 logo acima;
  • os pesos foram refeitos como nos rigs de rosto: dentro da boca, a fenda separa (lábio de cima 0; o de baixo 1 no meio e 0,5 nos cantos); fora dela, o peso atravessa a linha do lábio suavemente (1 a 0,06 abaixo, 0,5 na linha, 0 a 0,06 acima). As cortinas sumiram e as bochechas acompanham a mandíbula.

No Blender. Outra ferramenta nova (tools/blend_rig.py) monta o rig de verdade: um osso raiz e um osso de mandíbula na dobradiça, os pesos em dois grupos de vértices, e exporta out/rig/head.glb. Para conferir, o Blender gira o osso 0,3 radiano e comparamos os vértices com o nosso cálculo: a diferença foi 0,0 nos 521 mil vértices. O rig exportado é exatamente o que foi desenhado.

Resultado: a cabeça atual (params/sdf_head.json, agora a sdf_lips) tem os lábios separados; com a boca fechada, aparece só a linha da boca. Ainda falta: a borda do lábio de baixo fica ondulada quando abre, há um degrau no chão da boca, faltam dentes e língua, e a malha é pesada demais para o jogo (148 MB, 521 mil vértices), o que vai pedir uma versão leve que mantenha a fenda.

rig: boca fechada e aberta 0,2 e 0,35 radiano pelo osso da mandíbula
Claude

25A boca por dentro: uma linha só, dentes e língua

07/11, 09:55 a 10:21

Primeiro olhar, de novo: a nossa região de queixo, nariz e boca, fechada, ao lado de cinco gatos. Três diferenças, e a medida tratou cada uma:

  • o nariz parecia longe da boca. Medido, não está: das narinas ao centro do lábio de cima, a nossa tem 0,093, e os gatos 0,089 (de 0,074 a 0,104). O que enganava o olho era a linha da boca;
  • a linha da boca parecia um zíper: uma fenda reta e escura atravessando o focinho, onde os gatos têm o "Y" invertido (o filtro desce e dois arcos curtos caem e somem sob as almofadas). A causa: havia duas linhas de boca. O sulco desenhado na pele segue uma curva que desce no meio, e a fenda aberta para o rig seguia uma curva própria, mais achatada, até 0,02 acima do sulco. Agora a separação segue exatamente a curva do sulco (uma curva de Bézier quadrática, cujo x cresce em linha reta ao longo dela, então a altura em cada x sai direto), e a fenda fica no fundo do sulco: uma linha só, curva como a dos gatos;
  • o focinho parecia sem volume no três-quartos. Juntas mais firmes entre o focinho e a bochecha encolhiam o focinho e deixavam o nariz como uma bola grudada, e o erro do relevo subia (de 0,0071 para 0,0102 e 0,0142). A medida e o olhar concordaram que o focinho de hoje já é o mais próximo dos gatos; o "volume" que se vê neles vem dos bigodes e da sombra, não da forma. Não mudou.

A borda do lábio de baixo. Com a boca aberta, havia um degrau dentro do lábio de baixo: entre a fenda e a cavidade, o alto do lábio era uma faixa plana que caía num degrau. Arredondar mais a frente da cavidade, com o lábio mais fino, piorou: apareceu uma linha de boca dupla, porque o arredondamento (0,035) era maior que a espessura do lábio (0,028) e comia a pele de fora. A regra ficou anotada: o arredondamento tem que ser bem menor que a espessura. Com lábio de 0,045 e arredondamento de 0,03, a boca fechada volta a ter uma linha só, e aberta o lábio de baixo vira uma faixa curva como o "ω" do lábio de cima.

O rig foi refeito e conferido de novo no Blender (diferença de 1e-7).

boca fechada e aberta pelo osso, com uma linha só

Dentes e língua. Com a boca abrindo pelo rig, faltava o que aparece dentro dela. Dentes e língua são peças separadas, não escavadas na cabeça: viram partes da malha do jogo com pesos fixos (dentes de cima 0, presos ao crânio; dentes de baixo e língua 1, presos ao osso da mandíbula), e a cabeça fechada não muda nada.

Anatomia, simplificada para um personagem que fala. Em cada mandíbula, seis incisivos pequenos em fila na frente e um canino de cada lado; os caninos de cima são os mais longos. O canino de cima de um gato tem 8 a 10 mm, cerca de 0,09 na nossa unidade, mais do que a altura da boca por dentro (0,08), então os nossos têm 0,045; com a boca fechada as pontas ficam escondidas dentro da mandíbula, onde num gato os lábios os cobrem. Os dentes seguem o arco dental, logo para dentro da frente da cavidade, e a altura deles é medida a partir da linha do lábio, para acompanhar o "Y" invertido. A língua é longa e chata, deitada no chão da boca, com um sulco leve no meio. A ferramenta confere que nenhum vértice de dente ou língua fica fora da cabeça fechada.

A primeira língua era grande demais (uma cúpula rosa enchendo a boca); ficou mais baixa, mais fina e mais estreita. Ela sobe em direção ao fundo da boca quando a mandíbula abre, porque gira inteira com o osso e o fundo dela está perto da dobradiça, como num gato.

Nos renders, cor por vértice separa as partes: cabeça em argila, dentes marfim, língua rosa (os olhos, sem cor nesse preview, aparecem cinza). O rig foi exportado de novo e conferido no Blender (diferença de 1e-7 nos 556 mil vértices).

boca fechada e aberta 0,2 e 0,35 radiano, com dentes e língua
Desvio: orelhas, passos 26 e 27

Deu errado. A orelha como aba dobrada piorou, e as duas propostas seguintes foram recusadas ("parece um morcego"). A solução veio na branch da planta das orelhas.

mostrar os 2 passosesconder os 2 passos
Rafael

Vamos deixar a boca assim, por hora. No futuro, talvez voltamos nela. Quero melhorar as orelhas, conforme a sugestao anterior.

Rafael
Claude

26Orelhas refeitas como aba dobrada, e ficaram piores

07/11, 10:27 a 11:25deu errado

A boca ficou como estava, e partimos para as orelhas. Até aqui a orelha era um cone maciço com uma concha escavada na frente; a sugestão era refazê-la como uma aba dobrada.

Primeira olhada. Fizemos a orelha como uma lâmina de verdade: a casca do mesmo cone de antes (assim o contorno ajustado aos gatos no passo 15 continua valendo), aberta na frente. Um corte plano para abrir a frente deixou facetas chatas onde a orelha encontra o crânio e uma borda serrilhada. A versão que funcionou abre a lâmina por ângulo: em cada altura, ela só existe atrás de uma linha que passa pelo eixo do cone, e passada essa linha a distância é medida até a borda, um tubo com metade da espessura. A borda sai redonda por construção, sem corte para suavizar.

Depois, medir o que o olhar mostrou. Uma ferramenta nova (tools/ear_sections.py) corta a orelha direita de cada um dos 12 gatos em fatias horizontais, de 0,03 a 0,14 abaixo da ponta, e desenha as fatias vistas de cima. Ela mediu três coisas que não esperávamos:

fatia, abaixo da pontagatos (mediana)orelha antiga (cone)aba dobrada
espessura a 0,030,0330,0200,031
espessura a 0,060,0440,0340,043
espessura a 0,140,0680,0580,044
giro da fatia (borda de fora para trás)26° a 30°-8°25° a 35°
largura a 0,03 da ponta0,1040,0630,086
largura a 0,06 da ponta0,1490,1100,130
  • A orelha dos gatos não é papel. Cortada, ela é uma placa grossa curvada em crescente, que engrossa da ponta para a base. A primeira lâmina, com 0,02, era fina demais. Agora a espessura cresce para a base (ear_sheet, ear_sheet_grow).
  • A ponta é redonda. Perto da ponta a nossa orelha era uma agulha: 0,063 de largura contra 0,104 dos gatos. O raio da ponta virou um controle (ear_tip_r).
  • A orelha é girada. Nos gatos, a borda de fora fica para trás e a abertura olha para a frente e para fora, cerca de 28°. A nossa estava em -8°. O passo 23 tinha diminuído o giro para fechar a "janela" lateral, mas uma lâmina não tem janela, então o giro pôde voltar.

Também nas fatias apareceram dois erros nossos, cada um uma "conta" solta dentro da orelha perto da ponta: uma troca brusca entre a borda de dentro e a de fora bem no meio, e uma conta que supunha que a superfície mais próxima estava para o lado, quando na ponta arredondada ela está para cima. As duas foram corrigidas.

Por último, ajustar. O ajuste das orelhas (tools/fit_ears.py, agora com --flap) refez a forma de fora com a construção nova, incluindo o raio da ponta e o giro. Na primeira rodada ele aumentou a base do cone até 0,5 e a desceu, e na cabeça inteira apareceu o que o close não mostrava: uma concha oca descendo pelo lado da cabeça até a altura dos olhos. O contorno não enxerga isso, porque a silhueta é igual oca ou maciça. Três mudanças resolveram: a base ficou limitada ao tamanho antigo; perto da superfície do crânio a orelha é maciça (ear_fill), então o fundo da concha acompanha a cabeça; e a lâmina não fecha mais em anel na base, porque esse anel virava uma alça saliente no lado da cabeça. A borda vai direto até o crânio, como nos gatos. Por fim, os últimos 0,1 antes da ponta ficaram maciços (ear_tip_solid), porque a lâmina aberta sobre a ponta redonda deixava um ganchinho na borda.

Resultado: a orelha agora é uma placa curvada, de parede fina por inteiro, com a ponta arredondada e a abertura olhando para a frente e para fora. De trás, ficou parecida com a do Tabby e a do Siamês. Sobreposição dos contornos com a mediana dos gatos: de frente, de 0,932 para 0,949; de lado, de 0,852 para 0,846. A espessura e o giro caíram dentro da faixa dos gatos. Ainda falta: um vinco pequeno no fundo da concha, visível de trás. O rig não mudou (as orelhas têm peso 0); ele é exportado de novo junto com a malha leve.

orelhas: cone antigo e aba dobrada, de frente, três-quartos e de trás, ao lado de quatro gatos cabeça inteira com as orelhas novas fatias horizontais da orelha: cone antigo, aba dobrada e os 12 gatos
Rafael

As orelhas ficaram piores

Rafael
Claude

Olhando de novo o close, em três-quartos a aba virou uma folha enrolada: a borda ondula e dobra no alto, e a abertura parece um buraco arredondado. As orelhas dos gatos, a do Murdered sobretudo, são triângulos limpos, de bordas retas e firmes. Tínhamos adotado a aba porque as fatias diziam que espessura, giro e ponta tinham chegado perto dos gatos, mas essas medidas não veem a borda nem a limpeza do triângulo. É a mesma armadilha de antes: um número que bate não é um olhar que bate.

A cabeça atual (params/sdf_head.json) voltou para as orelhas do passo 23 (o cone com a concha). A aba continua no código, desligada, em params/sdf_ears_flap.json, e a ferramenta das fatias fica para medir.

Claude

27Orelhas: borda reta e ponta fina, "parece um morcego", e a lâmina enrolada

07/11, 11:25 a 12:33

O que piorou na aba ficou claro: a borda ondulada e enrolada, e a ponta redonda demais. A forma geral e o giro ficaram bons.

A ponta foi fácil: o raio da ponta voltou a 0,012 e ela ficou fina de novo.

A borda levou mais tempo. Os cortes da orelha no referencial dela mostraram de onde vinha a onda: a face de dentro da lâmina tinha um calombo no meio, porque a conversão de distância que usávamos falha quando a lâmina é quase tão grossa quanto o cone é fundo; e as bordas terminavam em "bulbos" que se enrolavam, porque ficavam onde o cone achatado faz a curva mais fechada, mais fechada do que a lâmina é grossa. Afinar a lâmina para a borda ajudou pouco. Subtrair do cone uma cópia dele do mesmo tamanho, deslocada para a frente, deu paredes de espessura zero, que se desfaziam.

O que funcionou foi o meio-termo, e é a orelha antiga feita direito: o cone menos uma concha um pouco menor (0,85 a 0,9 do cone) deslocada para a frente. A concha da orelha antiga começava mais acima da base, mas com o raio da base do cone, então furava a lateral (a "janela" do passo 23). Agora uma opção (ear_cup_follow) faz a concha acompanhar o afinamento do cone desde onde começa. As paredes afinam por igual até a borda, que sai reta e limpa, e o contorno e o giro são os da aba, que tinham sido aprovados.

fatia, abaixo da pontagatos (mediana)atual (cone)d3d4
espessura a 0,030,0330,0200,0250,025
espessura a 0,100,0520,0480,0580,059
espessura a 0,140,0680,0580,0680,071
giro26° a 30°-8°30° a 34°30° a 36°

As duas propostas diferem pouco: d4 começa a concha um pouco mais alto (base maciça maior). Desta vez não adotamos nada: a cabeça atual continua com as orelhas do passo 23 até a escolha.

orelhas: atual, a aba recusada, d3 e d4, de frente, três-quartos e de trás cabeça inteira: atual, d3 e d4
Rafael

Agora parece um morcego. Não ficaram legais. A orelha do gato não é tão pontiaguda. Nas referencias, ela forma um arco. Além disso, a parte da frente não forma uma barreira pro buraco do ouvido, a parte da frente precisa ser alinhada planamente com o resto da cabeca. As bordas devem ser finas, não gordas.

Rafael
Claude

Olhar de perto. Um close das orelhas de seis gatos, de frente, em três-quartos e de trás, confirmou os três pontos: o contorno é um arco (a borda de fora sobe quase reta, faz a curva no alto e desce pela borda de dentro, longa e inclinada até a testa); a testa entra direto na orelha, sem parede na frente do buraco, e a cavidade é mais funda embaixo, do lado de fora; e a borda é fina e arredondada.

A lâmina enrolada. Construímos ao pé da letra uma orelha que se aproxima de um cilindro com um meio círculo em cada ponta (ear_roll): um contorno plano em forma de cápsula (um círculo na base, um menor no alto, unidos por retas tangentes), enrolado num cilindro vertical como papel em volta de um tubo, fino e de borda redonda. Aqui as distâncias são exatas (a distância ao cilindro e o comprimento ao longo dele), então não aparece a onda da aba. De perto, a ponta em arco, a borda fina e a testa entrando na concha funcionaram. Na cabeça inteira, ainda não: de frente as orelhas abrem para os lados como folhas, mais baixas e mais afastadas que nos gatos. O ajuste pelos contornos não serve para essa construção: para encher a silhueta, ele achatou a lâmina e aumentou a base até ela virar uma aba deitada sobre a cabeça. Nenhuma delas virou proposta.

A pesquisa. Na internet, os guias de desenho falam de "triângulos de bordas arredondadas" e insistem que a orelha tem espessura e abertura; nada sobre a construção. O livro do Goldfinger só trata dos músculos da orelha. A série que encontramos (Pinegully, "How to Make a Cat in Blender", partes 1 a 3) foi mais útil. As legendas e trechos da parte 2 estão em data/videos/, fora do git. Na parte 2 (13:27 a 15:10), a orelha:

  • cresce de dentro da cabeça: ela apaga as faces da cabeça onde a orelha fica e estica esse anel para cima, primeiro até a base da orelha e depois até a ponta, e fecha o alto. A orelha é a própria superfície da cabeça continuando, com base larga e alongada da frente para trás;
  • tem a ponta em arco e, de lado, é uma barbatana de base larga;
  • tem a concha empurrada para dentro pela frente (pincel de inflar e esvaziar), deixando a borda fina e a frente continuando a testa;
  • tem uma dobrinha na base, do lado de fora (a "bolsa" marginal da orelha do gato, que o Siamês também tem), feita com algumas faces extrudadas;
  • e os detalhes modelados devem ser poucos: "muito do detalhe da orelha vem da textura".
a lâmina enrolada (m1, m3) ao lado do Murdered e do laranja, de frente, três-quartos e de trás
branch ears-blueprint: A planta 2D das orelhas

Saiu da main depois do passo 27; aprovada no B1 e de volta à main.

Rafael

Alias, o resultado q tivemos das orelhas esta seguindo num bom caminho

Rafael
Claude

B1A planta das orelhas tirada dos 12 gatos

07/11, 12:35 a 12:59aprovado

A ideia era usar imagens 2D de vários ângulos, como no tutorial. Em vez de baixá-las ou desenhá-las, tiramos essas imagens dos nossos 12 gatos. Eles já estão alinhados, na mesma escala, e dão desenhos sem perspectiva e coerentes entre si. Fotos escondem a orelha sob o pelo; desenhos de ângulos diferentes raramente batem. Como a lâmina enrolada (m1, m3) parecia o caminho certo, a planta foi usada para acertá-la.

A ferramenta (tools/ear_blueprint.py) desenha duas coisas:

  • as silhuetas da região da orelha de frente, de lado e de cima: cinza é a fração de gatos que cobre cada ponto, azul é a linha da metade dos gatos, e as nossas por cima, em cores;
  • a orelha no plano dela, vista de frente para a abertura, com a ponta para cima: é o "arco". Para cada cabeça, a orelha é a superfície acima do entalhe; o plano vem da direção em que esses pontos menos se espalham, e os triângulos são projetados nele. A mediana dos 12 é o arco dos gatos.

Dela saem números: a largura da orelha a 0,02, 0,05, 0,10 e 0,15 abaixo da ponta, o raio de um círculo ajustado à ponta (quão redondo é o arco), a altura do entalhe à ponta e para onde a abertura aponta (quanto gira para fora e quanto inclina).

O que ela mostrou. O arco da m3 já caía quase em cima do arco dos gatos: largura a 0,02 da ponta 0,104 contra 0,109, a 0,10 da ponta 0,210 contra 0,219, raio da ponta 0,070 contra 0,071. A forma estava certa. O erro era a orientação: a abertura girava 47° para fora (gatos 30°), que é o "abrir para os lados como folhas", e o plano estava em pé demais (inclinação -12°, gatos -49°). A orelha atual da main (o cone) mostra o contrário: é estreita e pontuda demais (largura a 0,02 da ponta 0,048, raio da ponta 0,030), que é o "morcego".

Acertando. Giramos e deitamos a orelha à mão até os números de orientação caírem na faixa dos gatos, compensando a altura (deitar para trás abaixa a ponta). Depois o ajuste das orelhas (tools/fit_ears.py --roll --only ear_x,ear_y,ear_z,ear_out) mexeu só na posição, com a forma congelada: a sobreposição com a silhueta mediana dos gatos foi de 0,73 para 0,945 de frente e de 0,74 para 0,827 de lado. Por fim, uma junção mais macia com a cabeça (ear_blend 0,12) tirou um friso que a parte de baixo da lâmina fazia deitada sobre o crânio.

orelhagatos (mediana)10% a 90%atual (cone)proposta
largura a 0,02 da ponta0,1090,089 a 0,1650,0480,122
largura a 0,10 da ponta0,2190,201 a 0,2640,1400,218
raio da ponta0,0710,060 a 0,1290,0300,077
altura0,2020,166 a 0,2450,1890,223
giro da abertura para fora30°16° a 45°13°26°
inclinação da abertura-49°-59° a -35°-56°-39°

Resultado (proposta): params/sdf_ears_blueprint.json. De frente as orelhas ficam no alto e abrem para a frente, com a borda de fora continuando a linha da cabeça; a ponta é um arco, a borda é fina e a borda de dentro desce até a testa, sem parede na frente. Ainda falta: um resto leve do friso no lado da cabeça, e a dobrinha da base (a "bolsa" marginal), que ainda não existe.

a planta: silhuetas e a orelha no plano dela, atual, m3 e a proposta cabeça inteira: atual e a proposta, ao lado de quatro gatos close: atual e a proposta, de frente, 30°, 60° e de trás
Rafael

Sim. Ficou muito melhor. Aprovado.

Rafael
Claude

A proposta virou a cabeça atual (params/sdf_head.json = sdf_ears_blueprint.json) e esta branch voltou para a main. Ficam para depois a dobrinha da base (a "bolsa" marginal) e o resto leve do friso no lado da cabeça. O rig é exportado de novo junto com a malha leve.

branch head-anatomy: A cabeça por anatomia

Saiu da main depois do passo 27; a crista (A3) e a bochecha (A4) aprovadas e de volta à main.

Claude

A1As pranchas dissecadas e a primeira no nosso referencial

07/11, 13:05 a 13:18

A proposta era usar uma referência dissecada (o gato sem pele, só ossos e músculos) para modelar a cabeça, testando primeiro numa região. Já tínhamos tentado em 06/11 reconstruir a cabeça "crânio, músculos, pele" contra um crânio escaneado e um écorché 3D; o crânio saiu com "cara de massinha" e o plano parou antes dos músculos. A diferença agora é usar as pranchas como planta, como fizemos com as orelhas: o desenho mostra, o 3D mede.

As referências (domínio público, no Internet Archive; os PDFs ficam em data/anatomy/, fora do git):

  • Reighard e Jennings, Anatomy of the Cat (1901): o crânio de cima, de lado e de baixo (figuras 39 a 41) e os músculos superficiais da cabeça (63 e 64);
  • Williams, The bones, ligaments, and muscles of the domestic cat (1875): cópias das pranchas de contorno do Straus-Durckheim (1845), o atlas de anatomia do gato mais detalhado do século 19; o gato inteiro de lado em camadas de músculos, o esqueleto e os ossos do crânio separados. Nelas a cabeça é pequena. No arquivo digital, os rótulos dos dois volumes estão trocados: as pranchas estão no que se chama "Text".

A primeira prancha no nosso referencial. Uma ferramenta nova (tools/anatomy_plate.py) põe uma prancha na nossa escala e no nosso lugar, encaixando-a no crânio escaneado, que já está posicionado dentro da nossa cabeça. A figura 40 (o crânio de lado) foi espelhada para o nariz ficar à direita; tiramos as letras e números (pedaços pequenos de tinta), fechamos o contorno e preenchemos o miolo para ter a silhueta do desenho. O encaixe casa as duas pontas do crânio, dos incisivos ao fundo do crânio, ao longo do eixo principal de cada silhueta: o comprimento do crânio é a medida mais estável entre dois gatos diferentes.

No caminho erramos três vezes, e vale anotar: o corte da figura começava baixo e arrancava o alto do crânio; maximizar a sobreposição puxava a escala para o lado errado (o crânio desenhado é mais alto que o escaneado); e a nossa transformação da imagem usava a rotação direta onde precisava da inversa, o que estragava todas as tentativas. Corrigido, as pontas caem no lugar e a sobreposição com o crânio escaneado é 0,87.

Resultado: o crânio desenhado dentro da nossa cabeça, na nossa escala. Já se vê a região do teste: a órbita, o arco zigomático por baixo dela e quanto de bochecha a nossa cabeça põe sobre o osso.

a figura 40 do Reighard no nosso referencial: traço = prancha, azul = crânio escaneado, laranja = nossa cabeça
Claude

A2Os músculos e a primeira tentativa na lateral da cara

07/11, 13:18 a 13:39deu errado

Os músculos no nosso referencial. A prancha IV do Straus-Durckheim (a terceira camada de músculos) mostra a cabeça de lado com os números do índice: 24 é a primeira cabeça do masseter, 23 e 15 o arco zigomático (o processo zigomático e o osso malar), 22 o temporal, 9 a mandíbula. Ela não mostra o crânio inteiro, então foi encaixada por dois pontos que existem nela e na nossa cabeça: o centro do olho e a ponta do nariz. O olho dela cai na nossa órbita e o arco dela cai sobre o arco do crânio desenhado, o que confirma o encaixe. Tentamos recortar cada região preenchendo a partir do número, mas os contornos desenhados não fecham (o preenchimento vazava para o papel); traçamos à mão, sobre uma grade, os contornos do masseter, do arco, do temporal e do corpo da mandíbula.

Uma conta que muda a abordagem. No nosso referencial a cabeça tem cerca de 1,0 de largura nas bochechas, e o arco zigomático do crânio fica a 0,29 do meio: nos gatos de referência há uns 0,15 a 0,2 de tecido e pelo por fora do osso, de cada lado. Os músculos dizem onde ficam as formas, não onde fica a superfície.

A tentativa. Trocamos as três massas genéricas da bochecha (maçã do rosto, mandíbula, papada) por massas com o contorno lateral traçado (masseter, arco, temporal), empurradas até uma face lateral e cobertas por uma camada de tecido. A primeira versão desfez a boca (a massa da mandíbula ia até os lábios, onde a fenda da boca é cortada depois) e deixou placas chapadas. Com as massas arredondadas como almofadas e sem a mandíbula, a boca voltou, mas o resultado continua pior que a cabeça atual: de perfil, uma placa com os cantos do contorno traçado; de frente, bochechas em calombos.

O que isso mostrou. Medindo, o centro do masseter traçado (z -0,01, y -0,13) fica dentro da região que a maçã do rosto e a papada atuais já ocupam: as massas atuais, ajustadas aos gatos, já estão onde a anatomia diz. Construir a bochecha a partir de contornos traçados deu formas piores, porque por fora quem manda é o tecido e o pelo, não o músculo.

a prancha IV (vermelho) sobre o crânio desenhado (preto) e o escaneado (azul), com os contornos traçados a bochecha refeita pelos contornos (an1, an2) ao lado da cabeça atual e de dois gatos
Claude

A3Ajustes pontuais: a crista do arco sob o olho

07/11, 13:40 a 14:00aprovado

Decidimos usar as pranchas como conferência para ajustes pontuais na cabeça atual. Primeiro, olhar: um close da bochecha de três-quartos e de lado, na nossa cabeça e em cinco gatos. Nos gatos (Tabby, Siamês, Murdered, um pouco no laranja) há uma crista suave que sai de baixo do canto de fora do olho e vai para trás, em direção à orelha: o arco zigomático aparecendo sob a pele, com o plano da bochecha mudando abaixo dela. A nossa bochecha é toda lisa e redonda.

A crista (zyg, desligada por padrão) segue a linha central do arco traçado na prancha IV, posta sobre a nossa pele: cada ponto da linha é levado até a pele por uma busca vinda de fora, e uma cadeia de cápsulas fica uma fração acima dela. A primeira versão ficou forte demais: um "tubo" colado na bochecha, com as pontas marcadas. Com a crista larga e baixa, afinando nas duas pontas, ela vira uma mudança de plano. As versões mais baixas fazem um "papo" logo abaixo do olho; subindo 0,03, ela fica parecida com a do Siamês. Proposta: params/sdf_zyg.json (0,007 de altura, 0,08 de largura).

Uma nota para comparar folhas: a folha da cabeça inteira põe todos os modelos numa única cena com câmera em perspectiva, então a primeira coluna é vista de um ângulo um pouco diferente das do meio. As orelhas da primeira coluna pareciam diferentes por isso; os parâmetros e as distâncias são idênticos.

close da bochecha: atual, duas versões baixas e a proposta, ao lado do Tabby e do Siamês cabeça inteira: atual e a proposta
Rafael

Interessante, realmente ficou bom dessa vez

Rafael
Claude

A crista virou parte da cabeça atual (params/sdf_head.json = sdf_zyg.json) e foi para a main. Este caminho continua aberto para os próximos ajustes pontuais.

Claude

A4O masseter: a massa da bochecha mais para trás

07/11, 14:01 a 14:58aprovado

O problema: nas pranchas, o masseter (o músculo que fecha a mandíbula) vai da parte de baixo do arco zigomático até a mandíbula e, nos felinos, passa da borda de trás e de baixo dela (é ele que faz a bochecha e a papada do gato). Nos gatos, a bochecha atrás do canto da boca parece ter volume, e no Tabby há uma linha que desce do olho pela bochecha. A nossa bochecha é lisa e redonda.

Primeiro, olhar e tentar o óbvio: uma elevação dentro do contorno traçado. A primeira versão empurrava a pele para fora dentro do contorno do masseter da prancha IV: saiu um platô com os cantos do polígono traçado e uma rampa íngreme demais. Trocando o polígono por uma elipse com a mesma área e orientação, ficou liso, mas virou um "botão" redondo na mandíbula. Deixando a massa se estender para trás e para baixo (só a borda da frente aparece), ficou uma placa em meia-lua colada na bochecha. Nenhuma lembrava os gatos. O código ficou desligado (masseter = 0).

a elevação do masseter em quatro variantes (p1 a p4), ao lado do Tabby e do Siamês: parece uma placa colada

Depois, medir o que o olho viu. Uma medida nova, o relevo lateral: olhando a cabeça de lado, para cada ponto (z, y) de uma grade sobre a bochecha, quanto a pele sai para fora (o x dela). Desenhamos isso como um mapa sombreado e um mapa de curvatura (vermelho onde a pele estufa, azul onde ela faz vinco), na nossa cabeça e em quatro gatos, e comparamos números nos 12 gatos bons. Duas descobertas:

  1. A linha do Tabby não é músculo, é pelo. Ela sai do canto de fora do olho e desce na diagonal para trás, exatamente onde a pelagem tabby pinta a listra da bochecha. O Siamês, o Murdered e o laranja não têm essa linha. O gerador que fez o Tabby esculpiu a pintura do pelo na forma. Não é uma forma para copiar.
  2. O que falta é a massa no lugar certo. Nos 12 gatos a bochecha é mais larga atrás (perto da orelha) e se fecha em direção ao focinho. A nossa carrega o volume mais para frente: falta 0,02 a 0,04 atrás e embaixo (onde fica o masseter) e sobra 0,02 a 0,07 na frente, atrás do canto da boca. A diferença entre os próprios gatos ali é bem menor que isso, então é uma diferença real.

O ajuste. Em vez de acrescentar uma forma, movi as que já existem (as massas da maçã do rosto, da papada e da mandíbula) com uma ferramenta nova, tools/fit_cheek.py, que ajusta esses números ao relevo lateral mediano dos gatos. A diferença média na bochecha caiu de 0,0195 para 0,0048: a papada cresceu e foi 0,14 para trás, a mandíbula ficou mais estreita. Os dentes e a língua continuam dentro da cabeça (o rig depende disso).

Proposta:

  • params/sdf_cheek_a.json: bochecha, papada e mandíbula ajustadas (diferença 0,0048). A mandíbula parou no limite que demos a ela (0,6).
  • params/sdf_cheek_b.json: só bochecha e papada, mandíbula como está (diferença 0,0087).

De perto a mudança é sutil: a bochecha fica mais cheia atrás e embaixo, e o lado do focinho, atrás da boca, mais fino; de frente, a cabeça fica um pouco mais "quadrada" embaixo, como a do Murdered. Ainda resta, no mapa de curvatura, um vinco raso na horizontal entre a maçã do rosto e a papada (y -0,07), que os gatos não têm; nas renderizações ele quase não aparece.

relevo lateral: sombreado em cima, curvatura embaixo (vermelho estufa, azul vinco), laranja = contorno do masseter da prancha; atual, a proposta a e quatro gatos close: atual, a, b e três gatos, de frente, três-quartos e de lado cabeça inteira: atual, a, b e quatro gatos

A bochecha com textura (teste rápido). Antes de decidir, quisemos ver como a proposta a ficaria com textura. Ainda não temos uma pelagem nossa (ela espera a forma ser aprovada), então fizemos um atalho, tools/coat_preview.py: como a nossa cabeça está no mesmo referencial que o Tabby, cada ponto da nossa superfície pega a cor do ponto mais próximo da superfície do Tabby, lida na textura dele. Os olhos pegam a cor da região do olho do Tabby do mesmo jeito.

O que dá para ver: com as listras, a cara lê como gato muito mais do que em argila, e a diferença entre a atual e a a fica nas bochechas de baixo, um pouco mais cheias atrás na a. Limitações do atalho: no pescoço aparecem faixas esticadas (ali o Tabby já foi cortado, então o ponto mais próximo é a borda do corte), e onde a nossa forma é diferente da dele (orelhas, boca, abertura dos olhos) as cores esticam ou ficam fora do lugar. O olho pintado do Tabby é menor que a nossa abertura, então os olhos parecem meio fechados.

a textura do Tabby passada para a cabeça atual e para a proposta a, ao lado do próprio Tabby
Rafael

b

Rafael
Claude

A bochecha e a papada ajustadas ao relevo lateral dos gatos, com a mandíbula como estava, viraram parte da cabeça atual (params/sdf_head.json = sdf_cheek_b.json) e foram para a main.

Claude

28A malha leve para o jogo

07/11, 14:59 a 15:13

O problema: a cabeça vem da função de distância por marching cubes num passo de 0,003 (fino assim para os lábios ficarem separados), o que dá 1,2 milhão de triângulos e um glb de 184 MB. Um jogo quer alguns milhares de triângulos por cabeça.

Como se faz nos jogos ("esculpe denso, joga leve"). A malha densa vira só a fonte do detalhe. Uma malha leve, com a mesma forma, é o que vai para o jogo; o que ela perde (as pequenas dobras da superfície: borda das pálpebras, couro do nariz, linha do lábio) fica guardado num normal map, uma imagem cujos pixels inclinam a normal da malha leve na hora de iluminar, como a superfície densa inclinaria. Ferramentas novas: tools/game_head.py (Python) e tools/blend_game.py (Blender):

  1. As partes densas, como o rig já fazia: a cabeça fechada com os lábios separados, os dentes de cima e de baixo, a língua, e agora os dois globos oculares (esferas com o polo no eixo do olhar, para a íris ficar em volta do polo mais tarde).
  2. A simplificação: cada parte perde triângulos por colapso de arestas, sempre onde o colapso mexe menos na superfície (a medida é a soma das distâncias ao quadrado aos planos dos triângulos em volta, o método de Garland e Heckbert, 1997). A pele fica com 12 mil triângulos, dentes e língua com 400 cada.
  3. Os pesos da mandíbula são calculados de novo nos vértices leves (eles vêm de uma fórmula sobre o espaço, não precisam ser copiados da malha densa).
  4. No Blender: as UVs (a malha cortada em ilhas e aberta no plano), o bake do normal map (para cada pixel, um raio curto sai da malha leve e volta até a densa, e a normal de lá é gravada), o esqueleto com o osso da mandíbula e o glb.

Dois tropeços no bake. Os raios longos atravessavam a pálpebra até o globo ocular e a fenda até o outro lábio, o que deixava pontinhos pretos (normais viradas para trás). Encurtamos os raios (a malha leve fica a 0,0002 da densa, em média) e passamos a trocar por "plano" os pixels inclinados mais de 55 graus, que só podem ser erros: 0,64% da imagem, quase tudo dentro da boca.

Resultado:

  • 15.888 triângulos ao todo (12 mil na pele), contra 1,2 milhão; glb de 2,4 MB com o normal map de 2048 dentro, contra 184 MB.
  • Distância da malha leve até a densa: média 0,0002 e máxima 0,0012 da largura da cabeça (num gato de verdade, centésimos de milímetro).
  • Nenhuma "cortina" ligando o lábio de cima ao de baixo, e a boca abre limpa pelo osso da mandíbula, com dentes e língua.
  • Com o normal map, a leve fica mais parecida com a densa do que sem ele: a dobra da pálpebra volta e as facetas da bochecha somem.
  • O glb abre no Blender com a malha, o esqueleto (root e jaw), os dois grupos de pesos e o material com o normal map.

Ainda falta: um traço bem fraco embaixo de um dos olhos e uma costura sutil na bochecha, os dois só com o normal map; a malha leve não é simétrica (cada lado foi simplificado por conta própria); os olhos são esferas lisas, sem íris.

malha densa, leve e leve com normal map (cabeça inteira e closes), e a leve com a boca aberta pelo osso da mandíbula
Rafael

Vamos deixar a parte de otimizacao de vertices pro final, la a gente define ate onde da pra ir.

Rafael
Claude

29O traço embaixo do olho e a costura na bochecha

07/11, 15:15 a 15:40

Antes disso, o traço embaixo do olho, a costura na bochecha e o corpo.

A causa. Pintamos de vermelho as bordas das ilhas UV da malha leve. O Smart UV Project tinha cortado a pele em cerca de 300 ilhas, com bordas em zigue-zague passando pela testa, pela bochecha e por baixo dos olhos. As duas marcas ficavam exatamente em cima de bordas: na costura, os pixels dos dois lados do normal map não combinam perfeitamente, e a luz mostra um traço.

O que testamos antes. O xatlas, outra abertura automática, deu de 175 a 350 ilhas do mesmo jeito. Abertura automática não sabe o que fica à vista.

A solução: escolher onde cortar. Agora o tools/game_head.py decide as costuras pela própria função da cabeça, e só onde ninguém olha:

  • em volta da base de cada orelha (onde a orelha passa a estar mais perto que o crânio);
  • na linha onde a pálpebra encontra o globo ocular (a pele escondida atrás do olho vira uma ilha própria, e essa linha já é um vinco escuro);
  • por dentro dos lábios (a fenda e a cavidade da boca);
  • no meio da nuca, de cima a baixo (sem esse corte a casca da cabeça seria um saco fechado, que não abre no plano).

A cara inteira virou uma ilha só, aberta no Blender pelo método de menor esticamento. Um segundo tropeço: o Smart UV, que continua abrindo dentes, língua e olhos, empacotava essas partes na escala delas, e os dentes ganhavam três vezes mais pixels que a cara. Igualamos a escala de todas as ilhas antes de empacotar; a cara foi de 600 para cerca de 800 pixels por largura de cabeça.

Resultado: 6 ilhas na pele, em vez de 300; o traço embaixo do olho e a linha na bochecha sumiram (antes em cima, agora embaixo). O resto ficou igual: 15.888 triângulos, distância média de 0,0002 até a malha densa, nenhuma cortina, glb de 2,2 MB. Ainda falta: a malha leve não é simétrica, os olhos não têm íris, e a quantidade de triângulos fica para o fim.

closes antes (Smart UV) e agora (costuras escolhidas) a malha leve com as costuras novas
Claude

30O corpo: os gatos no chão e o primeiro esboço

07/11, 15:30 a 15:52

Quais gatos servem. Dos 33 modelos de referência, 20 têm corpo inteiro. Vistos de lado na mesma escala, 8 estão em pé nas quatro patas, perto da pose de repouso: idle, orange, grey, tuxedo, murdered, sculpt, sf980 e sf1166. Ficaram de fora os que andam (uma pata no ar), o filhote, os sentados e deitados, a Sphynx em pé (raça de corpo longo e fino) e o sf1549, que usa um cachecol que enche o peito.

A régua (tools/body_refs.py). Todos os gatos já estavam no referencial da nossa cabeça, na mesma escala, porque foram encaixados pela cabeça. O que muda é a pose: um gato olhando para baixo tem o corpo inteiro inclinado nesse referencial. Então cada gato é apoiado no chão: o chão é a maior face de baixo do fecho convexo (a "embalagem" mais justa em volta do modelo), que num gato em pé encosta nas quatro patas. As patas são os pontos rentes ao chão, separados em frente e trás pelo maior vão e depois em esquerda e direita. Os gatos de poucos polígonos têm vértices muito espaçados, então a medida usa 300 mil pontos espalhados pela superfície. Medidas, em larguras de cabeça (mediana dos 8):

  • cernelha (o alto das costas sobre as patas da frente) 1,99 e quadril 2,03 acima do chão: as costas são quase retas;
  • barriga a 1,12 do chão; o peito desce mais, até uns 0,85 logo atrás das patas da frente;
  • patas da frente e de trás 1,77 afastadas; de um lado ao outro, 0,59 na frente e 0,73 atrás;
  • pernas com uns 0,2 de espessura de lado e 0,25 a 0,3 de frente;
  • a pata de trás em zigue-zague, mesmo parada: a meio da perna, a 0,55 do chão, ela vai 0,28 para trás (o jarrete, o calcanhar do gato, que fica alto porque o gato pisa na ponta dos dedos) e volta para cima da pata no joelho, a 1,0;
  • a cabeça a 2,19 do chão e 0,59 à frente das patas, sem inclinação (mediana 0,3 grau).
os 8 gatos no chão, de lado e de cima, com patas, linha das costas e da barriga e a mediana

O esboço (faber/cat_body.py). Como um escultor começa um animal: poucas massas com nome, cada uma uma forma simples, juntadas por união suave. O tronco é o peito (a caixa torácica), o lombo e a garupa; a perna da frente é o ombro, o antebraço e a pata; a de trás é a coxa, a canela até o jarrete, o pé até a pata e a pata; e ainda o pescoço, que se funde ao pescoço da cabeça, e a cauda reta para trás, como pede a pose de repouso. Os números vêm das medianas, e conferimos o esboço com a mesma régua dos gatos: todas as medidas caem dentro da faixa deles.

Duas correções no caminho, vistas na folha: as costas afundavam entre o lombo e a garupa (uma corcova; 1,91 contra 2,04 dos gatos), resolvido com um lombo mais longo e uma junção mais suave; e uma linha em volta do peito, como a barra de um colete. A cabeça é cara de calcular, então longe dela uso só um limite inferior da distância; esse limite começava na borda da caixa da cabeça e cortava a fusão com o corpo bem ali. Agora a cabeça é calculada de verdade até 0,4 fora da caixa, mais longe que o alcance da fusão.

Comprimento da cauda: 2,4, o do único gato com a cauda reta (Murdered); os outros a têm enrolada ou levantada.

o esboço do corpo com a nossa cabeça, ao lado de idle, orange, murdered, sf1166 e grey, na mesma escala

É uma proposta: nada foi adotado além do próprio esboço. Diferenças que já vejo: a cabeça fica um pouco baixa e à frente (o pescoço parece curto), a coxa ainda aparece como uma massa separada, as patas são simples e a cauda é um tubo reto.

Rafael

Vamos analisar a anatomia pra continuar o corpo. Esse primeiro esboco parece interessante, daí podemos comecar a explorar a anamotima pra polir isso, considerando o esqueleto e os musculos

Rafael
Claude

31A anatomia do corpo: o esqueleto dentro dos gatos

07/11, 15:55 a 16:05

As fontes.

  • Um esqueleto de gato inteiro em 3D: "Feline Skeleton Dec", do westerly (CC-BY), que é o mesmo autor do écorché que já tínhamos (o gato sem pele, só músculos). Os dois estão no mesmo lugar e na mesma pose, então o esqueleto fica exatamente dentro dos músculos. A pose não é a nossa de repouso (pernas um pouco abertas), mas o comprimento de cada osso não depende da pose.
  • Os livros: Goldfinger p. 167 e 168 (esqueleto e músculos superficiais do gato doméstico) e as pranchas do Straus-Durckheim reproduzidas no Ellenberger (p. 137 a 140: o gato em pé, os músculos profundos e os superficiais). O que guiou a leitura: "a borda de cima da escápula costuma ficar mais alta que as pontas das vértebras torácicas" (são as escápulas que fazem a cernelha), a caixa torácica é pequena, o gato pisa na ponta dos dedos. Nas pranchas, o tríceps faz uma massa grande atrás do braço, o fêmur desce para a frente até o joelho, a tíbia volta para trás até o jarrete, e a coxa (bíceps femoral) cobre a pelve por fora.

O esqueleto medido (tools/body_skeleton.py). O modelo se separa em 246 peças, uma por osso. Os ossos grandes recebem nome pela posição: crânio, mandíbula, pelve, sacro, escápula, úmero, ulna, rádio, fêmur, tíbia, fíbula e calcâneo; o resto vira coluna, costelas, pés e cauda. A escala vem do crânio dele comparado ao crânio escaneado que já está no nosso referencial: 1,29 (incerteza de uns 5%, porque o crânio dele é um pouco mais comprido para a largura). Nessa escala, em larguras de cabeça: úmero 0,88, rádio 0,86, fêmur 0,92, tíbia 0,90, escápula 0,59, pelve 0,95; caixa torácica com 1,45 de comprimento, 0,77 de largura e 0,85 de altura. São tamanhos de um gato de verdade (fêmur de uns 10 cm).

o esqueleto na nossa escala, ossos com cor e articulações marcadas

O esqueleto dentro dos gatos. Na mesma escala, alinhado no chão e nas patas da frente:

  • dentro do écorché, encaixa perfeitamente (a conferência da escala);
  • dentro do Murdered (o gato realista de um jogo grande), também encaixa: a coluna logo abaixo da linha das costas, costelas e perna da frente por dentro;
  • dentro do orange e do nosso esboço, a coluna passa uns 0,3 acima das costas. Os pés batem: o jarrete do esqueleto fica a 0,55 do chão e o punho a 0,28, como nos gatos. O que muda é o corpo: a mediana dos gatos de referência, e por isso o nosso esboço, tem o corpo uns 18% menor para o tamanho da cabeça que a anatomia real (cabeça grande e corpo baixo e largo, um pouco "fofo", comum em gatos de jogo; o pelo e a gordura também engordam a silhueta);
  • reduzido a 0,82, o esqueleto cabe no nosso esboço.
o esqueleto no écorché, no orange, no Murdered, no nosso esboço, e reduzido a 0,82 no nosso esboço

A decisão: seguir a anatomia real (corpo uns 20% maior em relação à cabeça, mais alto e mais longo, como o Murdered) ou manter as proporções dos gatos de referência (o esboço atual, com o esqueleto reduzido para caber). Em qualquer caso o esqueleto entra no corpo: as articulações viram as do rig, e os músculos passam a ser massas presas aos ossos.

Rafael

Anatomia real.

Rafael
Claude

32A escolha: anatomia real, e o esqueleto em pé

07/11, 16:08 a 16:18

O corpo cresce para caber o esqueleto no tamanho medido, como o Murdered.

O esqueleto já está quase na pose de repouso. As quatro patas estão sob o corpo, a perna da frente na vertical, as costas niveladas (com o arco natural do lombo). Só o pescoço não: ele corre quase na horizontal e a cabeça fica baixa e à frente, como num gato espreitando.

Duas rotações (tools/body_rest.py). O pescoço gira para cima na junta entre a última vértebra do pescoço e a primeira do peito, levando as sete vértebras cervicais e o crânio; depois o crânio acena na junta com a primeira vértebra até a cabeça ficar nivelada. As duas metas puxam uma contra a outra. Este pescoço (uns 0,5 de comprimento) só põe a cabeça na altura dos gatos (2,67, a mediana na escala anatômica; o Murdered tem 2,69) ficando quase em pé, e aí a cabeça recua para cima dos ombros:

altura da cabeçalinha do pescoçocabeça à frente das patas (gatos: 0,72)
2,6778 graus0,50
2,6060 graus0,67
2,5044 graus0,80

Ficamos com 2,60: as duas medidas ficam a menos de 0,07 dos gatos.

A nossa cabeça no esqueleto. O crânio escaneado já vive no referencial da nossa cabeça. Encaixamos esse crânio no crânio do esqueleto por ICP (o encaixe que alterna dois passos: parear cada ponto com o mais próximo da outra superfície, depois achar a rotação e o deslocamento que mais aproximam os pares), descartando a cada rodada os 10% de pares mais distantes (partes que um crânio tem e o outro não). Sobra uma folga média de 0,018. O ICP pronto do trimesh parava na hora e devolvia uma posição errada, por isso escrevemos o nosso. Também erramos o sentido de uma rotação na primeira tentativa (a cabeça desceu em vez de subir); a folha mostrou na hora.

o esqueleto em pé com a nossa cabeça (contorno) e o esboço antigo, em cinza claro, para a escala

O esboço antigo, em cinza claro, mostra quanto o corpo vai crescer: as costas sobem uns 0,3, e as patas da frente e de trás ficam 2,46 afastadas (eram 1,77).

Claude

33Os músculos presos ao esqueleto

07/11, 16:20 a 16:34mais recente

A ideia. Cada grupo muscular vira uma massa com nome, posicionada pelos ossos do esqueleto em pé: a posição sai das articulações e das pontas dos ossos (ombro, ponta do cotovelo, as duas pontas do fêmur, caixa torácica, pelve, linha da coluna); os números são só tamanhos e pequenos deslocamentos. Uma massa que corre ao longo de um osso é desenhada no referencial do próprio osso, então, quando o rig girar o osso, ela vai junto. Os grupos (faber/body_muscles.py), pelas pranchas do Goldfinger e do Straus-Durckheim e pelo écorché:

  • tronco: o tórax (a caixa torácica com os músculos deitados sobre ela), os músculos longos das costas dos dois lados da coluna, a barriga entre as costelas e a pelve, a garupa (glúteos) sobre a pelve;
  • perna da frente: o ombro (os músculos sobre a escápula, uma massa achatada no plano dela), o tríceps (de trás da escápula até a ponta do cotovelo), o braço (bíceps, na frente do úmero), o antebraço e a pata;
  • perna de trás: a coxa (bíceps femoral, quadríceps e semitendinoso em volta do fêmur), a panturrilha (gastrocnêmio, de trás do joelho até o calcanhar), a canela, o pé e a pata;
  • o pescoço e a cauda.

O alvo é o écorché. Ele está na mesma pose do esqueleto, que é a nossa de repouso, menos no pescoço e na cauda (que ficam fora da comparação). A medida é de volume: numa grade de pontos sobre o corpo, quanto o "dentro" das nossas massas coincide com o "dentro" do écorché. O ajuste mexe só nos tamanhos.

Um tropeço. O primeiro ajuste encolheu o peito até virar uma faixa fina. O écorché não é um sólido: cada músculo é uma superfície aberta, e o teste de "dentro ou fora" só marcava as paredes, deixando o interior do tronco vazio. Agora o "dentro" vem de preencher o espaço fechado pelas paredes, fatia por fatia nas três direções, e um ponto conta como dentro quando duas das três concordam.

Resultado: sobreposição de 0,59 para 0,86 no corpo todo. Tronco 0,94; costas e garupa 0,93; ombro e braço 0,87; coxa 0,86. As partes finas ficam piores (antebraço 0,52, canela e pé 0,65), porque nelas um erro pequeno de raio pesa muito no volume.

contornos de lado, de frente e de cima: o écorché (cinza) e as nossas massas (laranja)

Em Cycles, com a nossa cabeça no lugar que o esqueleto dá, a camada de músculo lê como um boneco articulado: ombro, coxa e patas aparecem como peças separadas. Num gato é a pele e a gordura que alisam essas junções. Um teste rápido, sem medir, com junções mais macias e uma pele uniforme por cima, já lê como gato (a terceira coluna); as patas ainda são bolotas e a cauda é um fio.

os nossos músculos com a cabeça, o écorché e o Murdered teste da pele: músculos, junção 0,15 com pele 0,04, junção 0,25 com pele 0,06
Claude

34Próximos passos

07/11, 16:34plano
  1. A pele de verdade: a camada sobre os músculos (gordura, pele, a espessura do pelo curto), ajustada à silhueta dos gatos de referência na escala anatômica (o Murdered e a mediana dos outros, aumentada para a proporção real), região por região.
  2. Cada grupo muscular de perto contra o écorché e as pranchas, começando pelo ombro e pela coxa, que hoje são as peças que mais aparecem.
  3. Patas e cauda com forma própria (dedos e almofadas; a cauda reta, afinando, como pede a pose de repouso).
  4. Os ossos do rig do corpo a partir do esqueleto em pé.
  5. A quantidade de triângulos e os níveis de detalhe, no fim. Depois do corpo, cada etapa ganha a sua própria timeline: variações, textura e pelagem, animação.