Skip to content

Sparkles

<Sparkles /> makes sparkles on your geometry's vertices – optionally guided by a directional light.

Usage

Basic

vue
<script setup lang="ts">
import { OrbitControls, Sparkles, TorusKnot } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
</script>

<template>
  <TresCanvas clear-color="#333">
    <TresPerspectiveCamera :position="[0, 0, 5]" />
    <TorusKnot :args="[1, 0.25, 128, 16]">
      <TresMeshBasicMaterial color="#222" />
      <Sparkles />
    </TorusKnot>
    <OrbitControls />
  </TresCanvas>
</template>

With TresDirectionalLight

By default, sparkles appear on the up-facing vertices. However, you can pass a directional light to the component. Moving the directional light will cause "lit" vertices to emit sparkles.

vue
<script setup lang="ts">
import { OrbitControls, Sparkles, Sphere, Torus } from '@tresjs/cientos'
import { TresCanvas, useRenderLoop } from '@tresjs/core'
import { shallowRef } from 'vue'

const lightRef = shallowRef()

useRenderLoop().onLoop(({ elapsed }) => {
  if (lightRef.value) {
    lightRef.value.position.x = Math.cos(elapsed) * 2.5
    lightRef.value.position.y = Math.sin(elapsed) * 2.5
  }
})
</script>

<template>
  <TresCanvas clear-color="#333">
    <TresPerspectiveCamera :position="[0, 0, 8]" />
    <TresDirectionalLight ref="lightRef">
      <Sphere
        color="white"
        :scale="0.1"
      />
    </TresDirectionalLight>
    <Torus :args="[1, 0.25, 16, 48]">
      <TresMeshBasicMaterial color="#222" />
      <Sparkles :directional-light="lightRef" />
    </Torus>
    <OrbitControls />
  </TresCanvas>
</template>

Sequences

All props beginning with :sequence- are used to define how a particle changes as it progresses (See also: Mixes). :sequence- props are of the type Gradient<T>, which can be any one of:

  • T: a single value
  • [T, T, T, ...]: an evenly distributed series of values
  • [[number, T], [number, T], ...]: an unevently distributed series of values, where number is a gradient "stop" from 0 to 1.

For example, all of these are acceptable values for Gradient<TresColor>:

  • 'red'
  • ['red', 'blue', 'green']
  • [[0.1, 'red'], [0.25, 'blue'], [0.5, 'green']]
vue
<script setup lang="ts">
import { OrbitControls, Sparkles, Sphere } from '@tresjs/cientos'
import { TresCanvas } from '@tresjs/core'
</script>

<template>
  <TresCanvas clear-color="#333">
    <TresPerspectiveCamera :position="[0, 0, 8]" />
    <Sphere>
      <TresMeshBasicMaterial color="#222" />
      <Sparkles
        :sequence-alpha="[[0., 0.], [0.6, 1.0], [0.7, 0.0], [1.0, 1.0]]"
        :sequence-color="['yellow', 'white', 'orange', 'red', 'black']"
        :sequence-offset="[[0.7, [0, 0, 0]], [0.75, [0, 0.1, 0]], [1.0, [0, 0.5, 0]]]"
        :sequence-size="[[0.0, 0.0], [0.7, 1.0]]"
        :sequence-surface-distance="[[0.0, 0.0], [0.7, 1.0]]"
        :lifetime-sec="2.0"
        :size="2"
        :surface-distance="0.8"
        :mix-color="1.0"
      />
    </Sphere>
    <OrbitControls />
  </TresCanvas>
</template>

Mixes

All props beginning with :mix- allow you to specify how a particle "progresses" through a corresponding :sequence- prop. E.g., :mix-alpha affects :sequence-alpha.

  • If the :mix- prop is 0.0, 'progress' through the :sequence- is determined entirely by the light shining on the surface of the sparkling mesh.1
  • If the :mix- prop is 1.0, 'progress' through the :sequence- is determined entirely by the particle's lifetime.

1) More precisely, the value is determined by the dot product of the directionalLight's inverted normalized position and each of the sparkling mesh's vertex normals.

vue
<script setup lang="ts">
import { Sparkles, Sphere } from '@tresjs/cientos'
import { TresCanvas, useRenderLoop } from '@tresjs/core'
import { TresLeches, useControls } from '@tresjs/leches'
import { shallowRef } from 'vue'
import '@tresjs/leches/styles'

const lightRef = shallowRef()
const { value: mix } = useControls({
  mix: { value: 0, min: 0, max: 1, step: 0.01 },
})

useRenderLoop().onLoop(({ elapsed }) => {
  if (lightRef.value) {
    lightRef.value.position.x = Math.cos(elapsed) * 3
    lightRef.value.position.y = Math.sin(elapsed) * 3
  }
})
</script>

<template>
  <TresLeches class="top-0 important-left-4" />
  <TresCanvas clear-color="#333">
    <TresPerspectiveCamera :position="[-2.5, 0, 8]" />
    <TresDirectionalLight ref="lightRef">
      <Sphere
        color="white"
        :scale="0.1"
      />
    </TresDirectionalLight>
    <Sphere :args="[1, 16, 16]">
      <TresMeshBasicMaterial color="#222" />
      <Sparkles
        :directional-light="lightRef"
        :mix-alpha="mix"
        :mix-color="mix"
        :mix-offset="mix"
        :mix-size="mix"
        :mix-surface-distance="mix"
        :lifetime-sec="2"
        :sequence-alpha="[0.1, 1.0]"
        :sequence-surface-distance="[0.1, 0.5]"
      />
    </Sphere>
  </TresCanvas>
</template>

Props

NameDescription
mapType: Texture | string
Default: 'https://raw.githubusercontent.com/Tresjs/asset...

Texture or image path for individual sparkles
geometryType: Object3D | BufferGeometry
Default: undefined

Vertices of the geometry will be used to emit sparkles. Geometry normals are used for sparkles' traveling direction and for responding to the directional light prop.
  • If provided, the component will use the passed geometry.
  • If no geometry is provided, the component will try to make a copy of the parent object's geometry.
  • If no parent geometry exists, the component will create and use an IcosphereGeometry.
directionalLightType: Object3D
Default: undefined

Particles "light up" when their normal "faces" the light. If no directionalLight is provided, the default "up" vector will be used.
lifetimeSecType: number
Default: 0.4

Particle lifetime in seconds
cooldownSecType: number
Default: 2.0

Particle cooldown in seconds – time between lifetime end and respawn
normalThresholdType: number
Default: 0.7

Number from 0-1 indicating how closely the particle needs to be faced towards the light to "light up". (Lower == more flexible)
noiseScaleType: number
Default: 3.0

Scale of the noise period (lower == more slowly cycling noise)
scaleNoiseType: number
Default: 1.0

Noise coefficient applied to particle scale
offsetNoiseType: number
Default: 0.1

Noise coefficient applied to particle offset
lifetimeNoiseType: number
Default: 0.0

Noise coefficient applied to particle lifetime
sizeType: number
Default: 1.0

Particle scale multiplier
alphaType: number
Default: 1.0

Opacity multiplier
offsetType: number
Default: 1.0

Offset multiplier
surfaceDistanceType: number
Default: 1.0

Surface distance multiplier
sequenceColorType: Gradient<TresColor>
Default: [[0.7, '#82dbc5'], [0.8, '#fbb03b']]

'Sequence' props: specify how a particle changes as it "progresses". See also "mix" props.
Color sequence as particles progress
sequenceAlphaType: Gradient<number>
Default: [[0.0, 0.0], [0.10, 1.0], [0.5, 1.0], [0.9, 0.0]]

Opacity sequence as particles progress
sequenceOffsetType: Gradient<[number, number, number]>
Default: [0.0, 0.0, 0.0]

Distance sequence as particles progress
sequenceNoiseType: Gradient<[number, number, number]>
Default: [0.1, 0.1, 0.1]

Noise sequence as particles progress
sequenceSizeType: Gradient<number>
Default: [0.0, 1.0]

Size sequence as particles progress
sequenceSurfaceDistanceType: Gradient<number>
Default: [0.05, 0.08, 0.1]

Distance from surface (along normal) as particles progress
mixColorType: number
Default: 0.5

'mix*' props: A particle "progresses" with a mix of two factors:
  • its normal "facing" the directionalLight
  • its lifetime
'mix*' props specify the relationship between the two factors.
How is a particle's progress for color calculated? (0: normal, 1: particle lifetime)
mixAlphaType: number
Default: 1.

How is a particle's progress for alpha calculated? (0: normal, 1: particle lifetime)
mixOffsetType: number
Default: 1.

How is a particle's progress for offset calculated? (0: normal, 1: particle lifetime)
mixSizeType: number
Default: 0.

How is a particle's progress for size calculated? (0: normal, 1: particle lifetime)
mixSurfaceDistanceType: number
Default: 1.

How is a particle's progress for surface distance calculated? (0: normal, 1: particle lifetime)
mixNoiseType: number
Default: 1.

How is a particle's progress for lifetime calculated? (0: normal, 1: particle lifetime)
blendingType: Blending
Default: AdditiveBlending

Material blending
transparentType: boolean
Default: true

Material transparency
depthWriteType: boolean
Default: false

Material depth write
5-39