Skip to main content
CMYK halftone printing effect applied to images with customizable dot patterns and ink colors for each channel (Cyan, Magenta, Yellow, Black). Simulates traditional four-color printing process.

Features

  • True CMYK color separation
  • Customizable ink colors per channel
  • Multiple dot styles (dots, ink, sharp)
  • Individual channel gain and flood controls
  • Grid noise and grain effects
  • Vintage printing simulation

Basic Usage

import { HalftoneCmyk } from '@paper-design/shaders-react';

function App() {
  return (
    <HalftoneCmyk
      image="/path/to/image.jpg"
      type="ink"
      size={0.2}
      contrast={1}
      softness={1}
      colorBack="#fbfaf5"
      colorC="#00b4ff"
      colorM="#fc519f"
      colorY="#ffd800"
      colorK="#231f20"
      gridNoise={0.2}
      floodC={0.15}
      gainC={0.3}
      gainY={0.2}
    />
  );
}

Parameters

Visual Parameters

image
string | HTMLImageElement
default:"''"
Optional source image to convert to CMYK halftone
type
'dots' | 'ink' | 'sharp'
default:"'ink'"
Dot rendering style:
  • dots: Separate dots with clear boundaries
  • ink: Blended dots simulating ink spread
  • sharp: Sharp dots with per-pixel color sampling
size
number
default:"0.2"
Halftone cell size (0 = large cells, 1 = small cells)
contrast
number
default:"1"
Image contrast adjustment before halftone conversion
softness
number
default:"1"
Edge softness of dots (0 = hard edge, 1 = smooth gradient)
colorBack
string
default:"'#fbfaf5'"
Background (paper) color in hex, rgb, or rgba format
colorC
string
default:"'#00b4ff'"
Cyan ink color in hex, rgb, or rgba format
colorM
string
default:"'#fc519f'"
Magenta ink color in hex, rgb, or rgba format
colorY
string
default:"'#ffd800'"
Yellow ink color in hex, rgb, or rgba format
colorK
string
default:"'#231f20'"
Black (key) ink color in hex, rgb, or rgba format
gridNoise
number
default:"0.2"
Smooth noise applied to both dot positions and color sampling
grainSize
number
default:"0.5"
Size of grain overlay texture
grainMixer
number
default:"0"
Strength of grain affecting dot size
grainOverlay
number
default:"0"
Strength of grain overlay on final output

Channel Controls

floodC
number
default:"0.15"
Flat cyan dot size adjustment applied uniformly
floodM
number
default:"0"
Flat magenta dot size adjustment applied uniformly
floodY
number
default:"0"
Flat yellow dot size adjustment applied uniformly
floodK
number
default:"0"
Flat black dot size adjustment applied uniformly
gainC
number
default:"0.3"
Proportional cyan dot size gain (enhances existing dots)
gainM
number
default:"0"
Proportional magenta dot size gain
gainY
number
default:"0.2"
Proportional yellow dot size gain
gainK
number
default:"0"
Proportional black dot size gain

Sizing Parameters

fit
'none' | 'contain' | 'cover'
default:"'cover'"
How to fit the shader into the canvas dimensions
scale
number
default:"1"
Overall zoom level of the graphics
rotation
number
default:"0"
Overall rotation angle in degrees
offsetX
number
default:"0"
Horizontal offset of the graphics center
offsetY
number
default:"0"
Vertical offset of the graphics center

Animation Parameters

speed
number
default:"0"
Animation speed multiplier (0 for static)
frame
number
default:"0"
Manual frame control for animation

Presets

The HalftoneCmyk shader comes with several built-in presets:
  • Default: Vibrant CMYK with cyan and yellow emphasis
  • Drops: High contrast with irregular dot placement
  • Newspaper: Grayscale newsprint effect
  • Vintage: Soft vintage colors with grain
import { HalftoneCmyk, halftoneCmykPresets } from '@paper-design/shaders-react';

function App() {
  return <HalftoneCmyk {...halftoneCmykPresets[0].params} image="/image.jpg" />;
}

Examples

Newspaper Print

<HalftoneCmyk
  image="/image.jpg"
  type="dots"
  size={0.01}
  contrast={2}
  softness={0.2}
  colorBack="#f2f1e8"
  colorC="#7a7a75"
  colorM="#7a7a75"
  colorY="#7a7a75"
  colorK="#231f20"
  gridNoise={0.6}
  floodK={0.1}
  gainC={-0.17}
  gainM={-0.45}
  gainY={-0.45}
  grainOverlay={0.2}
/>

Vintage Poster

<HalftoneCmyk
  image="/image.jpg"
  type="sharp"
  size={0.2}
  contrast={1.25}
  softness={0.4}
  colorBack="#fffaf0"
  colorC="#59afc5"
  colorM="#d8697c"
  colorY="#fad85c"
  colorK="#2d2824"
  gridNoise={0.45}
  floodC={0.15}
  gainC={0.3}
  gainY={0.2}
  grainMixer={0.15}
  grainOverlay={0.1}
/>

High Contrast Drops

<HalftoneCmyk
  image="/image.jpg"
  type="ink"
  size={0.88}
  contrast={1.15}
  softness={0}
  colorBack="#eeefd7"
  colorC="#00b2ff"
  colorM="#fc4f4f"
  colorY="#ffd900"
  colorK="#231f20"
  gridNoise={0.5}
  floodC={0.15}
  gainC={1.0}
  gainM={0.44}
  gainY={-1.0}
  grainMixer={0.05}
  grainOverlay={0.25}
/>

Technical Details

Shader Uniforms (Vanilla JS)

When using the vanilla JavaScript API:
import { HalftoneCmykTypes, getShaderNoiseTexture } from '@paper-design/shaders';

{
  u_type: HalftoneCmykTypes.ink, // or 1
  u_noiseTexture: getShaderNoiseTexture(), // Required!
  u_colorBack: [r, g, b, a],
  u_colorC: [r, g, b, a],
  u_colorM: [r, g, b, a],
  u_colorY: [r, g, b, a],
  u_colorK: [r, g, b, a],
  // ... other parameters
}

Dot Types

  • dots (0): Separate dots with clear boundaries
  • ink (1): Blended dots simulating ink spread
  • sharp (2): Sharp dots with direct pixel sampling

CMYK Separation

The shader automatically converts RGB images to CMYK using standard formulas:
  • Cyan: Absence of red
  • Magenta: Absence of green
  • Yellow: Absence of blue
  • Black (Key): Overall darkness
Each channel is rendered at a different rotation angle (15°, 75°, 0°, 45°) to prevent moiré patterns.

Channel Controls

Flood Parameters (-1 to 1):
  • Add or subtract a flat amount from all dots in a channel
  • Positive values make all dots bigger
  • Negative values make all dots smaller
  • Useful for overall color balance
Gain Parameters (-1 to 1):
  • Multiply existing dot sizes proportionally
  • Positive values enhance existing dots
  • Negative values reduce existing dots
  • Preserves relative differences between areas

Performance Notes

  • Static shader (no animation by default)
  • Requires noise texture (automatically handled in React)
  • ink and sharp types sample 9 cells per pixel
  • Performance scales with image resolution
  • Grid noise adds slight computational cost