npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

powershot-threejs

v0.7.0

Published

Authentic digital camera ISP and analog signal post-processing for Three.js WebGPU.

Readme

powershot for three.js

Authentic digicam, analog tape, film and night-vision emulation post-processing for Three.js.

Play live here.

https://cl0nazepamm.github.io/powershot-threejs/

Run the demo

npm install
npm run dev

Requires WebGPU.

Install in your Three.js project

npm install powershot-threejs three

Drop it on your scene (default workflow)

Every effect is a THREE.RenderPipeline output-node pass — wrap the node chain you already have and you're done. Sizing, frame counting, and per-frame bookkeeping are automatic:

import * as THREE from "three/webgpu";
import { pass } from "three/tsl";
import { Pipeline, powerShotPass } from "powershot-threejs";

const renderer = new THREE.WebGPURenderer({ canvas });
await renderer.init();

const powershot = new Pipeline(renderer);
powershot.setMode("analog");            // or "digital"
powershot.setPreset("powershot");
powershot.setInputEncoding("linear");   // a raw scene pass carries linear light

const renderPipeline = new THREE.RenderPipeline(renderer);
renderPipeline.outputNode = powerShotPass(pass(scene, camera), powershot);

function animate() {
  renderPipeline.render();
}

filmPass, infraredPass, nightshotPass, and solarFlarePass work exactly the same way, and any existing output node can stand in for the scene pass — stack your own manipulations first and put the camera last. Two rules:

  • Film replaces the tonemap. filmPass must be the only display transform in the chain (no ACES / AgX before it) and wants setInputEncoding("linear").
  • Feeding an already display-referred chain (post-tonemap manipulations)? Skip setInputEncoding — the default expects encoded input.

Adapters auto-size to the source; pass { autoSize: false } or { resolutionScale } to manage effect resolution yourself. See ADVANCED.md for the full adapter contract.

Processing images and videos

The same pipelines also run standalone on any texture: create a pipeline, pick a preset by name, call render(texture) every frame. Pick your mode below and copy its section. All snippets share this setup:

import * as THREE from "three/webgpu";

const renderer = new THREE.WebGPURenderer({ canvas });
await renderer.init();

The input texture can be an image, a video, or a render target's .texture. render() locks the internal processing resolution to the first frame it sees; call setSize(w, h) first to pick your own (e.g. a low authentic-camera resolution). When you need deterministic control — explicit frame numbers, fixed dt, an output render target — use renderTexture(texture, frame, options); see ADVANCED.md.

Digicam

Mid-2000s point-and-shoot look: sensor noise, sharpening halos and JPEG blocks.

import { Pipeline } from "powershot-threejs";

const powershot = new Pipeline(renderer);
powershot.setMode("digital");
powershot.setPreset("powershot");

// each frame:
powershot.render(inputTexture);

Presets: cybershot, powershot, coolpix, exilim, ixus.

Analog tape

VHS / camcorder look: chroma bleed, tracking errors, dropouts. Same Pipeline as digicam, different mode:

import { Pipeline } from "powershot-threejs";

const powershot = new Pipeline(renderer);
powershot.setMode("analog");
powershot.setPreset("powershot");

// each frame:
powershot.render(inputTexture);

Film

Motion-picture film: a real negative-to-print chain with film stocks, grain, halation, gate weave and flicker.

[!IMPORTANT] Film runs alone, on linear light. Do not combine it with the other PowerShot modes, and do not tone-map before it (no ACES / AgX / renderer tone mapping) — the negative→print chain is the tone map. Feed it a scene-linear HDR render target with renderer.toneMapping = THREE.NoToneMapping.

import * as THREE from "three/webgpu";
import { FilmPipeline } from "powershot-threejs";

const renderer = new THREE.WebGPURenderer({ canvas });
await renderer.init();
renderer.toneMapping = THREE.NoToneMapping;

const film = new FilmPipeline(renderer);
film.setInputEncoding("linear"); // input is scene-linear, not sRGB
film.setPreset("kodak_500t");

// each frame:
film.render(linearSceneTexture);

Stocks: kodak_500t, kodak_200t, kodak_250d, kodak_50d.

White phosphor

Night-vision tube: local gain, intensifier halo, scintillation, tube vignette — tuned around a P45-style white phosphor tube.

import { InfraredPipeline } from "powershot-threejs";

const infrared = new InfraredPipeline(renderer);
infrared.setPreset("white_phosphor");

// each frame (frame timing for the tube's auto-brightness loop is automatic):
infrared.render(inputTexture);

NightShot

Sony Handycam "NightShot": a camcorder CCD with the IR-cut filter flipped out — AGC breathing, heavy noise, vertical smear, green monochrome, then the analog tape path.

import { NightshotPipeline } from "powershot-threejs";

const nightshot = new NightshotPipeline(renderer);
nightshot.setPreset("nightshot_plus");

// each frame:
nightshot.render(inputTexture);

Solar Flares

Solar Flares, the spectral sunlight flare, is a separate scene-linear optical pass, not a sprite effect or a digicam preset. It uses a traced Heliar prescription for internal reflections, an aperture FFT for diffraction, a source-centred glare halo, and a low-frequency veiling layer. Run it before PowerShot, film, exposure, tone mapping, and output conversion:

import * as THREE from "three/webgpu";
import { pass } from "three/tsl";
import {
  SolarFlarePipeline,
  loadHeliarTronnierFlareProfile,
  solarFlarePass,
} from "powershot-threejs";

const scenePass = pass(scene, camera);
const profile = await loadHeliarTronnierFlareProfile();
const flare = new SolarFlarePipeline(renderer, {
  profile,
  camera,
  sun, // THREE.DirectionalLight
});
flare.setSize(width, height);
flare.setAperture({ fNumber: 8, blades: 7 });

const renderPipeline = new THREE.RenderPipeline(renderer);
renderPipeline.outputNode = solarFlarePass(scenePass, flare, {
  camera,
  sun,
  depthTexture: scenePass.getTexture("depth"),
});

function animate() {
  renderPipeline.render();
}

The true solar direction is never clamped to the viewport, so the lens can flare when the sun is just outside frame. Scene depth resolves partial on-screen solar occlusion. For off-screen occlusion, supply a camera-to-sun visibility provider. Run npm run dev and open /powershot-threejs/flare.html for the interactive WebGPU sunlight, aperture, component-isolation, and occlusion demo. See SOLAR_FLARES.md for the optical model, controls, PowerShot ordering, and calibration contract.

Going further

Per-mode controls, linear/HDR input, output grading, THREE.RenderPipeline integration, real NIR input and the repo layout are in ADVANCED.md.

Acknowledgements

  • NTSC
  • OpenISP