Notas
Como o Vitrola é feito
Uma Technics SL-Q3 de 1979 renderizada no Cycles, um grupo de luz por vez, com a luz misturada ao vivo no Metal pela hora do dia.
Matheus Fidelis, São Paulo
O Vitrola é um papel de parede para Mac: uma Technics SL-Q3 numa mesa perto de uma janela em São Paulo. Quando o Spotify ou o Música toca, o prato gira, o braço desce no disco e a capa no suporte vira o álbum que está tocando. A luz segue o seu relógio. Eu queria que parecesse uma foto e custasse quase nada pra ficar ligado o dia todo. A maior parte das decisões abaixo vem de segurar essas duas coisas ao mesmo tempo.
A vitrola
Modelei a SL-Q3 no Blender a partir do manual de serviço e de uma pasta de fotos de referência: corpo de 430 × 130 × 375 mm com a tampa, prato de 312 mm com os pontos do estroboscópio, braço em S com 230 mm de comprimento efetivo. Cada rodada de modelagem era renderizada nos mesmos ângulos das fotos e comparada lado a lado, e as três maiores diferenças eram corrigidas antes da rodada seguinte. As peças que se mexem (prato, braço, alavanca do cue, tampa) são objetos separados com a origem nos pivôs reais, porque o app precisa saber exatamente onde elas giram. O desgaste veio por último: poeira nos sulcos do tapete, riscos circulares na borda do prato, a serigrafia do start/stop gasta onde o dedo apertava.
Renderizar a luz, não a imagem
Nada é renderizado em 3D no seu Mac. Cada enquadramento (aberto, médio, fechado e de cima) é renderizado no Cycles em 3456 × 2234, a resolução nativa de um MacBook Pro de 16″, mas não como imagem pronta. A luz da cena é separada em grupos: sol, céu, luminária, preenchimento e as luzes da cidade lá fora. Cada grupo é renderizado sozinho, em branco, com intensidade 1. O sol tem uma plate por posição (manhã, meio-dia, tarde) e a vista da janela tem uma por horário. Luz soma de forma linear, então a soma de todas as plates com peso 1 é o render completo.

Sol (tarde)

Céu

Preenchimento

Luminária

Luzes da cidade

Vista da janela (tarde)
A mistura acontece na GPU, em Metal. Um preset (manhã, dia, tarde, noite) é um conjunto de pesos RGB por grupo, mais exposição, vinheta e grão. O relógio é uma lista de marcos, como 07:30 manhã e 17:15 tarde, e entre dois deles os pesos são interpolados com smoothstep. Como tudo é linear antes do tone map, cada preset vira uma única textura pré-misturada, e a qualquer hora o shader só mistura os dois vizinhos. Depois vêm a vinheta, um grão fixo por pixel e o tone map.

7h30

12h

17h30

21h
Os renders usam AgX no Blender, então o shader precisa da mesma curva, senão o app e as prévias do Blender não batem. O que foi pro app é uma aproximação do AgX calibrada com pares de EXR linear e o PNG do próprio Blender no mesmo quadro: contraste +0,04, deslocamento de +0,009 no espaço log e gama de saída 1,18. O erro médio fica em torno de 3/255.
Uma armadilha: as plates são OpenEXR em meia precisão, abertas pelo ImageIO. Ele abre compressão ZIP e PIZ, mas com DWAA ou DWAB devolve zero imagens e nenhum erro. Tudo vai em ZIP.
O seu álbum numa capa de papelão
Nas plates, a capa em pé e o rótulo do disco são brancos. O app sabe onde caem os quatro cantos de cada um, então aplica a arte do álbum com uma homografia e multiplica pela luz. O que fica na frente, como uma folha da costela-de-adão, já está fora da máscara. O rótulo funciona igual, dentro de um círculo, com um desfoque angular enquanto gira.

Na plate

No app
A capa também joga luz. Renderizo a área em volta dela uma vez com a capa branca e outra com a capa preta, e a diferença é a luz que a capa rebate na mesa. O app soma essa diferença tingida pela cor média da arte, então um álbum laranja esquenta um pouco a madeira. A pilha na mesa mostra o álbum que tocou antes deste.
O disco também é desenhado ao vivo, iluminado com um passe difuso e um especular do Cycles. O passo do sulco é fixo, como num corte de verdade, então cada faixa ocupa a largura da duração da música e um lado curto deixa um run-out largo. Os players só informam a faixa que está tocando, então o app guarda as durações que já viu de cada álbum e estima o resto. A biblioteca do Música dá a lista completa no próprio Mac, e um ajuste opcional busca a lista no catálogo público da Apple.
Prato e braço
A SL-Q3 é direct drive com trava a quartzo, e chega na velocidade rápido. O ângulo do prato é calculado em forma fechada a partir do relógio, em vez de ser somado quadro a quadro. Cada play ou pause abre uma aproximação exponencial da velocidade alvo, com constante de tempo de 0,16 s pra subir (trava em 33⅓ em cerca de 0,7 s) e 0,22 s pro freio. O ângulo é a integral exata disso, então um quadro perdido nunca faz o disco escorregar.
O braço é desenhado a partir de sprites renderizados em 29 ângulos, no máximo 1,5° um do outro, com a sombra e o reflexo na tampa. O app faz crossfade entre os dois mais próximos e corrige o resto do ângulo, e a subida do cue, com uma homografia montada a partir da matriz da câmera. O movimento usa molas criticamente amortecidas: uns 0,45 s pra levantar, perto de um segundo pra ir até o disco e uma descida lenta. Se você pula uma faixa no meio do movimento, o braço continua de onde está. Abaixado, a agulha acompanha o progresso da música dentro da faixa.
Chuva
A cada 15 minutos o app pergunta ao Open-Meteo o tempo agora na cidade da janela, São Paulo por padrão. Se está chovendo lá, gotas escorrem pelo vidro e refratam a vista atrás delas, dentro de uma máscara do vidro visível. Com a tampa aberta, as gotas vistas através do acrílico são atenuadas pela transmissão medida dele.
Pra deixar ligado
Um papel de parede fica horas na tela, então o trabalho principal é não desenhar. Os quadros vêm de um CADisplayLink a 30 fps que só roda enquanto algo se mexe: o prato, o braço, a troca de capa, a chuva, o vapor do café. Ele para quando a mesa está coberta, a tela está bloqueada ou os monitores dormem. O macOS continua dizendo que a janela da mesa está visível atrás de um app maximizado, por causa da faixa embaixo da barra de menus, então o app também confere se a área animada em si está coberta. Em Apple Silicon isso dá cerca de 3% de CPU com o disco tocando e 0% com as janelas por cima.
Entregar 1,3 GB de luz
As plates dos quatro enquadramentos somam cerca de 1,3 GB, demais pra um instalador. O DMG tem uns 11 MB. Depois o app baixa só o enquadramento que você escolher, em pacotes de até uns 300 MB, conferidos com SHA-256 e que retomam se a conexão cair. O servidor de licenças é um Cloudflare Worker, e os pacotes ficam no R2.
Se quiser perguntar sobre qualquer parte disso, escreva para matheus@onezi.com.br.