FXAA
Demo code
vue
<script setup lang="ts">
import { OrbitControls } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
import { TresLeches, useControls } from '@tresjs/leches'
import { NoToneMapping } from 'three'
import { BlendFunction } from 'postprocessing'
import { EffectComposerPmndrs, FXAAPmndrs } from '@tresjs/post-processing'
import type { PerspectiveCamera } from 'three'
import { ref } from 'vue'
import '@tresjs/leches/styles'
const gl = {
antialias: false,
clearColor: '#2e3440',
toneMapping: NoToneMapping,
}
const { autoRotateSpeed, blendFunction, wireframe, boxColor, opacity, samples, minEdgeThreshold, maxEdgeThreshold, subpixelQuality } = useControls({
blendFunction: {
options: Object.keys(BlendFunction).map(key => ({
text: key,
value: BlendFunction[key as keyof typeof BlendFunction],
})),
value: BlendFunction.SRC,
},
samples: {
value: 12,
min: 0,
max: 32,
step: 1,
},
minEdgeThreshold: {
value: 0.0312,
min: 0,
max: 1,
step: 0.001,
},
maxEdgeThreshold: {
value: 0.125,
min: 0,
max: 1,
step: 0.001,
},
subpixelQuality: {
value: 0.75,
min: 0,
max: 1,
step: 0.01,
},
autoRotateSpeed: {
value: 1,
min: 0,
max: 10,
step: 0.1,
},
boxColor: '#ffffff',
wireframe: false,
opacity: {
value: 1,
min: 0,
max: 1,
step: 0.01,
},
})
const wrapperRef = ref<HTMLElement | undefined>(undefined)
const cameraRef = ref<PerspectiveCamera | null>(null)
const onChange = (e: { object: PerspectiveCamera }) => {
if (!cameraRef.value) { return }
cameraRef.value.position.copy(e.object.position)
cameraRef.value.rotation.copy(e.object.rotation)
cameraRef.value.zoom = e.object.zoom
cameraRef.value.quaternion.copy(e.object.quaternion)
}
</script>
<template>
<div ref="wrapperRef" class="aspect-16/9 relative h-full">
<TresCanvas
v-bind="gl"
class="doc-fxaa-canvas-left"
>
<TresPerspectiveCamera :position="[0, 2, 3.5]" />
<OrbitControls :domElement="wrapperRef" auto-rotate :auto-rotate-speed="autoRotateSpeed" :target="[0, 0.25, 0]" @change="onChange" />
<TresMesh :position="[0, .5, 0]">
<TresBoxGeometry :args="[2, 2, 2]" />
<TresMeshBasicMaterial :color="boxColor" :wireframe="wireframe" />
</TresMesh>
</TresCanvas>
<div class="doc-fxaa-divider"></div>
<TresCanvas
v-bind="gl"
class="doc-fxaa-canvas-right"
>
<TresPerspectiveCamera ref="cameraRef" :position="[0, 2, 3.5]" />
<TresMesh :position="[0, .5, 0]">
<TresBoxGeometry :args="[2, 2, 2]" />
<TresMeshBasicMaterial :color="boxColor" :wireframe="wireframe" />
</TresMesh>
<Suspense>
<EffectComposerPmndrs>
<FXAAPmndrs
:blendFunction="Number(blendFunction)"
:opacity="opacity"
:samples="samples"
:maxEdgeThreshold="maxEdgeThreshold"
:minEdgeThreshold="minEdgeThreshold"
:subpixelQuality="subpixelQuality"
/>
</EffectComposerPmndrs>
</Suspense>
</TresCanvas>
<p class="doc-fxaa-info doc-fxaa-info-left text-xs font-semibold">⬅️ No FXAA</p>
<p class="doc-fxaa-info doc-fxaa-info-right text-xs font-semibold">With FXAA ➡️</p>
</div>
<TresLeches :float="false" />
</template>
<style scoped>
.doc-fxaa-canvas-left {
position: absolute !important;
inset: 0;
z-index: 1;
clip-path: inset(0 50% 0 0);
-webkit-clip-path: inset(0 50% 0 0);
}
.doc-fxaa-canvas-right {
position: absolute !important;
inset: 0;
z-index: 2;
pointer-events: none;
clip-path: inset(0 0 0 50%);
-webkit-clip-path: inset(0 0 0 50%);
}
.doc-fxaa-divider {
position: absolute;
top: 0;
bottom: 0;
left: 50%;
width: 2px;
background: red;
z-index: 3;
pointer-events: none;
}
.doc-fxaa-info {
position: absolute;
bottom: 0;
padding: 0.45rem 0.75rem;
margin: 0;
text-align: center;
color: #fff;
z-index: 2;
background: linear-gradient(90deg, #7a95b1 0%, #517284 100%);
}
.doc-fxaa-info-left {
left: 0;
border-radius: 0px 10px 0px 0px;
}
.doc-fxaa-info-right {
right: 0;
border-radius: 10px 0px 0px 0px;
}
</style>
The FXAAEffect
effect is part of the postprocessing
package. FXAA offers a performance-optimized anti-aliasing solution that smooths jagged edges while maintaining excellent performance. However, its quality may be modest at times, occasionally resulting in a slightly blurred appearance.
Usage
The <FXAAPmndrs>
component is easy to use and provides customizable options to suit different visual styles.
INFO
When using the <EffectComposerPmndrs>
pipeline, enabling native antialiasing with the antialias
props on <TresCanvas>
is unnecessary.
vue
<script setup lang="ts">
import { EffectComposerPmndrs, FXAAPmndrs } from '@tresjs/post-processing/pmndrs'
const gl = {
toneMapping: NoToneMapping,
antialias: false,
}
// It is not required to add `antialias: false` for
// the <TresCanvas> context, as it is automatically
// disabled when using `<EffectComposerPmndrs>`.
const effectProps = {
samples: 24
}
</script>
<template>
<TresCanvas v-bind="gl">
<TresPerspectiveCamera />
<!-- Your scene -->
<Suspense>
<EffectComposerPmndrs>
<FXAAPmndrs v-bind="effectProps" />
</EffectComposerPmndrs>
</Suspense>
</TresCanvas>
</template>
Props
Prop | Description | Default |
---|---|---|
blendFunction | Defines how the effect blends with the original scene. See the BlendFunction options. | BlendFunction.SRC |
opacity | The opacity of the effect. | 1 |
samples | The maximum amount of edge detection samples. | 12 |
minEdgeThreshold | The minimum edge detection threshold. Range: [0.0, 1.0] . | 0.0312 |
maxEdgeThreshold | The maximum edge detection threshold. Range: [0.0, 1.0] . | 0.125 |
subpixelQuality | The subpixel blend quality. Range: [0.0, 1.0] . | 0.75 |
Further Reading
For more details, see the FXAAEffect documentation