gzdoom-crosshatch.asm$E3C0 · peaks.bin

GZDoom Cross-Hatch Shader

A non-photorealistic post-process for GZDoom that turns scene brightness into pen-and-ink hatching, with optional Sobel outlines and every knob exposed as a CVar.

coverDoom gameplay rendered as black-and-white cross-hatching
Doom gameplay rendered as black-and-white cross-hatching
README.mdgzdoom-crosshatch/index.mdx

This is a configurable post-process NPR style for GZDoom. Scene luminance becomes hatch density, optional Sobel outlines add ink definition, and the whole look can be toggled at runtime through CVars.

Hatch density increasing in darker areas
Mid-to-dark density progression with optional outline emphasis.
Hatch, softness and grain combined
Combined hatch, softness, and grain controls tuned for readability.

Goal

Deliver a comic/etching visual treatment that is practical in actual gameplay: readable, adjustable, and easy to distribute as a single PK3.

The current scope prioritizes a robust screen-space implementation over deeper material-level integration. In v0-M3 the effect is intentionally post-process only. That keeps compatibility high on stock GZDoom hardware renderers and avoids the complexity of per-material world-space hatching.

Pipeline

  • GLDEFS registers hatch.fp as a post-process shader and binds CVar uniforms.
  • CVARINFO exposes runtime controls for hatch, breakup, tone, and outlines.
  • MAPINFO and ZSCRIPT.lmp register HatchHandler for integration.
  • shaders/PostProcess/hatch.fp computes the full NPR stylization pass.

Shader approach

  1. Sample InputTexture and compute luminance.
  2. Quantize darkness into configurable bands (hatch_bands).
  3. Build procedural hatch masks from stripe functions plus breakup layers: hatch_stipple, hatch_grain, and hatch_jitter.
  4. Increase dark-area density with adaptive scale (hatch_dark_density).
  5. Apply optional 3-tap smoothing (hatch_softness) to reduce shimmer.
  6. Composite ink with scene/base tone using hatch_strength, hatch_bw, and hatch_flat_tone.
  7. Optionally add Sobel outlines via outline_enable, outline_strength, and outline_threshold.

Limitations

  • Resolution-bound line quality. Hatch detail is pixel-space (gl_FragCoord), so low render resolutions collapse strokes and high resolutions can reveal aliasing unless retuned.
  • Motion shimmer and moiré. Repeated line frequencies can alias in camera motion; softness and breakup help but don’t fully remove temporal artifacts.
  • Screen-space drift. Patterns don’t lock to world geometry/UVs, so hatching can slide over surfaces during viewpoint changes.
  • Global coverage. The effect applies scene-wide, including HUD and sprites, which requires careful strength tuning for readability.
  • NPR is subjective. There’s no single correct stylization across all maps and lighting conditions; scene-specific CVar adjustments remain part of production use.