filmHD

@three-blocks/coreWebGPUWebGL
filmHD(inputNode : Node, options : Object) : FilmHDNode

Cinematic film grain with blue noise, scanlines, and temporal stability.

Features

  • Temporally stable grain (no flickering) using blue noise + white noise blend
  • Shadow-weighted grain (more visible in darks via grainResponseNode)
  • Animated scanlines for CRT/film look
  • Frame interpolation for smooth temporal evolution
  • Artist-friendly controls for all parameters

Algorithm

  • Blends blue noise (65%) + white noise (35%) for quality grain
  • Per-frame jitter and rotation for temporal variation
  • Luminance-based weighting (darks get more grain)
  • Optional scanline overlay with sine wave
Parameters
inputNodeNode
Source color buffer.
optionsoptionalObject
Optional configuration nodes.
Default is {}.
  • intensityNodeoptionalNode
    Grain intensity [0..1] (default: 0.82).
  • grainScaleNodeoptionalNode
    Grain density multiplier (default: 1.5).
  • grainSpeedNodeoptionalNode
    Temporal evolution speed (default: 12.0).
  • grainResponseNodeoptionalNode
    Shadow weighting [0..1] (default: 0.85).
  • grainContrastNodeoptionalNode
    Grain contrast multiplier (default: 1.25).
  • scanlineIntensityNodeoptionalNode
    Scanline blend amount [0..1] (default: 0.075).
  • scanlineFrequencyNodeoptionalNode
    Scanline frequency (default: 900.0).
  • blueNoiseLevelNodeoptionalNode
    Blue noise recursion level for quality.
  • timeNodeoptionalNode
    Override time input for animation control.
  • uvNodeoptionalNode
    Custom UV coordinates.
Returns
FilmHDNode — Film grain effect node.
Example
import { filmHD } from '@three-blocks/core';
import { pass, uniform } from 'three/tsl';

const scenePass = pass(scene, camera);

const grainEffect = filmHD(scenePass, {
  intensityNode: uniform(0.8),      // Strong grain
  grainScaleNode: uniform(1.5),     // Fine grain
  grainSpeedNode: uniform(12.0),    // Moderate animation
  grainResponseNode: uniform(0.85), // More grain in shadows
  scanlineIntensityNode: uniform(0.075), // Subtle scanlines
  scanlineFrequencyNode: uniform(900.0)
});

postProcessing.outputNode = grainEffect;