---
url: /examples/post-processing-builtin/fxaa.md
description: >-
  Compare a raw render with the built-in fast approximate anti-aliasing effect
  using a split-screen scissor test.
---

::: example-editor

```ts
import { fxaa, glCanvas, loop, onPointerEvents, quadRenderPass } from "@radiancejs/gl";
import fragment from "./scene.frag?raw";
import "./styles.css";

// Fast Approximate Anti-Aliasing (FXAA)

let threshold = 0.5;

const canvas = document.querySelector("canvas")!;

const withFxaa = glCanvas({
  canvas,
  dpr: 1,
  fragment,
  uniforms: {
    uTime: 0,
    uThreshold: () => threshold,
    uResolution: ({ canvasResolution }) => canvasResolution,
  },
  postEffects: [fxaa()],
});

const { gl } = withFxaa;

const withoutFxaa = quadRenderPass({
  gl,
  fragment,
  uniforms: {
    uTime: 0,
    uThreshold: () => threshold,
    uResolution: ({ canvasResolution }) => canvasResolution,
  },
});

gl.enable(gl.SCISSOR_TEST);

loop(({ time }) => {
  withFxaa.uniforms.uTime = time / 1000;
  withoutFxaa.uniforms.uTime = time / 1000;

  const thresholdPx = Math.floor(withFxaa.canvas.width * threshold);

  gl.scissor(thresholdPx, 0, withFxaa.canvas.width - thresholdPx, withFxaa.canvas.height);
  withFxaa.render();

  gl.scissor(0, 0, thresholdPx, withFxaa.canvas.height);
  withoutFxaa.render();
});

onPointerEvents(canvas, {
  move: ({ pointer, boundingRect }) => {
    threshold = (pointer.x - boundingRect.left) / boundingRect.width;
  },
  leave: () => {
    threshold = 0.5;
  },
});

```

```frag
uniform float uTime;
uniform vec2 uResolution;
uniform float uThreshold;

in vec2 vUv;
out vec4 fragColor;


void main() {
  vec2 uv = vUv - 0.5;
  vec3 color = vec3(0.0);
  vec3 squareColor = vec3(.0, .7, 1.);
  
  for (float i = 1.; i < 5.; i++) {
    float angle = .1 * i * sin(uTime);
    vec2 uvRotated = vec2(
      cos(angle) * uv.x - sin(angle) * uv.y,
      sin(angle) * uv.x + cos(angle) * uv.y
    );
    float square = step(max(abs(uvRotated.x), abs(uvRotated.y)), .1 * i);
    color += vec3(square) * squareColor / 4.;
  }

  color = mix(color, vec3(1.), step(abs(vUv.x - uThreshold), .002));


  fragColor = vec4(color, 1.0);
}

```

```css
html {
  color-scheme: light dark;
}

body {
  margin: 0;
  height: 100svh;
  display: grid;
  place-items: center;
}

canvas {
  width: min(90svmin, 900px);
  aspect-ratio: 1;
  display: block;
  border-radius: 8px;
  border: 1px solid rgb(128 128 128 / 0.4);
}

```

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>RadianceJS Example</title>
  </head>
  <body>
    <canvas id="glCanvas"></canvas>
    <script src="/index.ts"></script>
  </body>
</html>

```

:::
