@wolffo/three-fire
Version:
Modern TypeScript volumetric fire effect for Three.js and React Three Fiber with WebGPU support.
273 lines (266 loc) • 7.79 kB
TypeScript
import { Mesh, Texture, Color, Matrix4, Vector3 } from 'three';
import { MeshBasicNodeMaterial } from 'three/webgpu';
import * as three_tsl from 'three/tsl';
import React from 'react';
import { ReactThreeFiber } from '@react-three/fiber';
/**
* @fileoverview TSL Fire mesh class for vanilla Three.js with WebGPU support
*
* This is the TSL equivalent of the GLSL Fire class, using MeshBasicNodeMaterial
* and node-based shaders for WebGPU compatibility.
*/
interface FireTSLProps {
/** Fire texture (grayscale mask defining fire shape) */
fireTex: Texture;
/** Fire color tint (default: 0xeeeeee) */
color?: Color | string | number;
/** Ray marching iterations - higher = better quality, lower performance (default: 20) */
iterations?: number;
/** Noise octaves for turbulence - fixed at 3 for TSL version */
octaves?: number;
/** Noise scaling parameters [x, y, z, time] (default: [1, 2, 1, 0.3]) */
noiseScale?: [number, number, number, number];
/** Fire shape intensity (default: 1.3) */
magnitude?: number;
/** Noise lacunarity - frequency multiplier (default: 2.0) */
lacunarity?: number;
/** Noise gain - amplitude multiplier (default: 0.5) */
gain?: number;
}
/**
* Volumetric fire effect using TSL ray marching shaders
*
* WebGPU-compatible version using Three.js Shading Language (TSL).
* Creates a procedural fire effect that renders as a translucent volume.
* Uses Perlin noise (mx_noise_float) instead of simplex noise.
*
* @example
* ```ts
* import { FireTSL } from '@wolffo/three-fire/tsl/vanilla'
*
* const texture = textureLoader.load('fire.png')
* const fire = new FireTSL({
* fireTex: texture,
* color: 0xff4400,
* magnitude: 1.5
* })
* scene.add(fire)
*
* // In animation loop
* fire.update(time)
* ```
*/
declare class FireTSL extends Mesh {
material: MeshBasicNodeMaterial;
private uniforms;
private _time;
/**
* Creates a new FireTSL instance
*
* @param props - Configuration options for the fire effect
*/
constructor({ fireTex, color, iterations, noiseScale, magnitude, lacunarity, gain, }: FireTSLProps);
/**
* Updates the fire animation and matrix uniforms
*
* Call this method in your animation loop to animate the fire effect.
*
* @param time - Current time in seconds (optional)
*
* @example
* ```ts
* function animate() {
* fire.update(performance.now() / 1000)
* renderer.render(scene, camera)
* requestAnimationFrame(animate)
* }
* ```
*/
update(time?: number): void;
get time(): number;
set time(value: number);
/**
* Fire color tint
*
* @example
* ```ts
* fire.fireColor = 'orange'
* fire.fireColor = 0xff4400
* fire.fireColor = new Color(1, 0.5, 0)
* ```
*/
get fireColor(): Color;
set fireColor(color: Color | string | number);
/**
* Fire shape intensity
*
* Higher values create more dramatic fire shapes.
* Range: 0.5 - 3.0, Default: 1.3
*/
get magnitude(): number;
set magnitude(value: number);
/**
* Noise lacunarity (frequency multiplier)
*
* Controls how much the frequency increases for each noise octave.
* Range: 1.0 - 4.0, Default: 2.0
*/
get lacunarity(): number;
set lacunarity(value: number);
/**
* Noise gain (amplitude multiplier)
*
* Controls how much the amplitude decreases for each noise octave.
* Range: 0.1 - 1.0, Default: 0.5
*/
get gain(): number;
set gain(value: number);
}
type TSLNode = any;
/**
* Configuration for fire uniforms
*/
interface FireTSLConfig {
fireTex: Texture;
color?: Color | number;
noiseScale?: [number, number, number, number];
magnitude?: number;
lacunarity?: number;
gain?: number;
}
/**
* Uniforms interface for the TSL fire shader
* Using TSLNode type for flexibility with Three.js TSL type system
*/
interface FireTSLUniforms {
fireTex: Texture;
color: TSLNode;
time: TSLNode & {
value: number;
};
seed: TSLNode & {
value: number;
};
invModelMatrix: TSLNode & {
value: Matrix4;
};
scale: TSLNode & {
value: Vector3;
};
noiseScale: TSLNode;
magnitude: TSLNode & {
value: number;
};
lacunarity: TSLNode;
gain: TSLNode & {
value: number;
};
}
declare const createFireUniforms: (config: FireTSLConfig) => FireTSLUniforms;
/**
* Creates the main fire fragment node for ray marching
*
* @param uniforms - Fire shader uniforms
* @param iterations - Number of ray marching iterations (default: 20)
* @returns TSL node for the fragment shader
*/
declare const createFireFragmentNode: (uniforms: FireTSLUniforms, iterations?: number) => three_tsl.ShaderNodeObject<three_tsl.VarNode>;
/**
* @fileoverview React Three Fiber component for TSL Fire effect
*
* WebGPU-compatible version using Three.js Shading Language (TSL).
* Provides the same API as the GLSL FireComponent but with TSL backend.
*/
declare module '@react-three/fiber' {
interface ThreeElements {
fireTSL: ReactThreeFiber.Object3DNode<FireTSL, typeof FireTSL>;
}
}
/**
* Props for the Fire TSL React component
*/
interface FireProps extends Omit<FireTSLProps, 'fireTex'> {
/** Fire texture URL or Three.js Texture object */
texture: string | Texture;
/** Auto-update time from useFrame (default: true) */
autoUpdate?: boolean;
/** Custom update function called each frame */
onUpdate?: (fire: FireTSL, time: number) => void;
/** Child components */
children?: React.ReactNode;
/** Position in 3D space */
position?: [number, number, number];
/** Rotation in radians */
rotation?: [number, number, number];
/** Scale factor (uniform or per-axis) */
scale?: [number, number, number] | number;
}
interface FireRef {
fire: FireTSL | null;
update: (time?: number) => void;
}
/**
* React Three Fiber component for volumetric fire effect (TSL/WebGPU version)
*
* Creates a procedural fire effect using TSL (Three.js Shading Language)
* for WebGPU compatibility. Uses Perlin noise instead of simplex noise.
*
* Note: This component requires WebGPURenderer or a compatible WebGL fallback.
*
* @example
* ```tsx
* import { Fire } from '@wolffo/three-fire/tsl/react'
*
* <Canvas>
* <Fire
* texture="/fire.png"
* color="orange"
* magnitude={1.5}
* scale={[2, 3, 2]}
* position={[0, 0, 0]}
* />
* </Canvas>
* ```
*
* @example With custom animation
* ```tsx
* <Fire
* texture="/fire.png"
* onUpdate={(fire, time) => {
* fire.fireColor.setHSL((time * 0.1) % 1, 1, 0.5)
* }}
* />
* ```
*/
declare const FireComponent: React.ForwardRefExoticComponent<FireProps & React.RefAttributes<FireRef>>;
/**
* Hook for easier access to fire instance and controls
*
* Provides a ref and helper methods for controlling fire imperatively.
*
* @returns Object with ref, fire instance, and update method
*
* @example
* ```tsx
* function MyComponent() {
* const fireRef = useFire()
*
* const handleClick = () => {
* if (fireRef.fire) {
* fireRef.fire.magnitude = 2.0
* }
* }
*
* return (
* <Fire ref={fireRef.ref} texture="/fire.png" />
* )
* }
* ```
*/
declare const useFire: () => {
ref: React.RefObject<FireRef>;
fire: FireTSL | null;
update: (time?: number) => void | undefined;
};
export { FireComponent as Fire, FireComponent, FireTSL as FireMesh, createFireFragmentNode, createFireUniforms, useFire };
export type { FireTSLProps as FireMeshProps, FireProps, FireRef, FireTSLConfig, FireTSLUniforms };