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:
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.