es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo implementar manualmente el anti-aliasing con canvas?

Escribí una especie de renderizador que puede crear Campos de Distancia Firmados en Javascript / Canvas.

https://jsfiddle.net/MisterSirCode/zrbx8493/273/

Funciona bien, pero los SDF que renderiza, aunque son precisos, son ásperos y pixelados.

(Estoy calculando cada píxel manualmente y aplicando los datos de color basados en la posición X Y / distancia y luego editando los datos de imagen del lienzo)

enter image description here

Esto es menos de lo que quiero lograr. Quiero que los SDF renderizados tengan una apariencia suavizada, pero nunca he hecho un algoritmo para lograrlo y he encontrado poca información en línea que pueda ayudarme.

Lo que quiero saber es cómo puedo alias correctamente las esquinas y bordes de mis SDF para darles una apariencia más suave desde lejos.

Esta es la función principal en la que dibujo mis SDF en los datos de imagen: (El código fuente completo está en el enlace anterior)

draw() {
    let image = this.ctx.createImageData(this.image);
    let ivec = new Vector(image.width, image.height);
    for (var y = 0; y < image.height; ++y) {
        for (var x = 0; x < image.width; ++x) {
            let sphereOne = SDF.sphere(new Vector(ivec.x / 2, ivec.y / 2), 25)(new Vector(x, y, 1));
            let sphereTwo = SDF.sphere(new Vector(ivec.x / 4, ivec.y / 4), 15)(new Vector(x, y, 1));
            let dist = SDF.smoothAdd(sphereOne, sphereTwo, 35);
            let pos = (y * image.width + x) * 4;
            if (dist < 0) {
                image.data[pos++] = x / image.width * 255;
                image.data[pos++] = y / image.height * 255;
                image.data[pos++] = (image.width - x) / image.width * 255;
                image.data[pos] = 255;
            } else {
                let bc = this.scene.backColor;
                image.data[pos++] = bc[0] * 255;
                image.data[pos++] = bc[1] * 255;
                image.data[pos++] = bc[2] * 255;
                image.data[pos] = bc[3] * 255;
            }
        }
    }
    this.ctx.putImageData(image, 0, 0);
}
Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Como experto en IT especializado en Javascript, matemáticas, renderización y suavizado de bordes, aquí están mis recomendaciones para suavizar los bordes y esquinas de los SDFs para darles una apariencia más suave desde lejos:

    1. Implementar el sobremuestreo: El sobremuestreo es una técnica que implica renderizar la imagen a una resolución más alta y luego reducirla a la resolución objetivo. Esto ayuda a reducir los bordes dentados y le da a la imagen una apariencia más suave. Puedes lograr esto renderizando el SDF a una resolución más alta (por ejemplo, 2x o 4x la resolución objetivo) y luego reduciendo el resultado utilizando un filtro como bilineal o bicúbico.

    2. Utilizar un filtro de postprocesamiento: Otro enfoque es aplicar un filtro al SDF después de haberlo renderizado. Un filtro común para antialiasing es FXAA (Fast Approximate Anti-Aliasing). Este filtro detecta y suaviza los bordes dentados en la imagen, dándole una apariencia más suave. Puedes implementar FXAA siguiendo el algoritmo descrito en el documento original: http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf

    3. Utilizar una función SDF diferente: Es posible que la función SDF que estás utilizando no sea adecuada para el antialiasing. Considera utilizar una función SDF diferente que produzca bordes más suaves. Una función popular para esto es la Función de Distancia Firmada con Mezcla (SDSFB), que mezcla varias esferas para producir una transición suave entre ellas. Puedes encontrar una implementación de SDSFB en este repositorio: https://github.com/PavelDoGreat/WebGL-Fluid-Simulation

    4. Utilizar una técnica de renderizado diferente: Por último, considera utilizar una técnica de renderizado completamente distinta. Por ejemplo, puedes utilizar trazado de rayos para renderizar el SDF, lo cual produce bordes más suaves y tiene inherente antialiasing. Esto requerirá más cálculos, pero puede valer la pena si necesitas una salida de alta calidad. Puedes encontrar una implementación de trazado de rayos de SDF en este tutorial: https://www.iquilezles.org/www/articles/raymarchingdf/raymarchingdf.htm

Comments are closed.