Os campos de distâncias assinadas (SDFs) foram apresentados como uma solução rápida para obter renderização de fonte independente de resolução pela Valve neste documento .
Eu já tenho a solução Valve funcionando, mas gostaria de preservar a nitidez nos cantos. A Válvula afirma que seu método pode obter ângulos agudos usando um segundo canal de textura ANDed com o canal base, mas falta explicar como esse segundo canal seria gerado.
De fato, existem muitos detalhes de implementação deixados de fora deste documento.
Gostaria de saber se algum de vocês poderia me indicar uma direção para obter a renderização da fonte SDFs com cantos afiados.
texture
signed-distance-field
font-rendering
Felipe Lira
fonte
fonte
Respostas:
Adam Simmons fez um trabalho interessante nessa área. Não sei especificamente como ele está conseguindo isso, mas sua renderização vetorial baseada em SDF é a mais nítida que já vi na prática fora da Valve. http://twitter.com/adamjsimmons/status/611677036545863680
fonte
EDIT: Por favor, veja minha outra resposta com uma solução concreta.
Na verdade, eu resolvi esse problema exato há mais de um ano para a minha tese de mestrado. No artigo da Valve, eles mostram que você pode AND dois campos de distância para conseguir isso, o que funciona desde que você tenha apenas um canto convexo. Para cantos côncavos, você também precisa da operação OR. Esse cara realmente desenvolveu um sistema obscuro para alternar entre as duas operações usando quatro canais de textura.
No entanto, há uma operação muito mais simples que pode facilitar tanto AND quanto OR, dependendo da situação, e esta é a principal idéia da minha tese: a mediana de três . Então, basicamente, você usa exatamente três canais (ideais para RGB), que são completamente intercambiáveis, e os combina usando a operação mediana (escolha o valor do meio dos três).
Para acomodar a suavização de serrilhado, não trabalhamos apenas com booleanos, mas com valores de ponto flutuante, e a operação AND se torna o mínimo, e o OR se torna o máximo de dois valores. A mediana de três pode de fato fazer as duas coisas: se a < b , para ( a , a , b ), a mediana é o mínimo e, para ( a , b , b ), é o máximo.
O processo de renderização ainda é extremamente simples. Todo o shader de fragmento, incluindo anti-aliasing, pode se parecer com isso:
Portanto, a única diferença do método original é calcular a mediana logo após a amostragem da textura. Você precisará implementar a função mediana, o que pode ser feito com apenas 4 min / max de operações .
Agora, é claro, a questão é: como faço para construir um campo de distância de três canais?E esta é a parte complicada. A abordagem mais óbvia que tomei no início foi realizar uma decomposição da forma / glifo de entrada em três componentes e, em seguida, gerar um campo de distância convencional de cada um. As regras para essa decomposição não são tão complicadas. Em primeiro lugar, a área com pelo menos 2 dos 3 canais é interna. Então, se você imaginar isso como os canais de cores RGB, os cantos convexos deverão ser feitos de uma cor secundária e seus dois componentes principais continuarão para fora. Os cantos côncavos são o inverso: duas cores secundárias incluem sua cor primária comum, e a cunha entre o local em que as duas bordas continuam para dentro é branca. Também descobri que é necessário algum preenchimento onde duas cores primárias ou duas cores secundárias tocariam para evitar artefatos (por exemplo, no traçado do meio do "N"
A imagem a seguir é um exemplo de decomposição gerada pelo programa da minha tese:
Essa abordagem, no entanto, tem algumas desvantagens. Uma delas é que os efeitos especiais, como contornos e sombras, não funcionarão mais corretamente. Felizmente, eu também criei um segundo método, muito mais elegante, que gera diretamente os campos de distância e até suporta todos os efeitos gráficos. Também está incluído na minha tese e também tem mais de um ano de idade. Não vou dar mais detalhes agora, porque atualmente estou escrevendo um artigo que descreve essa segunda técnica em detalhes, mas vou publicá-la aqui assim que terminar.
Enfim, aqui está um exemplo da diferença de qualidade. A resolução da textura é a mesma em cada imagem, mas a esquerda usa uma textura regular, a do meio usa um campo de distância comum e a direita usa o meu campo de distância de três canais. A sobrecarga de desempenho é apenas a diferença entre a amostragem de uma textura RGB e uma monocromática.
fonte
Desculpe a longa espera, mas ficou óbvio que, embora o artigo que prometi esteja basicamente completo, o processo de publicação levará algum tempo. Portanto, preparei um programa de código aberto com o meu novo algoritmo de construção de campo à distância multicanal, msdfgen , que você pode experimentar agora.
Está disponível no GitHub: https://github.com/Chlumsky/msdfgen
(Eu sou novo nisso, por favor, deixe-me saber se há algo errado com o repositório.)
Alguém também perguntou sobre como ele se compara a um campo de distância monocromático maior, então aqui está um teaser da diferença de qualidade. No entanto, isso realmente depende da fonte específica, e eu não diria que vale sempre a pena os dados extras.
fonte
Muito interessante! Sou o autor do papel distanciado com válvula. Lamentamos que seja um pouco escasso nos detalhes da implementação. Eu incluí apenas o exemplo de dois canais como trabalho futuro - eu não tinha um gerador. Imaginei algo como gerar um sdf de alta resolução e, em seguida, segmentar com base no ângulo do gradiente do sdf seria uma tática razoável. Mas nunca cheguei a isso. Qualquer esquema multicanal deve ser ponderado com o uso de dados de canal único de alta resolução com o mesmo espaço de memória, para as proporções de ampliação que seu aplicativo precisa.
fonte
Eu não sou um especialista no assunto, mas você pode, pelo menos em teoria, preservar cantos afiados em um pseudo-SDF monocromático se você usou um filtro Bilateral, um filtro Bicúbico Direcional em vez de um filtro Bilinear padrão. Além do benefício óbvio de economizar memória, você também pode ter vários canais para adesivos SDF multicoloridos.
Como alternativa, se você não se importa em usar um segundo canal, também pode tentar ter um canal para Distância Horizontal e outro para Distância Vertical e usar uma pirâmide de energia Diferença de Laplacean (DoL) para comprimir a textura para que informações redundantes não ocorram. ser gravado.
Uma terceira e última solução teórica seria experimentar uma Textura Amostrada Hexagonal via Endereçamento de Conjunto de Matrizes.
Infelizmente, atualmente não tenho como testar minhas idéias e não consegui encontrar nenhum documento descrevendo ou testando algo semelhante às minhas idéias. Vou ligar todos os artigos relevantes onde obtive minhas informações / idéias em breve.
fonte