devlog 3 min read

Adding a Radiant Shader Background

A short postmortem on integrating a full-page shader background into ddox.cc without letting the effect take over the layout.

#astro #webgl #design #meta

I replaced the homepage background on ddox.cc with a tuned version of Radiant’s Phase Transition shader.

On paper, this looked simple. The shader is a self-contained HTML file with its own canvas and runtime, so the obvious move was to drop it into the site and call it done.

That part was easy. The difficult part was making it behave like part of the site instead of a visual effect pasted behind it.

Keep the effect isolated

The first decision was architectural. I did not rewrite the shader into Astro or Preact code. I kept it as a local static asset and mounted it through a fixed iframe behind the homepage content.

That choice preserved two useful boundaries:

  • The shader remained close to the original implementation
  • The site layout stayed responsible only for stacking, readability, and section structure

The integration layer ended up being small:

<PageLayout ambientBackground>
  <RadiantBackground />

  <div class="relative z-10">
    <Hero />
    <ScrollReveal>
      <FeaturedProjects />
    </ScrollReveal>
  </div>
</PageLayout>

That was enough to keep the animation independent while still letting the homepage control how much of it was visible.

The part that failed first

The static build looked correct almost immediately. The homepage rendered, the background moved, and the content stayed readable.

The dev server check exposed the real risk. A full-screen shader is good at making everything look fine in isolation while quietly breaking the page shell around it. The problem was not the animation itself. It was verification. A background effect can look correct in one path and still feel wrong once the rest of the page starts scrolling, revealing content, and layering cards over motion.

That changed how I validated the change. Instead of treating this as a visual tweak, I treated it like an integration problem:

  • verify the homepage still rendered the expected content structure
  • verify the old hero-only background layers were actually gone
  • verify the full Astro build still completed cleanly
  • verify the page in a browser on desktop and mobile

The browser pass mattered most. That is where it became obvious whether the shader was supporting the layout or competing with it.

What I tuned

The original effect had the right motion language but the wrong palette and intensity for this site. I adjusted the particle colors toward the existing gold-on-charcoal theme, reduced the density slightly, slowed the wave, and added a site-level overlay to darken the long scroll.

The key lesson was simple: motion is not the hard part. Restraint is.

A good background effect should make the page feel more deliberate without asking for attention on every screen. Once the content starts fighting the backdrop, the effect has already failed.

That is the tradeoff I wanted here. Keep the shader expressive, but make the homepage remain the thing people actually read.