Skip to content

Scanline

Demo code
vue
<script setup lang="ts">
import { Environment, Levioso, OrbitControls, Ring, Sphere, Stars } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
import { TresLeches, useControls } from '@tresjs/leches'
import { DoubleSide, MathUtils, NoToneMapping } from 'three'
import { BlendFunction } from 'postprocessing'
import { EffectComposerPmndrs, ScanlinePmndrs } from '@tresjs/post-processing'

import '@tresjs/leches/styles'

const gl = {
  clearColor: '#000000',
  toneMapping: NoToneMapping,
}

const glComposer = {
  multisampling: 4,
}

const { blendFunction, opacity, density, scrollSpeed } = useControls({
  density: { value: 1.15, step: 0.001, max: 2 },
  opacity: { value: 0.65, step: 0.1, min: 0, max: 1 },
  scrollSpeed: { value: 0.05, step: 0.01, min: 0, max: 2 },
  blendFunction: {
    options: Object.keys(BlendFunction).map(key => ({
      text: key,
      value: BlendFunction[key as keyof typeof BlendFunction],
    })),
    value: BlendFunction.HARD_MIX,
  },
})
</script>

<template>
  <div class="aspect-16/9">
    <TresCanvas
      v-bind="gl"
    >
      <TresPerspectiveCamera
        :position="[6.5, 3, 6.5]"
        :look-at="[0, 0, 0]"
      />
      <OrbitControls auto-rotate :auto-rotate-speed=".5" />

      <Suspense>
        <Environment :blur="1" preset="snow" />
      </Suspense>

      <TresAmbientLight />

      <TresGroup :rotation-y="MathUtils.degToRad(5)" :rotation-x="MathUtils.degToRad(100)">
        <Sphere :args="[2, 32, 16]">
          <TresMeshPhysicalMaterial color="#FC7BAC" :side="DoubleSide" :transmission=".5" />
        </Sphere>

        <Levioso :speed="2.5" :rotationFactor="1" :floatFactor=".5">
          <Ring :args="[4.25, 2.5, 32]" :scale-y="-1" :position-z="-.25">
            <TresMeshPhysicalMaterial color="#ffffff" :side="DoubleSide" :transmission=".25" />
          </Ring>
        </Levioso>
      </TresGroup>

      <Stars />

      <Suspense>
        <EffectComposerPmndrs v-bind="glComposer">
          <ScanlinePmndrs :density="density" :opacity="opacity" :scrollSpeed="scrollSpeed" :blendFunction="Number(blendFunction)" />
        </EffectComposerPmndrs>
      </Suspense>
    </TresCanvas>
  </div>
  <TresLeches :float="false" />
</template>

The Scanline effect is part of the postprocessing package. It simulates scanlines reminiscent of old CRT displays, creating a nostalgic or stylized visual effect for your scene. This effect can enhance the retro aesthetic of your project or add a unique visual touch.

Usage

The <ScanlinePmndrs> component is easy to use and provides customizable options to achieve the desired visual appearance.

vue
<script setup lang="ts">
import { TresCanvas } from '@tresjs/core'
import { EffectComposerPmndrs, ScanlinePmndrs } from '@tresjs/post-processing'
import { NoToneMapping } from 'three'

const gl = {
  clearColor: '#0ff000',
  toneMapping: NoToneMapping,
}

const effectProps = {
  density: 1.25,
  opacity: 0.65,
  scrollSpeed: 0.05,
}
</script>

<template>
  <TresCanvas v-bind="gl">
    <TresPerspectiveCamera :position="[5, 5, 5]" />

    <Suspense>
      <EffectComposerPmndrs>
        <ScanlinePmndrs v-bind="effectProps" />
      </EffectComposerPmndrs>
    </Suspense>
  </TresCanvas>
</template>

Props

PropDescriptionDefault
blendFunctionDefines how the effect blends with the original scene. See the BlendFunction options.BlendFunction.OVERLAY
densityThe density of the scanlines. Higher values increase the frequency of lines.1.25
opacityThe opacity of the scanlines. Controls the transparency of the effect.1.0
scrollSpeedThe speed at which the scanlines scroll vertically. When set to 0, the scanlines remain static. Any non-zero value animates the scanlines vertically.0.0

Further Reading

For more details, see the Scanline documentation