Skip to Content
Quarks
DocumentationAdvanced FeaturesValue Generators

Value Generators

Value generators are a core concept in three.quarks that provide flexible ways to generate and modify values over time or based on other parameters. They are used throughout the particle system to control particle properties such as size, color, rotation, emission rate, and more.

Overview

Value generators allow you to define how values change rather than using fixed values. This approach enables dynamic and more natural-looking particle effects. For example, instead of using a constant size for particles, you can make them grow or shrink over their lifetime.

Types of Value Generators

three.quarks provides several types of value generators to suit different needs:

Basic Value Generators

These generators produce simple numeric values:

ConstantValue

import { ConstantValue } from "three.quarks"; // Creates a value generator that always returns 5 const constant = new ConstantValue(5);

The ConstantValue generator returns the same value every time. It’s useful when you want a fixed property.

IntervalValue

import { IntervalValue } from "three.quarks"; // Creates a value generator that returns a random value between 1 and 10 const interval = new IntervalValue(1, 10);

The IntervalValue generator returns a random value within a specified range. The value is determined once when the particle is created and remains constant for that particle’s lifetime.

Function-based Value Generators

These generators produce values that can change over time or based on a parameter:

PiecewiseBezier

import { PiecewiseBezier, Bezier } from "three.quarks"; // Creates a Bezier curve from 0 to 1 const bezier = new Bezier(0, 0.33, 0.66, 1); // Creates a piecewise bezier function starting at time 0 const piecewise = new PiecewiseBezier([[bezier, 0]]);

The PiecewiseBezier generator uses Bezier curves to interpolate values smoothly. It’s particularly useful for creating easing functions or natural motion curves.

Color Generators

These generators are specific to producing color values:

ConstantColor

import { ConstantColor } from "three.quarks"; import { Vector4 } from "three"; // Creates a color generator that always returns red (RGBA) const red = new ConstantColor(new Vector4(1, 0, 0, 1));

The ConstantColor generator returns a constant color value.

ColorRange

import { ColorRange } from "three.quarks"; import { Vector4 } from "three"; // Creates a color generator that returns a random color between red and blue const colorRange = new ColorRange( new Vector4(1, 0, 0, 1), // Red new Vector4(0, 0, 1, 1), // Blue );

The ColorRange generator returns a random color within a specified range. Like IntervalValue, the color is determined once for each particle.

RandomColor

import { RandomColor } from "three.quarks"; import { Vector4 } from "three"; // Creates a color generator that returns a different random color between red and blue each time const randomColor = new RandomColor( new Vector4(1, 0, 0, 1), // Red new Vector4(0, 0, 1, 1), // Blue );

Unlike ColorRange, the RandomColor generator produces a new random color each time it’s called.

Gradient

import { Gradient } from "three.quarks"; import { Vector3 } from "three"; // Creates a gradient from black to white const gradient = new Gradient( [ [new Vector3(0, 0, 0), 0], // Black at position 0 [new Vector3(1, 1, 1), 1], // White at position 1 ], [ [1, 0], // Alpha 1 at position 0 [1, 1], // Alpha 1 at position 1 ], );

The Gradient generator interpolates colors based on a parameter (usually time). It’s excellent for smooth color transitions over a particle’s lifetime.

RandomColorBetweenGradient

import { RandomColorBetweenGradient, Gradient } from "three.quarks"; // Create two gradients const gradient1 = new Gradient(/* ... */); const gradient2 = new Gradient(/* ... */); // Create a random color between the two gradients const randomGradient = new RandomColorBetweenGradient(gradient1, gradient2);

This generator creates random colors between two gradients, allowing for more varied color transitions.

Rotation Generators

These generators are specific to producing rotation values:

AxisAngleGenerator

import { AxisAngleGenerator, ConstantValue } from "three.quarks"; import { Vector3 } from "three"; // Creates a rotation around the Y axis with a constant speed const rotation = new AxisAngleGenerator( new Vector3(0, 1, 0), // Y axis new ConstantValue(1), // 1 radian per second );

The AxisAngleGenerator rotates particles around a specified axis by a given angle.

EulerGenerator

import { EulerGenerator, ConstantValue } from "three.quarks"; // Creates a rotation that changes in all three axes const rotation = new EulerGenerator( new ConstantValue(0.1), // X rotation new ConstantValue(0.2), // Y rotation new ConstantValue(0.3), // Z rotation );

The EulerGenerator applies rotation using Euler angles, which is useful for more complex rotations.

RandomQuatGenerator

import { RandomQuatGenerator } from "three.quarks"; // Creates random rotations const random = new RandomQuatGenerator();

The RandomQuatGenerator generates random rotations, which is useful for creating varied orientations.

Vector Generators

These generators are specific to producing 3D vector values:

Vector3Function

import { Vector3Function, ConstantValue } from "three.quarks"; // Creates a vector that grows in all dimensions const vectorFunc = new Vector3Function( new ConstantValue(1), // X component new ConstantValue(2), // Y component new ConstantValue(3), // Z component );

The Vector3Function generator creates 3D vectors based on separate functions for each component.

Using Value Generators in Particle Systems

Value generators are used throughout the particle system configuration to control various properties:

import { ParticleSystem, ConstantValue, PiecewiseBezier, Gradient, SphereEmitter, ColorOverLife, SizeOverLife, } from "three.quarks"; import { Vector3, Vector4 } from "three"; // Create a particle system const system = new ParticleSystem({ // Use a constant value for particle lifetime startLife: new ConstantValue(2), // Use a constant value for initial speed startSpeed: new ConstantValue(5), // Use a sphere emitter shape: new SphereEmitter(), // Add behaviors that use function generators behaviors: [ // Size changes over particle lifetime using a bezier curve new SizeOverLife(new PiecewiseBezier(/* ... */)), // Color changes over particle lifetime using a gradient new ColorOverLife(new Gradient(/* ... */)), ], });

Creating Custom Value Generators

You can create custom value generators by implementing the appropriate interface:

import { ValueGenerator, GeneratorMemory, FunctionJSON } from "three.quarks"; // Create a custom value generator class CustomValueGenerator implements ValueGenerator { type: "value" = "value"; constructor(private parameter: number) {} startGen(memory: GeneratorMemory): void { // Initialize if needed } genValue(memory: GeneratorMemory): number { // Generate and return a value return Math.sin((this.parameter * Date.now()) / 1000); } toJSON(): FunctionJSON { return { type: "CustomValueGenerator", parameter: this.parameter, }; } clone(): ValueGenerator { return new CustomValueGenerator(this.parameter); } }

Performance Considerations

When using value generators, keep these performance tips in mind:

  1. ConstantValue is the most efficient generator as it doesn’t need to compute anything.
  2. Complex generators like PiecewiseBezier are more CPU-intensive, so use them sparingly with large numbers of particles.
  3. Consider using startGen() to pre-compute values for particles when possible.

Examples

Size that grows and then shrinks

import { PiecewiseBezier, Bezier, SizeOverLife } from "three.quarks"; // Create a bezier curve that rises and falls const curve = new Bezier(0, 1, 1, 0); const sizeChange = new PiecewiseBezier([[curve, 0]]); // Add it to a behavior const behavior = new SizeOverLife(sizeChange);

Color that transitions from red to blue over lifetime

import { Gradient, ColorOverLife } from "three.quarks"; import { Vector3 } from "three"; // Create a gradient from red to blue const colorChange = new Gradient( [ [new Vector3(1, 0, 0), 0], // Red at start [new Vector3(0, 0, 1), 1], // Blue at end ], [ [1, 0], // Full opacity at start [0, 1], // Fade out at end ], ); // Add it to a behavior const behavior = new ColorOverLife(colorChange);

Random rotation speed around y-axis

import { AxisAngleGenerator, IntervalValue, RotationOverLife, } from "three.quarks"; import { Vector3 } from "three"; // Create a rotation with random speed between 1 and 3 radians per second const rotation = new AxisAngleGenerator( new Vector3(0, 1, 0), new IntervalValue(1, 3), ); // Add it to a behavior const behavior = new RotationOverLife(rotation);

Conclusion

Value generators are a powerful feature of three.quarks that allow for flexible and dynamic particle effects. By combining different generators and behaviors, you can create complex and visually appealing effects that would be difficult to achieve with static values.

Next Steps

Now that you understand value generators, here are some recommended next steps:

  1. Explore Behaviors: Learn more about Behaviors to understand how to apply value generators to different particle properties.

  2. Optimize Performance: Review the Optimization Techniques guide to ensure your particle systems run efficiently.

  3. Study Examples: Look at the Examples section to see value generators in action in complete particle systems.

  4. Advanced Integration: Integrate your particle systems with other Three.js features like physics simulations or scene transitions.

Last updated on