Esquinas afiladas con fuentes de campos de distancia firmados


49

Los campos de distancia firmados (SDF) se presentaron como una solución rápida para lograr una resolución de fuente independiente de Valve en este documento .

Ya tengo la solución Valve funcionando, pero me gustaría preservar la nitidez en las esquinas. Valve afirma que su método puede lograr esquinas afiladas mediante el uso de un segundo canal de textura AND con el de base, pero no explica cómo se generaría este segundo canal.

De hecho, hay muchos detalles de implementación que quedan fuera de este documento.

Me gustaría saber si alguno de ustedes podría indicarme una dirección para obtener el renderizado de fuentes SDF con esquinas afiladas.


De hecho, Adam ya publicó el código fuente en shadowrtoy. Aquí está el enlace: shadertoy.com/view/ltXSDB
Felipe Lira

Me tienes emocionado. ¡Publicó las cosas bezier en sombreado pero no las cosas de campo de distancia de textura!
Alan Wolfe

@AlanWolfe Creo que lo ha hecho solo para establecer curvas bezier establecidas por procedimientos. No estoy seguro del esfuerzo requerido para integrar esto en un ttf render lib. Cuando tenga algo de tiempo, lo echaré un vistazo.
Felipe Lira

parece que tiene un poco de salsa mágica al lado de almacenar y recuperar las distancias de una textura. Sin una textura en juego, los ejemplos de sombreado faltan esa parte de la ecuación.
Alan Wolfe

Un poco tarde para la fiesta, pero este hilo antiguo de reddit tiene mucha información sobre varios métodos para mejorar la nitidez del renderizado basado en SDF: reddit.com/r/gamedev/comments/2879jd/…
Necrolis

Respuestas:


7

Adam Simmons ha hecho un trabajo interesante en esta área. No sé específicamente cómo lo está logrando, pero su representación vectorial basada en SDF es la más aguda que he visto en la práctica fuera de Valve. http://twitter.com/adamjsimmons/status/611677036545863680


Por supuesto, no tengo todos los detalles, pero me parece que esta persona simplemente usó un campo de pseudodistancia en lugar de uno normal, que ya fue demostrado en un artículo de 2006 por Qin, McCool y Kaplan ". Glifos vectoriales mapeados en textura en tiempo real ", que también se menciona en el documento de Valve. Solo afecta las mitras de los contornos y no hace nada para mejorar la apariencia de las esquinas. Sospecho que la razón por la que se ve nítida es porque usa texturas de campo de distancia poco prácticas. Aunque podría estar equivocado.
Detheroc

69

EDITAR: Vea mi otra respuesta con una solución concreta.

En realidad, resolví este problema exacto hace más de un año para mi tesis de maestría. En el documento de Valve, muestran que puede Y dos campos de distancia para lograr esto, lo que funciona siempre que solo tenga una esquina convexa. Para esquinas cóncavas, también necesita la operación OR. Este tipo realmente desarrolló un sistema oscuro para cambiar entre las dos operaciones usando cuatro canales de textura.

Sin embargo, hay una operación mucho más simple que puede facilitar tanto AND como OR según la situación, y esta es la idea principal de mi tesis: la mediana de tres . Básicamente, usa exactamente tres canales (ideales para RGB), que son completamente intercambiables, y los combina usando la operación mediana (elija el valor medio de los tres).

Para acomodar el suavizado, no trabajamos solo con valores booleanos, sino con valores de coma flotante, y la operación AND se convierte en el mínimo, y el OR se convierte en el máximo de dos valores. La mediana de tres puede hacer ambas cosas: si a < b , para ( a , a , b ), la mediana es el mínimo, y para ( a , b , b ), es el máximo.

El proceso de renderizado sigue siendo extremadamente simple. El sombreador de fragmentos completo, incluido el suavizado, puede verse así:

int main() {
    // Bilinear sampling of the distance field
    vec3 s = texture2D(sdf, p).rgb;
    // Acquire the signed distance
    float d = median(s.r, s.g, s.b) - 0.5;
    // Weight between inside and outside (anti-aliasing)
    float w = clamp(d/fwidth(d) + 0.5, 0.0, 1.0);
    // Combining the background and foreground color
    gl_FragColor = mix(outsideColor, insideColor, w);
}

Entonces, la única diferencia con el método original es calcular la mediana justo después de muestrear la textura. Sin embargo, tendrá que implementar la función mediana, que se puede hacer con solo 4 min / max operaciones .

Ahora, por supuesto, la pregunta es, ¿cómo construyo un campo de distancia de tres canales?Y esta es la parte difícil. El enfoque más obvio que tomé al principio fue realizar una descomposición de la forma / glifo de entrada en tres componentes, y luego generar un campo de distancia convencional de cada uno. Las reglas para esta descomposición no son tan complicadas. En primer lugar, el área con al menos 2 de los 3 canales activados es el interior. Entonces, si imagina esto como los canales de color RGB, las esquinas convexas deben estar hechas de un color secundario, y sus dos componentes principales continúan hacia afuera. Las esquinas cóncavas son lo inverso: dos colores secundarios encierran su color primario común, y la cuña entre donde ambos bordes continúan hacia adentro es blanca. También descubrí que es necesario un poco de relleno donde dos colores primarios o dos secundarios se tocarían para evitar artefactos (por ejemplo, en el trazo medio de la "N"

La siguiente imagen es un ejemplo de descomposición generada por el programa de mi tesis:

Descomposición multicanal de glifos

Sin embargo, este enfoque tiene algunos inconvenientes. Uno de ellos es que los efectos especiales, como los contornos y las sombras, ya no funcionarán correctamente. Afortunadamente, también se me ocurrió un segundo método, mucho más elegante, que genera los campos de distancia directamente e incluso admite todos los efectos gráficos. También está incluido en mi tesis y también tiene más de un año. No voy a dar más detalles en este momento, porque actualmente estoy escribiendo un documento que describe esta segunda técnica en detalle, pero lo publicaré aquí tan pronto como esté terminado.

De todos modos, aquí hay un ejemplo de la diferencia en calidad. La resolución de la textura es la misma en cada imagen, pero la izquierda usa una textura regular, la del medio usa un campo de distancia ordinario y la derecha usa mi campo de distancia de tres canales. La sobrecarga de rendimiento es solo la diferencia entre muestrear una textura RGB versus una monocromática.

ingrese la descripción de la imagen aquí


55
Gran primera respuesta, ¡bienvenido a Computer Graphics SE! :) ¿Tu tesis está disponible públicamente? (¿O será después de que haya terminado dicho documento?) Si es así, probablemente sería muy útil vincularlo también.
Martin Ender

Se supone que debe estar a disposición del público, pero parece que la escuela aún no lo ha presentado. De todos modos, preferiría no difundirlo ahora, ya que el artículo que estoy escribiendo realmente explicará mucho mejor las partes importantes y se centrará en cómo implementarlo, y debería completarse muy pronto.
Detheroc

@Detheroc Notifique aquí y en el gamedev Q cuando haya terminado con el artículo. La explicación aún no está 100% clara para mí. Sugeriría mostrar la composición paso a paso en imágenes.
Ingeniero

1
Me encantaría poder replicar sus resultados actuales, incluso si no son tan buenos como sus resultados futuros, +1 para compartir todos los detalles que pueda. muy emocionante. ¿Ha considerado la aplicación de cualquiera de las técnicas para la marcha de rayos (trazado de esfera)? En texturas de volumen o similar ...
Alan Wolfe

44
La tesis está disponible públicamente aquí: dspace.cvut.cz/bitstream/handle/10467/62770/…
Romain Guy

43

Perdón por la larga espera, pero se ha vuelto obvio que aunque el artículo que prometí está básicamente completo, el proceso de publicación llevará algún tiempo. Por lo tanto, he preparado un programa de código abierto con mi nuevo algoritmo de construcción de campo de distancia multicanal, msdfgen , que puede probar ahora mismo.

Está disponible en GitHub: https://github.com/Chlumsky/msdfgen

(Soy nuevo en esto, así que avíseme si hay algún problema con el repositorio).

Alguien también preguntó cómo se compara con un campo de distancia monocromático más grande, por lo que aquí hay un avance de la diferencia de calidad. Sin embargo, realmente depende de la fuente en particular, y no diría que siempre vale la pena los datos adicionales.

Campo de distancia multicanal 16x16 Campo de distancia monocromo 32x32


3

¡Bastante interesante! Soy el autor del documento de distancia firmado con válvula. Lamento que sea un poco escaso en detalles de implementación. Solo incluí el ejemplo de dos canales como trabajo futuro: no tenía un generador. Pensé que algo así como generar un sdf de alta resolución y luego segmentar en función del ángulo del gradiente del sdf sería una táctica razonable. Pero nunca lo conseguí. Cualquier esquema multicanal debe compararse con el uso de datos de canal único de mayor resolución de la misma huella de memoria, para las proporciones de aumento que su aplicación necesita.


0

De ninguna manera soy un experto en el tema, pero es posible que, al menos en teoría, pueda preservar las esquinas afiladas en un pseudo-SDF monocromático si utilizó un filtro bilateral o un filtro bicúbico direccional en lugar de un filtro bilineal estándar. Además del beneficio obvio de ahorrar memoria, también podría tener múltiples canales para calcomanías SDF multicolores.

Alternativamente, si no le importa usar un segundo canal, entonces también podría intentar tener un canal para Distancia Horizontal y otro para Distancia Vertical, y usar una pirámide de energía de Diferencia de Laplacean (DoL) para comprimir la textura para que la información redundante no No se grabará.

Una tercera y última solución teórica sería experimentar con una textura de muestreo hexagonal a través de direccionamiento de conjunto de matriz.

Desafortunadamente, actualmente no tengo ningún medio para probar mis ideas y no he podido encontrar ningún documento que describa o pruebe algo similar a mis ideas. En breve, vincularé todos los artículos relevantes donde obtuve mi información / ideas.