{
 "$schema": "../../schema.json",
 "schema": "fundus/1",
 "id": "ascii-dither-pixel-stil",
 "name": "ASCII-, Dither- und Pixel-Stil (Render und Hover)",
 "name_en": "ASCII / dithering post-processing render style / ASCII / glyph field hover / Pixel grid hover / pixelate / dither hover",
 "kurz": "Ein 3D-Knoten läuft durch einen eigenen Shader-Pass und erscheint als ASCII mit CRT-Look, als Bayer-Dither in Markenfarben oder als Pixelraster; unter dem Zeiger scheint in 5vw-Kacheln das Original durch.",
 "kategorie": "3D & WebGL",
 "kategorie_slug": "3d-webgl",
 "kategorie_nr": 11,
 "bau_chat": "C5",
 "prioritaet": "A",
 "trendstatus": "aufsteigend",
 "belegstatus": "belegt",
 "website_belege": 3,
 "stimmung": [
  "präzise",
  "verspielt",
  "laut",
  "experimentell"
 ],
 "stimmung_roh": [
  "retro",
  "technisch",
  "nerdig",
  "brutal",
  "digital",
  "verspielt"
 ],
 "technik": [
  "three",
  "webgl-shader",
  "postprocessing",
  "canvas",
  "css",
  "vanilla-js"
 ],
 "technik_gruppen": [
  "css",
  "js",
  "webgl",
  "canvas"
 ],
 "leistungskosten": "mittel",
 "steckbrief": {
  "beschreibung": "Eine 3D-Szene, ein Video oder ein Bild wird zuerst normal in ein Render-Target gerendert. Ein Nachbearbeitungs-Pass teilt das Bild dann in Zellen und übersetzt jede Zelle in eine grobe Form: ASCII-Zeichen (Zellen 8 bis 16 px), Dither-Punkte (1 bis 4 px) oder Pixelblöcke. Beim Dithering wird die Helligkeit jedes Pixels mit einer Bayer-Matrix (4×4 oder 8×8) verglichen. Ergebnis ist 1-Bit oder eine kleine Palette. Varianten sind Floyd-Steinberg (vorberechnet) und Blue Noise. Beim ASCII-Stil bestimmt die Helligkeit der Zelle das Zeichen aus einem Glyphen-Atlas. Shape-aware ASCII wählt das Zeichen zusätzlich nach der Kantenrichtung in der Zelle. Die Maus verändert Zellgröße oder Schwelle oder lässt das Original durchscheinen. Ein CRT-Zusatz bringt Scanlines, Wölbung und Phosphor-Glühen.",
  "warum_es_wirkt": "Hochwertiges 3D trifft auf Retro-Computer-Ästhetik. Der Stil reduziert Details auf eine starke grafische Handschrift und kaschiert einfache Modelle. Er wirkt technisch und handgemacht zugleich und verbindet das Terminal von früher mit heutiger KI- und Daten-Ästhetik. Retro-Digitales (Dithering, 8-Bit, Terminal) ist 2025/26 ein wachsendes Motiv, etwa in Codrops-Experimenten.",
  "wann_einsetzen": "Tech- und KI-Marken mit Haltung, Dev-Tools, Creative-Coding-Studios, Musik, Gaming, Entwickler-Portfolios mit Nerd-Charme. Gut als Hero-Hintergrund, für 404-Seiten und als Hover-Zustand von Projektbildern.",
  "wann_nicht": "Wenn ein Produkt fotorealistisch gezeigt werden muss. Bei warmen, klassischen oder organischen Marken. Hinter Fließtext. Auf kleinen Flächen, auf denen Zeichen unlesbar werden. Bei zu feinen Zellen auf Mobilgeräten (Flimmern, Moiré) und bei Rastern aus Hunderten DOM-Elementen (Leistung). Video-Variante: nicht für Filme, deren Inhalt man erkennen muss (Produktdemo, Erklärvideo), und nie mit Ton im Autoplay.",
  "varianten": [
   "Bayer-Dither 1-Bit",
   "Dither mit Markenpalette",
   "ASCII nach Helligkeit",
   "Shape-aware ASCII: Zeichen nach Kantenrichtung, z. B. ein Logo als ziehbarer 3D-Körper (Codrops 09/2026)",
   "CRT- und Monitor-Look mit Scanlines, Vignette, Wölbung und Aberration (Midjourney)",
   "Dither im 3D-Raum: Wolken mit Bayer-Dither in 3 px Zellen (Good Growth)",
   "Zeichenfeld unter Spotlight-Maske, per WebGL mit Glyphen-Atlas (Codrops AnimatedCodeBackground)",
   "Canvas-ASCII eines Videos mit Cursor-Verwirbelung",
   "Pixel-Spur: 5vw-Kacheln leuchten unter dem Zeiger auf und verschwinden nach 300 ms (Olivier Larose)",
   "Bild pixelt beim Laden oder Hover in Stufen scharf (Codrops ImagePixelLoading)",
   "Pixel-Glitch mit Clip-Path-Streifen und image-rendering: pixelated (Codrops GlitchPerspective)",
   "Raster-Kollision: Kacheln reagieren auf die Nähe des Zeigers (Motion)"
  ],
  "umsetzung": "Szene in ein WebGLRenderTarget rendern, dann ein Vollbild-Quad mit eigenem Shader zeichnen (oder einen eigenen Effekt in EffectComposer bzw. pmndrs postprocessing). Zellen über gl_FragCoord an Device-Pixeln ausrichten, sonst flimmert es beim Scrollen. Bei 3D den Dither im Screen-Space stabil halten. Die Bayer-Matrix steht als Konstante oder Formel im Shader.\n\nASCII: Zeichen nach Tinte sortiert in eine Atlas-Textur zeichnen. Pro Zelle die Szene einmal in der Zellmitte abtasten, Index = floor(Helligkeit · n). Weil jede Zelle nur einen Messpunkt braucht, reicht ein Render-Target in halber Auflösung. Die Cursor-Distanz kann Index, Farbe oder die Mischung mit dem Original steuern.\n\nPixel-Spur: per Canvas oder kleiner Datentextur statt DOM. Ein Float32Array hält einen Alpha-Wert je Kachel. pointermove setzt die Kachel unter dem Zeiger auf 1; die Strecke dazwischen abtasten, damit bei schnellen Bewegungen keine Lücken bleiben. Pro Frame linear um dt/300 ms abbauen.\n\nBild-Pixelation: Bild in ein kleines Offscreen-Canvas (Breite ÷ Zellgröße) zeichnen und mit imageSmoothingEnabled = false hochskalieren. Die Zellgröße in Stufen ändern, z. B. 24 → 12 → 6 → 3 → 1. Fallstrick: Ein DOM-Raster mit Hunderten Elementen und mouseenter ist einfach, aber teuer. DPR berücksichtigen.",
  "mobil": "Größere Zellen. Ohne Hover leuchten zufällige Kacheln als ruhige Hintergrundbewegung auf, beim Wischen folgt die Spur dem Finger. Bei schwacher GPU die Bildrate drosseln oder ein Standbild zeigen. Projektbilder pixeln beim Hereinscrollen scharf.",
  "reduzierte_bewegung": "Szene einfrieren, der Stil bleibt als Standbild. Keine Spur, keine Stufen beim Wechsel, keine CRT-Einschaltanimation. Bilder sofort scharf.",
  "barrierefreiheit": "Inhalte nie nur als ASCII- oder Pixelbild zeigen: Texte bleiben echtes HTML, die Canvas-Fläche ist aria-hidden. Flimmern vermeiden (Photosensitivität), besonders bei feinen Zellen und Glitch-Effekten. Kontrast von Text über aktiven Kacheln prüfen, denn mix-blend-mode: difference kann unlesbare Mischfarben erzeugen."
 },
 "messwerte": {
  "easing": "Stufen (steps) bzw. lineares Abklingen; easeOutQuad (CRT-Wölbung, Midjourney); Lerp .02 (Good Growth)",
  "dauer_ms": "300 Abklingzeit pro Kachel (Larose); Wölbung 3000; Aberration klingt mit τ 750 ab (Midjourney)",
  "stagger_ms": "",
  "distanz": "Kachelgröße 5vw (20 Spalten); Dither-Zellen 3px (Good Growth)",
  "sonstiges": "Midjourney: Scanlines 0.4, Vignette 0.7, Wölbung 0.1. Good Growth: Bayer 2×2 zweistufig, Schwelle 0.45, alpha .12",
  "herkunft": "beobachtet",
  "quelle": "https://blog.olivierlarose.com/tutorials/pixel-cursor-trailing; https://www.midjourney.com/public/out/clientSideEntry-h0zd935e.js",
  "aus_eintrag": [
   "pixel-raster-hover"
  ]
 },
 "kurve": {
  "bezier": [
   0.5,
   1,
   0.89,
   1
  ],
  "css": "cubic-bezier(0.5, 1, 0.89, 1)",
  "name": "easeoutquad",
  "dauer_ms": 300
 },
 "gesehen_bei": [
  {
   "seite": "Codrops – Shape-Aware ASCII Renderer in Three.js",
   "url": "https://tympanus.net/codrops/2026/09/04/beyond-the-luminance-ramp-a-shape-aware-ascii-renderer-in-three-js/",
   "auszeichnung": "",
   "beobachtung": "Laut Feed: Logo als ziehbarer 3D-Körper, in ASCII gerendert, Zeichen pro Zelle auf der GPU gewählt.",
   "art": "artikel"
  },
  {
   "seite": "Codrops – Efecto: ASCII and Dithering with WebGL Shaders",
   "url": "https://tympanus.net/codrops/2026/01/04/efecto-building-real-time-ascii-and-dithering-effects-with-webgl-shaders/",
   "auszeichnung": "",
   "beobachtung": "Laut Feed: Retro-Bildverarbeitung und Vintage-Monitor-Looks live per WebGL-Shader.",
   "art": "artikel"
  },
  {
   "seite": "Codrops AnimatedCodeBackground (Repo)",
   "url": "https://github.com/codrops/AnimatedCodeBackground",
   "auszeichnung": "",
   "beobachtung": "Neuere Varianten (index2+) zeichnen das Zeichenfeld per WebGL mit glyphAtlas.js statt per CSS-Maske.",
   "art": "demo"
  },
  {
   "seite": "Olivier Larose: Pixel Cursor Trailing",
   "url": "https://blog.olivierlarose.com/tutorials/pixel-cursor-trailing",
   "auszeichnung": "",
   "beobachtung": "20 Spalten, Blöcke 5vw × 5vw, Block wird bei mouseenter schwarz und nach 0.3 s wieder transparent; Text mit mix-blend-mode: difference.",
   "art": "artikel"
  },
  {
   "seite": "Codrops ImagePixelLoading (Repo)",
   "url": "https://github.com/codrops/ImagePixelLoading",
   "auszeichnung": "",
   "beobachtung": "Nachbau eines pixeligen On-Scroll-Bildladeeffekts.",
   "art": "demo"
  },
  {
   "seite": "Codrops GlitchPerspective (Repo)",
   "url": "https://github.com/codrops/GlitchPerspective",
   "auszeichnung": "",
   "beobachtung": "Pixelbild mit Glitch-Animation (buōy) per clip-path-Keyframes, flash steps(1,end).",
   "art": "demo"
  },
  {
   "seite": "Motion Examples: Pointer collision detection",
   "url": "https://motion.dev/examples/react-collision-hover-grid",
   "auszeichnung": "",
   "beobachtung": "Hover-Raster mit Kollisionserkennung.",
   "art": "demo"
  },
  {
   "seite": "Codrops: Animating 160,000 cubes to visualize dithering (04/2026)",
   "url": "https://tympanus.net/codrops/2026/04/01/animating-160000-cubes-in-three-js-to-visualize-dithering/",
   "auszeichnung": "",
   "beobachtung": "Im Telegram-Kanal gelistet – Beleg für das Dithering-Interesse 2026 (Artikel nicht gelesen).",
   "art": "artikel"
  },
  {
   "seite": "Egor Shesternin – Portfolio",
   "url": "https://www.egorbuilds.com/",
   "auszeichnung": "",
   "beobachtung": "Live geprüft 31.10.2026 (HTML/Bundle per curl abgerufen): Startseite mit React-Three-Fiber-Szene und eigenem Postprocessing-Effekt „AsciiEffect“ (Uniforms cellSize, invert, colorMode, asciiStyle, glyphAtlas/glyphTiles, volumeShading, tintColor, mousePos).",
   "art": "website"
  },
  {
   "seite": "Midjourney",
   "url": "https://www.midjourney.com/",
   "auszeichnung": "",
   "beobachtung": "Live geprüft 31.10.2026 (HTML/Bundle per curl abgerufen): clientSideEntry-h0zd935e.js: Zeichenfeld per WebGL mit Glyph-Atlas (uGlyphAtlas, instanzierte Quads aBounds/aGlyphUv/aColor); Zeilenhöhe = 1.3 × (Höhe ÷ Zeilenzahl); das Feld wird als Wirbel verdreht (Winkel = Zeit·0.1 ÷ max(0.1, Radius)); im Zentrum ein ASCII-Logo (logoLines/logoMask), dessen Zeichen per Zeichencode-Interpolation einmorphen. Nachbearbeitung im Stil eines CRT: Wölbung 0.1 über 3 s easeOutQuad, chromatische Aberration .005·exp(−t/.75), Scanlines Deckkraft 0.4, Vignette 0.7, Tonemapping ×2.2.",
   "art": "website"
  },
  {
   "seite": "Good Growth",
   "url": "https://goodgrowth.com/",
   "auszeichnung": "",
   "beobachtung": "Live geprüft 31.10.2026 (HTML/Bundle per curl abgerufen): index-CqpgIB8L.js: Wolkenschicht aus 900 Sprites mit Bayer-Dithering im Fragment-Shader (bayer2, 3px große Rasterzellen, Schwelle × 0.45, verworfene Pixel statt Transparenz, Farbe mit alpha .12), Nebel smoothstep 100–2600, Mitte per Maske 0.28–0.85 freigestellt; Kamera fliegt mit 42 Einheiten/s, Maus-Parallaxe 40/20 mit Lerp .02.",
   "art": "website"
  }
 ],
 "tutorials": [
  {
   "titel": "Beyond the Luminance Ramp: A Shape-Aware ASCII Renderer in Three.js",
   "url": "https://tympanus.net/codrops/2026/09/04/beyond-the-luminance-ramp-a-shape-aware-ascii-renderer-in-three-js/"
  },
  {
   "titel": "Efecto: Building Real-Time ASCII and Dithering Effects with WebGL Shaders",
   "url": "https://tympanus.net/codrops/2026/01/04/efecto-building-real-time-ascii-and-dithering-effects-with-webgl-shaders/"
  },
  {
   "titel": "Olivier Larose: Pixel Cursor Trailing",
   "url": "https://blog.olivierlarose.com/tutorials/pixel-cursor-trailing"
  },
  {
   "titel": "Olivier Larose: Image Pixel Loading",
   "url": "https://blog.olivierlarose.com/tutorials/image-pixel-loading"
  },
  {
   "titel": "Paper Shaders – Dithering / Image dithering",
   "url": "https://shaders.paper.design/"
  },
  {
   "titel": "Codrops: Shape-aware interactive ASCII (09/2026)",
   "url": "https://tympanus.net/codrops/?p=120018"
  }
 ],
 "kombinierbar_mit": [
  "halbton-raster",
  "shader-uebergang-dissolve",
  "nachbearbeitung-filmlook",
  "interaktives-3d-hero",
  "scramble-decode",
  "karten-spotlight-glow",
  "bild-trail-cursor"
 ],
 "urls": {
  "detail": "https://cecodesign.de/lab/fundus/3d-webgl/ascii-dither-pixel-stil/",
  "meta": "https://cecodesign.de/lab/fundus/3d-webgl/ascii-dither-pixel-stil/meta.json",
  "demo": "https://cecodesign.de/lab/fundus/3d-webgl/ascii-dither-pixel-stil/demo"
 },
 "herkunft": {
  "quelldateien": [
   "material3d.json",
   "hover.json",
   "patch-belege-2.json",
   "r3-belege-a.json"
  ],
  "pruefnotizen": [
   "patch-belege-2.json: 1 Produktionsbeleg; Ziel ≥2 nicht erreicht (Codrops-Fallstudien als Fundort waren am 31.10. per Cloudflare gesperrt).",
   "r3-belege-a.json (Runde 3, 31.10.2026): Midjourney deckt ASCII-Render plus CRT-Look ab, Good Growth das Bayer-Dithering im 3D-Kontext. Treffer bei Lusion/Choo Choo World (u_ditherSeed) sind nur Anti-Banding-Rauschen und zählen nicht."
  ],
  "zusammengelegt_aus": [
   "ascii-dither-render",
   "ascii-glyphen-hover",
   "pixel-raster-hover"
  ],
  "querverweis_kategorien": [
   "Hover"
  ]
 },
 "bau": {
  "status": "fertig",
  "kurz": "Ein 3D-Knoten läuft durch einen eigenen Shader-Pass und erscheint als ASCII mit CRT-Look, als Bayer-Dither in Markenfarben oder als Pixelraster; unter dem Zeiger scheint in 5vw-Kacheln das Original durch.",
  "demo": true,
  "abhaengigkeiten": [
   "three@0.186.0"
  ],
  "werte": {
   "pipeline": "Szene in WebGLRenderTarget (halbe Auflösung), dann Vollbild-Quad mit ShaderMaterial; Zellen über gl_FragCoord / DPR in CSS-Pixeln",
   "ascii": {
    "zelle_px": "10 × 16 (mobil 12 × 19)",
    "glyphen": " .:-=+*#%@ (10, nach gemessener Tinte sortiert)",
    "atlas": "40 × 64 px je Glyphe, Geist Mono 500 50px",
    "helligkeit": "smoothstep(0.03, 0.85, lum)",
    "farbe": "Tinte → Signal → Papier, smoothstep(0.45, 0.9); Glyphe × (0.4 + 0.6 · lum)"
   },
   "crt": {
    "scanlines": 0.4,
    "scanline_periode_px": 3,
    "vignette": 0.7,
    "woelbung": 0.1,
    "woelbung_dauer_ms": 3000,
    "woelbung_easing": "easeOutQuad 1 − (1 − t)²",
    "aberration": "0.005 · e^(−t / 0.75 s)"
   },
   "dither": {
    "matrix": "Bayer 4 × 4",
    "zelle_px": "3 (mobil 4)",
    "palette": [
     "#0c0b0a",
     "#3a1608",
     "#ff5b24",
     "#efe9dc"
    ],
    "helligkeit": "lum × 1.15"
   },
   "pixel": {
    "zelle_px": "12 (mobil 16)",
    "rampe": [
     "#0c0b0a",
     "#3a1608",
     "#8a2a0c",
     "#ff5b24",
     "#f2b48c",
     "#efe9dc"
    ],
    "fuge_px": 1,
    "dither": "keiner"
   },
   "spur": {
    "kachel": "5vw = Breite ÷ 20 (mobil ÷ 8)",
    "abklingen_ms": 300,
    "easing": "linear (alpha −= dt / 300)",
    "verhalten": "Kachel unter dem Zeiger bleibt an; Strecke wird in 0.4-Kachel-Schritten abgetastet",
    "rand": "1 px Signal × 0.85 · alpha",
    "inhalt": "Original-Render scheint durch"
   },
   "moduswechsel": {
    "stufen": "Zellgröße × 4 → × 2 → × 1",
    "stufe_ms": 150,
    "easing": "steps"
   },
   "parallaxe": {
    "lerp": 0.02,
    "drehung_rad": "x 0.35 · y, y 0.5 · x"
   },
   "rotation_rad_s": {
    "x": 0.22,
    "y": 0.31,
    "ring_z": 0.4
   },
   "projektbilder": {
    "stufen_px": [
     24,
     12,
     6,
     3,
     1
    ],
    "stufe_ms": 60,
    "gesamt_ms": 300,
    "verfahren": "Offscreen-Canvas Breite ÷ Zelle, imageSmoothingEnabled = false"
   },
   "ui": {
    "dauer_ms": 150,
    "easing": "cubic-bezier(0.5, 1, 0.89, 1)"
   },
   "vorfuehrung": {
    "modus_ms": 4200,
    "bahn": "Lissajous sin(1.3 t) × sin(2.1 t + 0.6) um das Objekt"
   },
   "drosselung": "Bildzeit im Mittel über 45 ms → 70 ms Pause je Bild"
  },
  "ausloeser": "hover",
  "touch": "Kein Hover: zufällige Kacheln leuchten alle 260 ms auf und zeigen das Original; beim Wischen über die Bühne folgt die Spur dem Finger (touchmove). Größere Zellen (ASCII 12 × 19, Dither 4, Pixel 16 px, 8 Kachelspalten). Projektbilder pixeln beim Hereinscrollen (55 % sichtbar) einmal scharf. Video-Variante: gleiches Verhalten, das Video läuft stumm und inline (playsinline).",
  "reduziert": "Szene steht (keine Rotation, keine Parallaxe), keine Spur, Moduswechsel ohne Stufen, CRT-Wölbung fest auf 0.1 ohne Aberration. Projektbilder sofort scharf. Gerendert wird nur bei Änderung. Video-Variante: Video spielt nicht, gezeigt wird das Bild bei 1,2 s im gewählten Raster.",
  "korrekturen": {
   "beschreibung": "Eine 3D-Szene, ein Video oder ein Bild wird zuerst normal in ein Render-Target gerendert. Ein Nachbearbeitungs-Pass teilt das Bild dann in Zellen und übersetzt jede Zelle in eine grobe Form: ASCII-Zeichen (Zellen 8 bis 16 px), Dither-Punkte (1 bis 4 px) oder Pixelblöcke. Beim Dithering wird die Helligkeit jedes Pixels mit einer Bayer-Matrix (4×4 oder 8×8) verglichen. Ergebnis ist 1-Bit oder eine kleine Palette. Varianten sind Floyd-Steinberg (vorberechnet) und Blue Noise. Beim ASCII-Stil bestimmt die Helligkeit der Zelle das Zeichen aus einem Glyphen-Atlas. Shape-aware ASCII wählt das Zeichen zusätzlich nach der Kantenrichtung in der Zelle. Die Maus verändert Zellgröße oder Schwelle oder lässt das Original durchscheinen. Ein CRT-Zusatz bringt Scanlines, Wölbung und Phosphor-Glühen.",
   "warum_es_wirkt": "Hochwertiges 3D trifft auf Retro-Computer-Ästhetik. Der Stil reduziert Details auf eine starke grafische Handschrift und kaschiert einfache Modelle. Er wirkt technisch und handgemacht zugleich und verbindet das Terminal von früher mit heutiger KI- und Daten-Ästhetik. Retro-Digitales (Dithering, 8-Bit, Terminal) ist 2025/26 ein wachsendes Motiv, etwa in Codrops-Experimenten.",
   "wann_einsetzen": "Tech- und KI-Marken mit Haltung, Dev-Tools, Creative-Coding-Studios, Musik, Gaming, Entwickler-Portfolios mit Nerd-Charme. Gut als Hero-Hintergrund, für 404-Seiten und als Hover-Zustand von Projektbildern.",
   "wann_nicht": "Wenn ein Produkt fotorealistisch gezeigt werden muss. Bei warmen, klassischen oder organischen Marken. Hinter Fließtext. Auf kleinen Flächen, auf denen Zeichen unlesbar werden. Bei zu feinen Zellen auf Mobilgeräten (Flimmern, Moiré) und bei Rastern aus Hunderten DOM-Elementen (Leistung). Video-Variante: nicht für Filme, deren Inhalt man erkennen muss (Produktdemo, Erklärvideo), und nie mit Ton im Autoplay.",
   "varianten": [
    "Bayer-Dither 1-Bit",
    "Dither mit Markenpalette",
    "ASCII nach Helligkeit",
    "Shape-aware ASCII: Zeichen nach Kantenrichtung, z. B. ein Logo als ziehbarer 3D-Körper (Codrops 09/2026)",
    "CRT- und Monitor-Look mit Scanlines, Vignette, Wölbung und Aberration (Midjourney)",
    "Dither im 3D-Raum: Wolken mit Bayer-Dither in 3 px Zellen (Good Growth)",
    "Zeichenfeld unter Spotlight-Maske, per WebGL mit Glyphen-Atlas (Codrops AnimatedCodeBackground)",
    "Canvas-ASCII eines Videos mit Cursor-Verwirbelung",
    "Pixel-Spur: 5vw-Kacheln leuchten unter dem Zeiger auf und verschwinden nach 300 ms (Olivier Larose)",
    "Bild pixelt beim Laden oder Hover in Stufen scharf (Codrops ImagePixelLoading)",
    "Pixel-Glitch mit Clip-Path-Streifen und image-rendering: pixelated (Codrops GlitchPerspective)",
    "Raster-Kollision: Kacheln reagieren auf die Nähe des Zeigers (Motion)"
   ],
   "umsetzung": "Szene in ein WebGLRenderTarget rendern, dann ein Vollbild-Quad mit eigenem Shader zeichnen (oder einen eigenen Effekt in EffectComposer bzw. pmndrs postprocessing). Zellen über gl_FragCoord an Device-Pixeln ausrichten, sonst flimmert es beim Scrollen. Bei 3D den Dither im Screen-Space stabil halten. Die Bayer-Matrix steht als Konstante oder Formel im Shader.\n\nASCII: Zeichen nach Tinte sortiert in eine Atlas-Textur zeichnen. Pro Zelle die Szene einmal in der Zellmitte abtasten, Index = floor(Helligkeit · n). Weil jede Zelle nur einen Messpunkt braucht, reicht ein Render-Target in halber Auflösung. Die Cursor-Distanz kann Index, Farbe oder die Mischung mit dem Original steuern.\n\nPixel-Spur: per Canvas oder kleiner Datentextur statt DOM. Ein Float32Array hält einen Alpha-Wert je Kachel. pointermove setzt die Kachel unter dem Zeiger auf 1; die Strecke dazwischen abtasten, damit bei schnellen Bewegungen keine Lücken bleiben. Pro Frame linear um dt/300 ms abbauen.\n\nBild-Pixelation: Bild in ein kleines Offscreen-Canvas (Breite ÷ Zellgröße) zeichnen und mit imageSmoothingEnabled = false hochskalieren. Die Zellgröße in Stufen ändern, z. B. 24 → 12 → 6 → 3 → 1. Fallstrick: Ein DOM-Raster mit Hunderten Elementen und mouseenter ist einfach, aber teuer. DPR berücksichtigen.",
   "mobil": "Größere Zellen. Ohne Hover leuchten zufällige Kacheln als ruhige Hintergrundbewegung auf, beim Wischen folgt die Spur dem Finger. Bei schwacher GPU die Bildrate drosseln oder ein Standbild zeigen. Projektbilder pixeln beim Hereinscrollen scharf.",
   "reduzierte_bewegung": "Szene einfrieren, der Stil bleibt als Standbild. Keine Spur, keine Stufen beim Wechsel, keine CRT-Einschaltanimation. Bilder sofort scharf.",
   "barrierefreiheit": "Inhalte nie nur als ASCII- oder Pixelbild zeigen: Texte bleiben echtes HTML, die Canvas-Fläche ist aria-hidden. Flimmern vermeiden (Photosensitivität), besonders bei feinen Zellen und Glitch-Effekten. Kontrast von Text über aktiven Kacheln prüfen, denn mix-blend-mode: difference kann unlesbare Mischfarben erzeugen."
  },
  "geprueft": "31.10.2026",
  "notiz": "Hero eines erfundenen Creative-Coding-Studios: Three.js-Torusknoten mit Ring, eigener Post-Pass mit drei Modi (ASCII mit CRT nach Midjourney-Werten, Bayer-Dither 3 px nach Good Growth, Pixel mit 6-Ton-Rampe). Zeiger-Spur nach Larose (20 Spalten, 300 ms) als Datentextur: dort scheint der Original-Render durch. Moduswechsel in Stufen 4→2→1. Darunter Projektkarten, die beim Hover in 5 Stufen à 60 ms scharf pixeln. Ohne WebGL: CSS-Raster mit Glühen. Drosselt die Bildrate bei Software-Rendering. Bilder 01.11.2026: eigene Bilder statt Portfolio. Korrektur 02.11.2026: Variante video (Prinzip Video Effects aus BUTTONS-SLIDERREV-RECHERCHE Q28, nichts übernommen): eigener Clip zitronen-tisch.mp4 als VideoTexture durch denselben Post-Pass, Headline „Film, Zeichen für Zeichen.“, Kontrastschicht, cover im Shader. Neu für beide Varianten: Pause-Knopf „Anhalten“ (WCAG 2.2.2) und Ruhe außerhalb des Viewports. Umschalter 3D-Szene | Video im Pult. Korrektur 02.11.2026 (Prüfung): In der Variante video überdeckte die Werte-Zeile am Desktop den Lauftext; Quellen-Zeile gekürzt (VideoTexture/Pause stehen in werte), Text sitzt bei Video auf bottom clamp(116px, 15vh, 160px).",
  "varianten": [
   {
    "id": "szene",
    "name": "3D-Szene im Raster",
    "knopf": "3D-Szene",
    "wann": "Creative-Coding-Studio, Label, Tech-Kultur: ein eigenes 3D-Objekt wird live zu ASCII, Dither oder Pixeln, unter dem Zeiger scheint das Original durch.",
    "werte": {
     "quelle": "Three.js-Torusknoten mit Ring, Render-Target in halber Auflösung"
    }
   },
   {
    "id": "video",
    "name": "Video als Zeichen in Echtzeit",
    "knopf": "Video",
    "wann": "Kampagne, Musik, Festival, Studio-Showreel: ein eigener kurzer Clip läuft stumm durch denselben Pass (ASCII, Dither, Pixel), unter dem Zeiger erscheint das Originalbild. Nicht, wenn man den Filminhalt erkennen muss.",
    "werte": {
     "quelle": "eigenes Video medien/zitronen-tisch.mp4, 1280 × 720, 25 fps, 4,9 s Schleife, muted, loop, playsinline, preload auto; im DOM, 2 × 2 px, opacity 0",
     "textur": "THREE.VideoTexture, LinearFilter, ohne Mipmaps, ohne Farbraum-Umrechnung; die 3D-Szene wird im Video-Modus nicht gerendert",
     "deckung": "object-fit: cover im Shader: (uv − 0.5) · uCover + uMitte; Querformat 1,25-fach näher (uCover · 0.8) und Bildmitte x 0.42, damit das Motiv rechts neben dem Text steht; Hochformat Mitte 0.5",
     "kontrast": "Kontrastschicht hinter dem Text: links rgba(12, 11, 10) .9 → .72 bei 34 % → 0 bei 62 %, unten .85 → 0 bei 26 %; Telefon von unten .94 → .8 bei 48 % → 0 bei 72 %",
     "ruhe": "Video und Bildschleife pausieren außerhalb des Viewports (IntersectionObserver), bei verstecktem Tab und über den Knopf „Anhalten“",
     "ohne_webgl": "Posterbild zitronen-tisch-poster.jpg mit 6-px-Schachbrett darüber",
     "pause": "„Anhalten“ oben rechts (button, aria-pressed, Name „Bewegung anhalten“), gleiche Pause wie FUNDUS_DEMO.pause; gilt auch für die 3D-Szene"
    }
   }
  ]
 }
}
