SMAA
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, EdgeDetectionMode, PredicationMode, SMAAPreset } from 'postprocessing'
import { EffectComposerPmndrs, SMAAPmndrs } from '@tresjs/post-processing'
import type { PerspectiveCamera } from 'three'
import { ref } from 'vue'
import '@tresjs/leches/styles'
const gl = {
antialias: false,
clearColor: '#FC7BAC',
toneMapping: NoToneMapping,
}
const { blendFunction, debug, autoRotateSpeed, opacity, preset, wireframe, boxColor, predicationMode, edgeDetectionMode } = useControls({
blendFunction: {
options: Object.keys(BlendFunction).map(key => ({
text: key,
value: BlendFunction[key as keyof typeof BlendFunction],
})),
value: BlendFunction.NORMAL,
},
debug: {
options: [
{ text: 'OFF', value: 0 },
{ text: 'EDGES', value: 1 },
{ text: 'WEIGHTS', value: 2 },
],
value: 0,
},
preset: {
options: Object.keys(SMAAPreset).map(key => ({
text: key,
value: SMAAPreset[key as keyof typeof SMAAPreset],
})),
value: SMAAPreset.HIGH,
},
predicationMode: {
options: Object.keys(PredicationMode).map(key => ({
text: key,
value: PredicationMode[key as keyof typeof PredicationMode],
})),
value: PredicationMode.DISABLED,
},
edgeDetectionMode: {
options: Object.keys(EdgeDetectionMode).map(key => ({
text: key,
value: EdgeDetectionMode[key as keyof typeof EdgeDetectionMode],
})),
value: EdgeDetectionMode.COLOR,
},
boxColor: '#ffffff',
wireframe: false,
opacity: {
value: 1,
min: 0,
max: 1,
step: 0.01,
},
autoRotateSpeed: {
value: 0.5,
min: 0,
max: 10,
step: 0.1,
},
})
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-smaa-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-smaa-divider"></div>
<TresCanvas
v-bind="gl"
class="doc-smaa-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>
<SMAAPmndrs
:debug="Number(debug)"
:blendFunction="blendFunction"
:opacity="opacity"
:preset="preset"
:predicationMode="predicationMode"
:edgeDetectionMode="edgeDetectionMode"
/>
</EffectComposerPmndrs>
</Suspense>
</TresCanvas>
<p class="doc-smaa-info doc-smaa-info-left text-xs font-semibold">⬅️ No SMAA</p>
<p class="doc-smaa-info doc-smaa-info-right text-xs font-semibold">With SMAA ➡️</p>
</div>
<TresLeches :float="false" />
</template>
<style scoped>
.doc-smaa-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-smaa-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-smaa-divider {
position: absolute;
top: 0;
bottom: 0;
left: 50%;
width: 2px;
background: red;
z-index: 3;
pointer-events: none;
}
.doc-smaa-info {
position: absolute;
bottom: 0;
padding: 0.45rem 0.75rem;
margin: 0;
text-align: center;
color: #fff;
z-index: 2;
background: linear-gradient(90deg, #ff2277 0%, #fdb1c8 100%);
}
.doc-smaa-info-left {
left: 0;
border-radius: 0px 10px 0px 0px;
}
.doc-smaa-info-right {
right: 0;
border-radius: 10px 0px 0px 0px;
}
</style>
The SMAAEffect
effect is part of the postprocessing
package. SMAA (Subpixel Morphological Antialiasing) is a post-processing antialiasing technique that uses look-up tables to detect edges accurately, preserving texture details while minimizing false positives.
INFO
SMAA generally provides superior visual quality compared to FXAA, though it is slightly less performant. Note that SMAA is distinct from MSAA.
Usage
The <SMAAPmndrs>
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, SMAAPmndrs } from '@tresjs/post-processing/pmndrs'
import type { SMAAPreset } from 'postprocessing'
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 = {
preset: SMAAPreset.HIGH
}
</script>
<template>
<TresCanvas v-bind="gl">
<TresPerspectiveCamera />
<!-- Your scene -->
<Suspense>
<EffectComposerPmndrs>
<SMAAPmndrs 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 |
preset | Define the quality and performance trade-offs. See the SMAAPreset options. | SMAAPreset.MEDIUM |
edgeDetectionMode | Define the edge detection modes. See the EdgeDetectionMode options. | EdgeDetectionMode.COLOR |
predicationMode | Define the edge detection modes. See the PredicationMode options. | PredicationMode.DISABLED |
debug | Define the debug mode. Options: - 0 : OFF - 1 : EDGES - 2 : WEIGHTS | 0 (OFF) |
Further Reading
For more details, see the SMAAEffect documentation