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

@dimitrisgkegkas/postprocessing

v0.1.0

Published

Configurable ink wash effect and Three.js postprocessing composer.

Readme

@dimitrisgkegkas/postprocessing

Ink wash postprocessing and a configurable Three.js composer. ESM with TypeScript types; no React, asset requests, or GLSL build plugin required.

yarn add @dimitrisgkegkas/postprocessing [email protected] [email protected]

Composer

import { SRGBColorSpace, RepeatWrapping, TextureLoader } from 'three'
import { ShaderEffectComposer } from '@dimitrisgkegkas/postprocessing'

renderer.outputColorSpace = SRGBColorSpace
const paper = await new TextureLoader().loadAsync('/your-assets/paper.jpg')
paper.colorSpace = SRGBColorSpace
paper.wrapS = paper.wrapT = RepeatWrapping

const composer = new ShaderEffectComposer(renderer, scene, camera, {
    paperTexture: paper, // optional; otherwise white paper
    draw: { appearance: 1, inkColor: '#82380d', edgeRadius: 0.5 },
    multisampling: 'auto', // low DPR: up to 8 samples; DPR >= 2: none
    antialiasing: true, // final SMAA pass, independent of MSAA
})
composer.setSize(width, height) // CSS pixels, after renderer.setPixelRatio(...)
composer.render(deltaSeconds) // call once per animation frame
composer.setDrawParams({ appearance: 0.5 })
composer.setColorChannel('redBlue')
composer.setAntialiasingEnabled(false)
composer.setDrawEffectEnabled(false)

// After replacing camera or scene:
composer.setMainCamera(nextCamera)
composer.setMainScene(nextScene)

// Cleanup: the composer owns its passes/effects, the application owns textures.
composer.dispose()
paper.dispose()

EffectComposer is an alias of ShaderEffectComposer. Constructor options also include drawEnabled, colorChannel, smaaPreset, edgeDetectionMode, renderToScreen, frameBufferType, depthBuffer, and stencilBuffer. Half-float buffers are the default because the material's red signal can exceed 1. The composer preserves caller renderer color-space settings; use sRGB output for display.

setMultisampling(number | 'auto') changes the sampling policy. On DPR changes, call renderer.setPixelRatio(...) then composer.setSize(width, height); buffers change without replacing effects. setRenderToScreen(false) keeps output in composer.inputBuffer.texture after rendering. This texture is linear working-space data: apply display conversion only at final output. When adding/removing custom passes, call updateOutputPass() afterward so the last enabled pass receives output.

Standalone effect and parameters

import { DrawEffect } from '@dimitrisgkegkas/postprocessing'
import { EffectPass } from 'postprocessing'
const effect = new DrawEffect({ paperTexture: paper, inkColor: '#82380d' })
customComposer.addPass(new EffectPass(camera, effect))
effect.setParams({ edgeStrength: 3, textureStrength: 5 })
effect.setPaperTexture(nextPaper) // old/new textures remain caller-owned
effect.setColorChannel('all')
const current = effect.getParams() // colors are cloned Three.Color instances

| Draw parameter | Default | Meaning | | ----------------- | ------------------- | ----------------------------------------------------- | | appearance | 1 | Reveal, clamped to 0–1 | | inkColor | rgb(51%, 22%, 5%) | Ink wash color | | outlineColor | black | Outline color | | edgeRadius | 0.5 | Sampling radius in CSS pixels | | edgeStrength | 2 | Outline intensity multiplier | | textureStrength | 10 | Paper grain contrast; 0 disables grain | | paperMidpoint | 0.734 | Neutral paper brightness in sRGB | | usePaperTexture | true | Use supplied paper; missing texture always uses white |

Colors follow Three.js conventions: CSS strings and hex values are sRGB, Color instances contain linear values. Setters update uniforms in place; no shader recompilation. setOptions aliases setParams; the composer also retains getEffect('draw') and setEffectParams('draw', params).

Exports also include DRAW_DEFAULTS, ColorChannelEffect, CHANNEL_MASKS, resolveMultisampling, drawFragmentShader, and public option types. Supported channels: all, red, green, blue, redGreen, redBlue, greenBlue.

Input contract

This effect interprets RGB data, as produced by @dimitrisgkegkas/fiber-material: red = depth/orientation edges, green = grain/outline intensity, blue = lighting/ink density. It is not a general-purpose filter for arbitrary photographs. When assembling your own pipeline, put it immediately after the scene's data render, before color grading/tone mapping, then apply SMAA to the finished outlines. A white background represents blank paper.

Targets Three.js WebGLRenderer, not WebGPU/TSL. The package imports safely without a DOM and constructing DrawEffect performs no network requests. Creating the composer/SMAA and rendering require a browser and WebGL.

R3F

Create the composer in an effect using gl, scene, and camera from useThree; dispose it in cleanup. Resize on width/height/DPR changes and render with useFrame((_, delta) => composer?.render(delta), 1). Positive render priority takes over R3F's rendering loop. Keep texture loading/ownership and UI controls in the application. Do not allocate the composer during a React render.

Build and distribution

From the repository root: yarn build:packages, yarn dev:packages, yarn test, or yarn pack:packages. From this folder: yarn build, yarn dev, or npm pack. Publishing runs a fresh build via prepack. Runtime peers are three ~0.174.0 and postprocessing ~6.37.1; they are not bundled. Published under the personal @dimitrisgkegkas npm scope. Current license: UNLICENSED.