Skip to content
Voro
  1. Image
  2. Effects

Ink Bleed

Example Built with Kernel FX Ships with Voro as an example. It may change between versions.

Ink Bleed retains ink and water on a simulated sheet. Deposit mode reads RGB as ink colour and alpha as the amount laid down. Subject Match paints toward the incoming picture using a limited pigment palette.

Place Ink Bleed under Effects in the Image view. Connect text or a drawing with alpha to image and begin with Deposit and Continuous rhythm. Set Ink Rate for how long marks remain on screen, then adjust Water and Sizing to control their spread.

For footage, try Subject Match. For separate prints, choose Stamp and set Stamp Interval and Fresh Sheet.

  • image supplies ink colour and coverage in Deposit, or the subject in Subject Match.
  • field drags the wash through Field Flow.
  • mask pre-wets areas of the sheet through Mask Water.
  • resist protects areas as masking fluid.
  • out shows the finished sheet or selected Tap.
  • Ink Rate sets deposition per second. Nib Width limits mark detail in millimetres.
  • Water wets the mark. Sizing keeps water on the surface; lower values let the sheet absorb it.
  • Rhythm selects Continuous, Stamp or Triggered. In Triggered mode, a rising Trigger past 0.5 makes an impression.
  • Fresh Sheet controls how much previous ink remains between Stamp or Triggered impressions.
  • Surface selects the material. Sheet Size and Sheet Resolution set its physical size and simulation detail.
  • Ink Behaviour selects darkening ink, Body paint that can cover a dark ground, or Discharge that lifts bound pigment.
  • Dry Time, Separation and Staining control drying, pigment separation and retention.

A full-alpha image deposits ink continuously in Deposit mode. Use alpha, Stamp or Subject Match to control that accumulation. Set Premultiplied Input to match how the incoming image stores its colour and alpha.

Inputs

  • image image required
    RGBA
  • field image
    2 channels
  • mask image
    single channel
  • resist image
    single channel

Outputs

  • out image
    RGBA

Ink

Mix (Mix) Float op('ink_bleed').par.Mix

Blend the source to the finished sheet. 0 is an exact passthrough.

Default:
1
Range:
0 to 1
Ink Source (Source) Menu op('ink_bleed').par.Source

Deposit: the image IS the ink - RGB is its colour, ALPHA is how much is being laid this instant, and holding a mark on screen soaks it in for that long. Subject Match: the image is a subject and a painter reproduces it with the pigments in the box, correcting against what is already on the sheet.

Default:
deposit
Options:
deposit, subject
Ink Rate (Rate) Float op('ink_bleed').par.Rate

Ink laid per second at full alpha. Real seconds, so a mark held for two seconds soaks the same at 30, 60 or 120 frames per second - and a nib that moves fast leaves less behind than one that lingers, which is why DRAWING wants a far higher rate than holding does. Under Stamp and Triggered the whole interval's worth arrives in one generation instead, so changing the rhythm redistributes the ink in time without changing how much of it there is.

Default:
12
Range:
0 to 120
Bite (Bite) Float op('ink_bleed').par.Bite

How much of the ink is driven into the fibre where it lands and stays there. This is what leaves a permanent record of the mark: at 0 every drop goes into the surface film and the water is free to carry the whole mark away, which is how writing dissolves into a blot with nothing left where it was written.

Default:
0.45
Range:
0 to 1
Nib Width (Brush) Float op('ink_bleed').par.Brush

Millimetres. A mark cannot be read finer than the nib that laid it, and a brush cannot resolve detail finer than itself - so this is the real abstraction control in both modes. Small for writing and calligraphy, large for a loose wash.

Default:
1.5
Range:
0.3 to 40
Water (Wet) Float op('ink_bleed').par.Wet

Film depth the mark wets the surface to, in microns. A loaded round carries 40-120, a pen far less. The water follows the ink: the surface is wet where material is being laid and nowhere else, which is what puts a wet edge on the mark's own boundary.

Default:
30
Range:
0 to 300
Rhythm (Rhythm) Menu op('ink_bleed').par.Rhythm

Continuous: ink flows in every frame - this is drawing and calligraphy. Stamp: the whole frame is laid at once every interval and the material works in between, so successive frames print over each other into one sheet. Triggered: one impression per rising edge of Trigger.

Default:
continuous
Options:
continuous, stamp, triggered
Stamp Interval (Interval) Float op('ink_bleed').par.Interval

Seconds between impressions in Stamp, and the size of one charge in Triggered - an impression carries Ink Rate multiplied by this, so it is worth the same as that many seconds of continuous ink.

Default:
1.5
Range:
0.05 to 30
Trigger (Trigger) Float op('ink_bleed').par.Trigger

Rising past 0.5 lays one impression in Triggered rhythm. Bind it to anything - a beat, an LFO, a button. The edge is read once per generation, so an impression lands on the generation after the one that crossed.

Default:
0
Range:
0 to 1
Fresh Sheet (Fresh) Float op('ink_bleed').par.Fresh

Stamp and Triggered only. How much of a NEW sheet each impression is pulled onto. Ink does not fade out of paper, so this is not a decay: it is the printer taking the last pull off the press. At 1 every impression lands on clean paper and the result is a stop-motion print that updates whole. At 0 nothing is ever taken away and impressions build into a palimpsest until the sheet is at its mass tone. In between, the last pull is still faintly there under this one.

Default:
0.85
Range:
0 to 1
Ink Behaviour (Behaviour) Menu op('ink_bleed').par.Behaviour

Absorbing: ink darkens the ground, the subtractive default. Body: the fourth pigment becomes titanium white, so the material can go LIGHTER than the ground - drop Ground Reflectance and this is chalk, silver ink or gouache on a dark sheet. Discharge: the mark removes what is bound in the surface and hands it back to the water, which carries it outward - bleach on a dyed sheet.

Default:
absorbing
Options:
absorbing, body, discharge
Discharge Strength (Bleach) Float op('ink_bleed').par.Bleach

How hard a discharge mark strips bound pigment out of the fibre. What it takes goes back into the water, not away, so it blooms outward and settles in a rim.

Default:
1
Range:
0 to 3
Premultiplied Input (Premult) Toggle op('ink_bleed').par.Premult

Off for a straight mark - a Text TOP, where RGB is the ink colour at full strength and alpha is coverage. On when the incoming image already has its colour multiplied by its alpha, so the colour is recovered before it is read as ink.

Default:
Off
Options:
Off, On
Dry Nib (Drybrush) Float op('ink_bleed').par.Drybrush

Dries the nib so it only touches the surface's peaks. The skip is the sheet's own tooth, not a texture.

Default:
0
Range:
0 to 1
Load (Load) Float op('ink_bleed').par.Load

Subject Match only. How much of the missing pigment one wash carries. Low values glaze up over many passes; 1 lays the whole match in one stroke.

Default:
0.4
Range:
0 to 1
Correct (Correct) Float op('ink_bleed').par.Correct

Subject Match only. How much the painter corrects against what is already on the sheet. At 1 a passage that already matches receives nothing, so the painting settles and follows a moving subject. At 0 nothing is ever taken back and the material does all of it - which is what Deposit does by construction.

Default:
1
Range:
0 to 1
Strength (Strength) Float op('ink_bleed').par.Strength

Subject Match only. Scales the matched absorbance. Above 1 the painter overstates the subject.

Default:
0.75
Range:
0.2 to 3
Values (Values) Int op('ink_bleed').par.Values

Subject Match only. How many values the painter reads the subject as. A watercolourist simplifies a scene into a handful of washes, each laid where it is right and stopped where it is not - and those stopping places are where the material gets its hard, darkened edges. 0 keeps continuous tone and gives a soft, edgeless painting.

Default:
9
Range:
0 to 14
Wet In Wet (Wetonwet) Float op('ink_bleed').par.Wetonwet

Subject Match only. How wet a passage may still be before the brush works into it again. At 0 the painter waits for each wash to dry and glazes over it. At 1 the brush keeps working the passage while it is soaking, so everything blends and nothing sets.

Default:
0.05
Range:
0 to 1

Surface

Surface (Surface) Menu op('ink_bleed').par.Surface

Hot press is smooth, cold press is the classic NOT surface, rough is deeply toothed, handmade keeps the mould's laid lines. Silk is woven, so the wick runs along the weave and dye travels further with the warp than across it. Plaster drinks everything and binds on contact. Glass drinks nothing - it beads, runs and drips. Stone is deep, thirsty and slow.

Default:
cold
Options:
hot, cold, rough, handmade, silk, plaster, glass, stone
Sheet Size (Papersize) Float op('ink_bleed').par.Papersize

Long edge of the sheet in millimetres. This is the whole domain: everything physical is measured against it, so a small sheet has visibly coarser fibre and shorter capillary runs.

Default:
210
Range:
60 to 760
Weight (Weight) Float op('ink_bleed').par.Weight

Sheet weight in gsm. A heavy sheet holds more water before it floods and cockles less.

Default:
300
Range:
90 to 640
Fibre Height (Tooth) Float op('ink_bleed').par.Tooth

Peak-to-valley height of the surface in microns. Pigment granulates into the valleys and a dry nib only touches the peaks.

Default:
95
Range:
0 to 280
Sizing (Sizing) Float op('ink_bleed').par.Sizing

Gelatine size. High sizing keeps water on the surface so it can flow; low sizing drinks it straight into the fibre like blotting paper. This is the single control that decides whether a pen line stays a line or becomes a furry blot. The surface re-centres it - glass is effectively fully sized however low this goes, plaster barely sized however high.

Default:
0.55
Range:
0 to 1
Weave Direction (Weave) Float op('ink_bleed').par.Weave

Degrees. Which way the warp runs on a woven surface. Only silk is woven; on every other surface this does nothing.

Default:
0
Range:
-180 to 180
Ground Tone (Papertone) Float op('ink_bleed').par.Papertone

Warm rag at 1, cool bright white below 0.

Default:
0.3
Range:
-1 to 1
Ground Reflectance (Papershade) Float op('ink_bleed').par.Papershade

Cotton rag reflects about 0.93. In Absorbing behaviour this is the lightest value the effect can produce, because there is no white pigment in the box. Turn it down toward black and switch Ink Behaviour to Body, and the material paints light onto a dark sheet instead.

Default:
0.93
Range:
0.02 to 1
Sheet Resolution (Simres) Menu op('ink_bleed').par.Simres

Simulation cells along the sheet's long edge, independent of the output. Raise it for finer capillary structure and finer writing, not for a sharper picture.

Default:
1024
Options:
512, 768, 1024, 1408
Sheet (Seed) Int op('ink_bleed').par.Seed

Which sheet out of the block. Same seed, same fibre.

Default:
11
Range:
0 to 99999

Water

Mobility (Mobility) Float op('ink_bleed').par.Mobility

Scales the film's lubrication flow. The law is depth-squared, so puddles run and thin films barely creep - which is why a wash sets as it dries without any control saying so. Turn it down and transport happens inside the fibre instead, which is what ink on paper actually does.

Default:
1
Range:
0 to 4
Capillary Suction (Suction) Float op('ink_bleed').par.Suction

How hard dry fibre beside a wet passage pulls water out of the film. The wet edge is drained fastest, the water replacing it arrives carrying pigment, and the pigment stays when the water is gone. That is where a tideline comes from.

Default:
1
Range:
0 to 4
Absorbency (Absorbency) Float op('ink_bleed').par.Absorbency

How fast the surface drinks the free film into itself. The surface re-centres it: plaster and stone drink hard, glass not at all.

Default:
1
Range:
0 to 3
Capillary Wick (Wick) Float op('ink_bleed').par.Wick

How far damp spreads through the fibre ahead of the water - and it does not spread empty, it carries what is dissolved in it. THIS is feathering, and it is the transport that makes ink bleed on thirsty paper where there is no film left at all.

Default:
1
Range:
0 to 3
Dry Time (Drytime) Float op('ink_bleed').par.Drytime

Seconds for a full film to evaporate. Real seconds, so drying looks identical at 30, 60 or 120 frames per second.

Default:
6
Range:
0.15 to 90
Humidity (Humidity) Float op('ink_bleed').par.Humidity

A soaked sheet dries more slowly than a nearly dry one. Zero removes the coupling.

Default:
0.35
Range:
0 to 1
Edge Pinning (Pinning) Float op('ink_bleed').par.Pinning

How hard the surface's tooth holds a wet edge in place. High pinning gives a hard-stopping mark; zero lets it creep out everywhere.

Default:
0.7
Range:
0 to 2
Tooth Steering (Valley) Float op('ink_bleed').par.Valley

How much the surface steers water into its own valleys. This is where granulation comes from.

Default:
0.45
Range:
0 to 1
Board Tilt (Tilt) Float op('ink_bleed').par.Tilt

Tips the board so gravity joins the flow.

Default:
0
Range:
0 to 1
Tilt Direction (Tiltangle) Float op('ink_bleed').par.Tiltangle

Degrees. 90 runs the wash down the sheet.

Default:
90
Range:
-180 to 180
Field Flow (Fieldflow) Float op('ink_bleed').par.Fieldflow

Millimetres per second the field input drags the wash. Unconnected or black is still.

Default:
0
Range:
0 to 40
Mask Water (Maskgain) Float op('ink_bleed').par.Maskgain

How much the mask input pre-wets the surface. Black changes nothing.

Default:
1
Range:
0 to 3
Resist (Resistgain) Float op('ink_bleed').par.Resistgain

How strongly the resist input works as masking fluid. Black changes nothing.

Default:
1
Range:
0 to 2

Pigment

Palette (Palette) Menu op('ink_bleed').par.Palette

Classic: Ultramarine / Quinacridone Rose / New Gamboge / Burnt Sienna, granulating and traditional. Modern: Phthalo / Quinacridone Magenta / Hansa Yellow / Payne's Grey, high chroma, staining, hard to lift - the most separated bleed halos come from this one. Earth: Cerulean / Venetian Red / Yellow Ochre / Raw Umber, chalky and heavily granulating. Body: Cobalt / Cadmium Red / Cadmium Yellow / Ivory Black, opaque - they cover instead of glazing.

Default:
classic
Options:
classic, modern, earth, body
Neutral From Earth (Neutral) Float op('ink_bleed').par.Neutral

How much of the grey component is mixed from the palette's fourth pigment instead of the chromatic three. It changes how the darks granulate, because it changes which pigment is in them. Body behaviour uses that fourth slot for white, so this does nothing there.

Default:
0.4
Range:
0 to 1
Separation (Separation) Float op('ink_bleed').par.Separation

How differently the four pigments travel. Each one settles and stains at its own rate, so a spreading halo sorts itself into its components as it goes - that is chromatography, and it is why black writing gets a magenta fringe. At 0 all four travel together and the halo is simply a lighter version of the ink you laid. Above 1 they separate further than any real paint does.

Default:
1
Range:
0 to 3
Settling (Settle) Float op('ink_bleed').par.Settle

How fast pigment drops out of suspension. Heavy pigments settle first, which is why the palette matters.

Default:
1
Range:
0 to 3
Granulation (Granulation) Float op('ink_bleed').par.Granulation

How strongly settled pigment gathers in the surface's valleys. It applies to pigment sitting ON the surface, not to what has soaked into the fibre, and it fades out as the tooth fills up - a saturated passage has no valleys left to granulate into.

Default:
1
Range:
0 to 2
Staining (Staining) Float op('ink_bleed').par.Staining

Scales each pigment's own tendency to sink into the fibre and stay there.

Default:
1
Range:
0 to 2
Lifting (Lift) Float op('ink_bleed').par.Lift

How readily flowing water picks pigment back up. This is what makes backruns and tidelines, and it is what keeps a continuously worked sheet from silting up. Turn it down for ink that stays where it landed.

Default:
0.6
Range:
0 to 3
Binding (Bind) Float op('ink_bleed').par.Bind

How fast a dying film locks its pigment down for good.

Default:
1
Range:
0 to 3
Light Fastness (Fade) Float op('ink_bleed').par.Fade

How fast light bleaches what is already bound into the sheet, at each pigment's own rate - fugitive yellows go first, phthalos and cadmiums barely at all. 0 is archival and the sheet keeps everything forever. Turn it up and a sheet being printed into continuously reaches a standing state instead of silting to black, which is what lets this run for hours.

Default:
0
Range:
0 to 3
Ink Capacity (Capacity) Float op('ink_bleed').par.Capacity

How much material one sheet can hold before it will take no more. The mass tone is reached long before this.

Default:
22
Range:
3 to 60

Look

Tap (Tap) Menu op('ink_bleed').par.Tap

The sheet, or a look inside it at that point in the chain.

Default:
paint
Options:
paint, water, damp, pigment, surface, flow
Wet Gloss (Gloss) Float op('ink_bleed').par.Gloss

Sheen off the standing water. It shows where the sheet is still wet.

Default:
0.55
Range:
0 to 2
Wet Darkening (Wetdark) Float op('ink_bleed').par.Wetdark

A wash always dries lighter. This is how much darker it looks while the water is still in it.

Default:
0.6
Range:
0 to 1
Surface Relief (Relief) Float op('ink_bleed').par.Relief

Raking light across the surface's tooth.

Default:
0.6
Range:
0 to 1.5
Cockle (Cockle) Float op('ink_bleed').par.Cockle

Unstretched paper buckles where it has been wet, and stays buckled. Heavy paper cockles less.

Default:
0.35
Range:
0 to 1.5
Fibre Wander (Fibre) Float op('ink_bleed').par.Fibre

How much a wet edge follows individual fibres. This is the ragged edge, evaluated at output resolution so it stays crisp above the simulation grid.

Default:
0.6
Range:
0 to 1.5
Light (Lightangle) Float op('ink_bleed').par.Lightangle

Direction of the raking light, degrees.

Default:
135
Range:
0 to 360
Exposure (Lighting) Float op('ink_bleed').par.Lighting

How brightly the sheet is lit.

Default:
1
Range:
0.3 to 2