Communitygithub.com

glsl-sdf-typography

Cria qualquer palavra, nome ou frase como letras de vidro líquido 3D em GLSL, em qualquer fonte real (Google Fonts por nome, um arquivo de fonte ou uma vibe como romântico, nuvem, medieval, cartoon) ou em tubos de néon artesanais, preenchidos com a superfície de vidro líquido em movimento, sobre uma cor de fundo sólida (preto por padrão) ou na própria imagem do usuário, com uma prévia HTML pronta para abrir.

O que é glsl-sdf-typography?

Esta skill é um construtor de tipografia GLSL SDF que transforma qualquer texto solicitado pelo usuário (palavra, nome, frase) em letras de vidro líquido 3D animadas. Ela suporta dois modos principais: o modo de fonte real (padrão), que utiliza contornos reais de fontes do Google Fonts transformados em funções de distância exatas, e o modo de tubos de néon, onde as letras são construídas manualmente com traços circulares de espessura constante. O usuário pode personalizar a fonte (por nome, vibe, ou arquivo), a cor de fundo (sólida ou uma imagem), e substituir pontuações, acentos ou títulos (como o ponto do 'i') por formas pré-definidas (coração, estrela, diamante, lua, etc.). A skill gera um arquivo HTML pronto para visualização, e a translucidez do vidro pode ser ajustada. É ideal para quando o usuário pedir para escrever, soletrar ou renderizar texto com efeito de vidro, GLSL ou SDF.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Playful-Design/liquid-glass-skill/tree/HEAD/glsl-sdf-typography

Perguntar na sua IA favorita

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

Documentação

Construtor de Tipografia GLSL SDF

1. Função e Comportamento Esperado

Você é um especialista em tipografia GLSL SDF (Campo de Distância Assinado). Quando invocado, leia a solicitação do usuário (seção 2), defina o texto no estilo de letra solicitado (seção 2.1) e entregue um shader completo e executável: letras de vidro líquido sobre um fundo sólido (seção 7). As letras mantêm a aparência de vidro líquido: a superfície líquida em movimento da habilidade glsl-liquid-glass é visível apenas através das letras e formas, enquanto tudo ao redor delas é de uma cor sólida. NÃO codifique todo o alfabeto. Gere funções SDF apenas para os caracteres realmente presentes no texto solicitado.

2. Lendo a Solicitação

As solicitações vêm na sintaxe curta /liquid-glass-skill (que essa habilidade define), ou como frases simples, por exemplo:

  • "Escreva 'Joyeux anniversaire Mia' e substitua o ponto do i em Mia por um coração."
  • "A frase 'pixel jam': o i ganha uma estrela em vez do ponto, o j um diamante, fundo creme."
  • "Bonjour Chloé em duas linhas, com uma pequena lua em vez do acento no é."

Extraia cinco coisas:

  1. Texto. A string exata a ser renderizada. Texto entre aspas tem prioridade; caso contrário, pegue as palavras que o usuário designar explicitamente ("escreva meu nome Chloé", "o título …"). Mantenha maiúsculas, minúsculas, acentos, pontuação e espaçamento exatamente como fornecidos. Nunca traduza, corrija a ortografia ou altere maiúsculas/minúsculas. Se não estiver claro quais palavras renderizar, faça uma pergunta curta.
  2. Quebras de linha. Respeite as explícitas ("em duas linhas", uma /, uma nova linha). Caso contrário, quebre automaticamente (seção 6).
  3. Edições de marca. Para cada uma: caractere alvo, qual(is) ocorrência(s), forma e opções (tamanho, cor, derretida ou flutuante).
    • Ocorrência: "o i em Mia", "o segundo i", "o último j", "todo i". Se o usuário nomear um caractere que ocorre várias vezes sem dizer qual, aplique a edição a todas e informe isso.
    • Apenas marcas destacáveis podem ser substituídas (tabela abaixo). Se o usuário mirar em um caractere sem uma (ex.: "o ponto do o", ou o I maiúsculo), não invente silenciosamente: pergunte se deve adicionar a forma acima da letra como um ornamento.
    • As formas vêm do catálogo glsl-sdf-shapes. Se uma forma solicitada não estiver listada, construa-a conforme essa habilidade descreve e diga que é uma aproximação composta.
    • Padrão: a forma substitui toda a marca (ambos os pontos de um trema, a menos que o usuário diga um), flutua acima da letra e tem o mesmo vidro das letras.
  4. Fonte ou vibe (seção 2.1). Uma palavra de humor ("conto de fadas", "romântico", "fofo") escolhe uma vibe. Padrão: DM Serif Display.
  5. Fundo. Uma cor sólida, preto #000000 por padrão (ou a cor da vibe). Aceite nomes de cores (a habilidade liquid-glass-skill tem a tabela) e códigos hexadecimais. Ou uma imagem que o usuário fornecer (um caminho de arquivo, ou uma imagem anexada à mensagem: salve-a em um arquivo primeiro), veja seção 2.2. A superfície líquida nunca é mostrada ao redor das letras, apenas dentro delas (seção 7.2): letras na frente de um fundo líquido em movimento não podem ser lidas. Essa superfície sozinha, como fundo de tela cheia, é a habilidade glsl-liquid-glass.
Marca substituívelCaracteresConstrução padrãoCentro
Título (ponto)i jcírculo, raio Ry = +0.60
Pontos de pontuação. : ; ! ?círculo, raio Rna linha de base ou acima dela, conforme a glifo precisar
Trema (dois pontos)ä ë ï ö ü ÿ e maiúsculasdois círculos, x = ±0.22+0.60 (minúsculas), +1.30 (maiúsculas)
Agudo, grave, circunflexoé è ê à â î ô û ù e maiúsculascápsulas curtas+0.60 (minúsculas), +1.30 (maiúsculas)
Cedilhaç Çarco curto abaixoy = -1.30
Anelå Åanel pequeno+0.60 / +1.30

Antes do código, imprima um breve resumo para que o usuário possa verificar sua leitura:

TextoLinhasEdições de marcaFonteFundo
happy birthday Chloehappy birthday / Chloei em birthday → estrela (flutuante)DM Serif Displaypreto #000000
Be mine1i → coraçãoLavishly Yours (vibe romântico)#F6D5DC
Mia1i → coraçãoDM Serif Displayimagem beach.jpg

2.1 Estilo de letra: uma fonte real (padrão) ou tubos de néon

Modo fonte (padrão). As letras são os contornos reais de uma fonte, transformados em funções de distância exatas e renderizados como vidro líquido fofo. Não desenhe essas letras à mão: execute o script, que escreve o shader inteiro a partir de templates/liquid-glass-text.glsl e as formas em glsl-sdf-shapes/shapes.glsl.

python3 <this skill>/scripts/font_to_glsl.py --google "DM Serif Display" \
    --text "I love/Playful Design!" --mark "i@Design=star" --mark "!=heart" \
    --bg "#B5A0D0" --out i-love-playful-design.glsl
O usuário dizOpção do script
vibe romântico, "estilo conto de fadas", "algo fofo"--vibe romantic (tabela abaixo)
tom rosa, "vidro rosa", "vidro claro"--tint pink (paleta pastel); "claro" → --tint white
arco-íris, "cores líquidas originais", "iridescente"--palette liquid
3d, "letras 3D separadas", "letras balão fofas"--look objects (seção 7.0)
fonte Pacifico, "em Playfair Display"--google "Pacifico" (baixada do Google Fonts, cache em ~/.cache/liquid-glass-fonts)
um arquivo de fonte ("use ~/fonts/Brand.otf")--font PATH
negrito, itálico, peso 800--style Bold / --style Italic para famílias estáticas, --axis wght=800 para variáveis
o texto, / para uma nova linha--text "linha um/linha dois". Escolha as linhas conforme seção 6
"o i em Design → estrela"--mark "i@Design=star"
"o 2º i", "todo i"--mark "i:2=star", --mark "i=star"
"ponto do ! → coração", maior--mark "!=heart", --mark "!=heart*1.3"
"uma lua cheia em vez do o" (letra inteira, qualquer caractere)--replace "o=fullmoon", --replace "o@love=heart" (mesma sintaxe de --mark; a forma ocupa o lugar e tamanho da letra)
cor de fundo--bg "#B5A0D0" ou um nome de cor
imagem de fundo--image PATH (seção 2.2)
vidro mais fofo / mais achatado--puff 0.25 / --puff 0.10 (padrão: da largura da haste da fonte)
espaçamento mais solto / mais apertado, espaçamento de linha--tracking 0.05 (em), --line-height 1.0
  • Fontes decorativas pesadas (texturas, respingos): --simplify 0.008 remove os pequenos pontos e mantém o shader rápido. O script imprime o número de segmentos e um aviso acima de 4000: os navegadores podem desistir de tal shader (página em branco ou ícone de carinha triste). Aumente --simplify (0.008, depois 0.015) ou encurte o texto. Uma vibe pode definir simplify em vibes.json; evite fontes que ainda excedam 4000 segmentos em textos curtos.
  • Formas detalhadas (butterflies, crown, butterfly) precisam de espaço: dê a elas *2 ou mais em um i, e prefira butterfly em vez de butterflies quando o texto for pequeno ou sobre um fundo claro.
  • Formas disponíveis para o script: circle heart star sparkle diamond moon fullmoon flower plus butterfly butterflies cloud crown spade club (palavras como "ás de espadas", "trèfle", "lua cheia" mapeiam para elas: veja o catálogo glsl-sdf-shapes). Para qualquer outra forma, adicione-a a shapes.glsl primeiro (a habilidade glsl-sdf-shapes diz como).
  • O script recusa uma marca em um caractere sem ponto ou acento destacável nessa fonte, e um caractere ausente na fonte. Relate isso ao usuário em vez de contornar.
  • Licenças: Google Fonts são gratuitas para incorporar (OFL ou Apache). Para um arquivo de fonte que o usuário trouxer, lembre-o uma vez de que o shader contém os contornos das letras, então a licença da fonte deve permitir a incorporação.
  • Custo: uma letra de fonte tem 20 a 60 curvas, então uma frase longa é mais pesada que os tubos. Se uma frase ultrapassar cerca de 40 caracteres, avise que pode ficar lenta em GPUs fracas.
  • Se você puder renderizar o shader (por exemplo, com WebGL em um navegador headless), verifique-o uma vez, especialmente as marcas: uma forma que colide com um vizinho ganha *0.8.

Vibes (vibes.json nesta habilidade; cada uma define a fonte, uma cor de fundo usada apenas quando o usuário não nomeia nenhuma, e qualquer ajuste). Combine as palavras do usuário com uma vibe ou um de seus aliases:

VibeTambém correspondeFonteFundo padrão
adventureaventureiro, ousado, exploradorCaprasimoverde-escuro #12343B
cloudnublado, fofo, suave, borbulhanteRubik Bubblescéu #BFD9F2
medievalfantasia, celta, cavaleiroUncial Antiquaazul noite #14202B
romanticnamorados, amor, casamentoLavishly Yoursblush #F6D5DC
cartoonconto de fadas, design antigo, caprichosoHenny Pennycreme #F2EEE6
drippinggotejamento, tinta molhada, derretimento, assustadorRubik Wet Paintpreto #0A0A0A
  • Se o usuário descrever um humor que não corresponde a nenhuma vibe, escolha você mesmo uma fonte Google adequada, diga qual e ofereça-se para salvá-la como uma nova vibe (adicione uma entrada a vibes.json e depois reinstale a habilidade).

Modo tubo de néon (fonte tubos, "néon", "monolinha"): as letras construídas à mão das seções 3 a 6, tubos de vidro redondos de espessura constante. Use-o apenas quando o usuário pedir essa aparência.

2.2 Em uma imagem

Com --image PATH a imagem do usuário substitui a cor sólida: ela preenche o quadro (cortada para cobri-lo, como um papel de parede), as letras projetam sua sombra de contato suave sobre ele e as letras de vidro distorcem a imagem como vidro real. Dentro das letras, photoInGlass mistura a superfície líquida com a imagem (--photo-in-glass, padrão 0.35; 0 = apenas líquido, 1 = vidro claro mostrando apenas a imagem). Use 1 quando o usuário quiser "vidro claro na minha foto", 0 quando quiser que as letras líquidas se destaquem.

  • O shader lê a imagem de iChannel0. Além do .glsl, o script escreve NOME.html: uma página com o shader e a imagem incorporados, que executa ao vivo em qualquer navegador ao dar um duplo clique. Sempre aponte o usuário para este arquivo: o Shadertoy não pode carregar as próprias imagens deles sem uma extensão. Na página, soltar outra imagem sobre ela troca o fundo, Espaço pausa, S salva um PNG.
  • Fotos do iPhone (HEIC) e imagens com mais de 3 MB são convertidas para um JPEG de no máximo 2048 px (macOS sips).
  • Uma foto movimentada dificulta a leitura das letras: se necessário, sugira uma área mais calma da imagem, um --photo-in-glass menor ou um texto maior.

3. Regras para Construir Letras (Traços de Tubo, apenas modo tubo de néon)

As letras são tubos de vidro redondos (estilo néon). Construa cada letra exclusivamente a partir de traços de um raio constante const float R = 0.15;: cápsulas retas e arcos circulares. Cada traço de cada letra e marca padrão usa R (monolinha). A distância 2D aos traços depois se torna um tubo 3D (seção 7.3).

float sdCapsule(vec2 p, vec2 a, vec2 b, float r) {
    vec2 pa = p - a, ba = b - a;
    float h = clamp(dot(pa, ba)/dot(ba, ba), 0.0, 1.0);
    return length(pa - ba*h) - r;
}

// Traço ao longo de um arco circular: centro c, raio ra, direção média `dir`
// (radianos, 0 = +x, PI/2 = para cima), meia-abertura `ap` (PI/2 = meio círculo, PI = círculo completo).
float sdArcStroke(vec2 p, vec2 c, float ra, float dir, float ap, float r) {
    p -= c;
    float a = 1.5707963 - dir;                 // gire para que `dir` aponte para +y
    p = mat2(cos(a), sin(a), -sin(a), cos(a)) * p;
    vec2 sc = vec2(sin(ap), cos(ap));
    p.x = abs(p.x);
    return ((sc.y*p.x > sc.x*p.y) ? length(p - sc*ra) : abs(length(p) - ra)) - r;
}

Métricas (unidades de glifo, linhas centrais dos traços):

  • Maiúsculas e dígitos: linha de base y = -0.85, linha da caixa alta y = +0.85 (tinta abrange -1.0 a +1.0).
  • Minúsculas: altura-x y = +0.15, ascendentes até +0.85, descendentes até -1.55.
  • Meia largura hw (linha central): maiúsculas padrão 0.40, minúsculas e dígitos padrão 0.35, largas (M W m w) 0.60, estreitas (I i l j ! . , : ; ') 0.0 a 0.15. Cada glifo é centralizado em sua própria origem x = 0.
  • Letras redondas (O C G D U S o c e …) são estádios: arcos de meio círculo unidos por cápsulas retas. Nunca dimensione p de forma não uniforme para fazer uma elipse, porque isso quebra o campo de distância.
  • Caracteres não suportados (escritas não latinas, emoji): informe o usuário em vez de adivinhar.

Glifos de referência (combine o estilo deles para todos os outros caracteres):

float glyph_O(vec2 p) {
    float d = sdArcStroke(p, vec2(0.0,  0.45), 0.40,  1.5708, 1.5708, R);
    d = min(d, sdArcStroke(p, vec2(0.0, -0.45), 0.40, -1.5708, 1.5708, R));
    d = min(d, sdCapsule(p, vec2(-0.40, -0.45), vec2(-0.40, 0.45), R));
    d = min(d, sdCapsule(p, vec2( 0.40, -0.45), vec2( 0.40, 0.45), R));
    return d;
}

float glyph_A(vec2 p) {
    float d = sdCapsule(p, vec2(0.0, 0.85), vec2(-0.45, -0.85), R);
    d = min(d, sdCapsule(p, vec2(0.0, 0.85), vec2( 0.45, -0.85), R));
    d = min(d, sdCapsule(p, vec2(-0.29, -0.25), vec2(0.29, -0.25), R));
    return d;
}

// Tigela minúscula, compartilhada por a b d o p q g e…
float bowl(vec2 p) {
    float d = sdArcStroke(p, vec2(0.0, -0.20), 0.35,  1.5708, 1.5708, R);
    d = min(d, sdArcStroke(p, vec2(0.0, -0.50), 0.35, -1.5708, 1.5708, R));
    d = min(d, sdCapsule(p, vec2(-0.35, -0.50), vec2(-0.35, -0.20), R));
    d = min(d, sdCapsule(p, vec2( 0.35, -0.50), vec2( 0.35, -0.20), R));
    return d;
}
float glyph_d(vec2 p) { return min(bowl(p), sdCapsule(p, vec2(0.35, -0.85), vec2(0.35, 0.85), R)); }

float glyph_i(vec2 p) {
    float d = sdCapsule(p, vec2(0.0, -0.85), vec2(0.0, 0.15), R);   // haste até a altura-x
    return min(d, length(p - vec2(0.0, 0.60)) - R);                 // título padrão
}

4. Pontos e Acentos Personalizados (Integração de Formas, modo tubo de néon; o script faz isso no modo fonte)

Quando uma edição de marca se aplica (seção 2):

  1. Construa a base da letra sem sua marca (ex.: glyph_dotless_i, apenas a haste).
  2. Adicione a forma como uma marca separada através da macro MARK (seção 6), não dentro do glifo. As marcas vão para sua própria distância, porque as formas recebem um perfil 3D diferente dos tubos (seção 7.3).
  3. A forma é a SDF 2D de glsl-sdf-shapes, centrada na origem e ajustando-se a [-1, 1], dimensionada exatamente: `sdfShape((

... [truncado para tradução]

Individual skills in this repo

This repo contains 1 individual skill — each has its own dedicated page.

Habilidades Relacionadas