Skip to content

Pixel Shader (Three.js)

A spinning crystal sphere rendered through Three.js’s EffectComposer with the RenderPixelatedPass addon — chunky retro pixels with antialiased edges. Ported from refs/three/examples/webgl_postprocessing_pixel.html.

PillarWhat it needs
@gjsify/webglMultiple framebuffers (WebGLRenderTarget), custom shaders compiled at runtime, OrbitControls
@gjsify/dom-elementsThe standard canvas/RAF/Resize trio
@gjsify/adwaita-webBrowser embed’s resolution-tier controls
Adwaita widgets (GJS)Adw.PreferencesGroup + Adw.SpinRow for pixel-size + render-resolution controls
gjsify showcase three-postprocessing-pixel

Opens a GTK4 window with an Adw.ToolbarView. Adjust pixel-size to crush the resolution into chunky cells; the RenderPixelatedPass writes into a low-res framebuffer then upscales with nearest-neighbor sampling for the retro look.

import { mount } from '@gjsify/example-dom-three-postprocessing-pixel/browser';
mount(document.getElementById('app')!);

Same scene logic. Browser-side resolution controls live in @gjsify/adwaita-web web components for visual parity with the GJS shell.

showcases/dom/three-postprocessing-pixel/

The shared three-demo.ts drives the scene + post-processing pipeline. Both targets re-use it; the only target-specific code is the host shell.

The plain three-geometry-teapot exercises a single forward render pass. This one threads the render through:

  1. Custom-resolution WebGLRenderTarget — the pixelated buffer
  2. RenderPassRenderPixelatedPass — multi-stage composition
  3. OutputPass — final blit to the screen framebuffer
  4. Custom GLSL shaders for the pixel-art edge detection

Each step has its own buffer / texture state. If @gjsify/webgl mishandles ANY framebuffer attachment or read-back, the pipeline produces a black canvas. Smoke-testing this showcase verifies the bridge’s framebuffer / texture state-tracking is intact across the full WebGL2 surface.