跳到主要內容

lab · landing-hero heroVisual

Hero lab · webgl-hero backgrounds

Working catalog of landing-hero heroVisual candidates built on the webgl-hero widget, with exact config and honest verdicts.

Site landing-hero (blocklets/arcblock/.web/components/landing-hero/) accepts an optional heroVisual prop that renders a full-bleed .landing-hero-visual target div behind the copy. Pair it with an AUP widget child block naming a Web Device widget (here, webgl-hero — WebGL 3D backgrounds, 24 modes, shipped with the runtime) and the hero becomes a real demonstration of what Web Device's widget layer can render, not decoration bolted onto the page.

This page is a running catalog, not a tutorial: each candidate below is a real render with its exact config, kept here so a future pass doesn't have to re-derive which modes actually work and which look right for this site's editorial tone — see "Dead ends" for the ones that don't.

All 24 webgl-hero modes, using this site's own ::gallery{folder} media block (see Folder-backed media gallery) rather than a hand-built grid. Each mode's caption notes what it renders and whether it reads the colors config or hardcodes its own palette; full config and larger screenshots are in the reference section further down the page.

How this is wired

aup
component hero slot=site-introduction component=landing-hero variant=home
    headlineVariant=balanced-statement maxLines=3 heroVisual=webgl
    title=:k0 subtitle=:k1 ... {
  widget hero-bg name=webgl-hero target=".landing-hero-visual" mode=topo
      colors="#008f7a,#fcfdfc" opacity=0.5 speed=0.4 mouse=false
}

heroVisual=webgl switches the component to single-column copy with a fixed max-width and a readability scrim. Horizontal coverage is sized off the copy box (not the section — a scrim sized in vw/% drifts out of sync with the text the wider the browser window gets). Vertical coverage has to reach the hero edges: the copy sits in a padded, vertically-centered inner, so a scrim that only extends a few rem around the copy leaves a strip of uncovered canvas under the header. The trace/geometry aside used elsewhere on this site is suppressed when heroVisual is set — pick one visual per hero, not both.

Below 760px the widget doesn't run at all — a small inline script registers a DOMContentLoaded listener early enough to remove the widget's config <script> before the engine's own listener ever scans for it, so no WebGL context, no Three.js, no render loop gets created on a phone. Matches this site's rule that mobile layouts don't run WebGL/canvas effects; a plain hero (headline, subtitle, actions) renders instead.

Live comparison pages (internal, not in nav): /en/hero-lab-topo/, /en/hero-lab-aurora/, /en/hero-lab-cubegrid/ — same copy as the homepage hero, different heroVisual config, useful for side-by-side judgment in a real browser before anything ships to the homepage itself.

These render correctly only against a locally-built arc. The CSS-override and opacity bugs below are fixed upstream in ArcBlock/arc#4402 (merged), and the topo coverage/aspect fix is in ArcBlock/arc#4490 — until whichever of those hasn't shipped in a release lands on the arc binary actually serving this blocklet, the live pages above can still show the un-fixed behavior (widget mounts but collapses to height:0, or topo stretched on wide screens). The screenshots in each candidate section are the honest record of what this looks like on a fixed build; the live links are for local verification, not a guarantee of what the deployed site currently shows.

Candidates

topo — dense contour fill

ArcBlock hero with a topographic contour-line pattern in teal, fading to white behind the "Own the software you need." headline

mode=topo colors="#008f7a,#fcfdfc" colorsDark="#2ec8ae,#061211" opacity=0.5 speed=0.4 mouse=false

Verdict: strongest candidate so far. Reads as a real technical texture (elevation lines), not a generic AI-tech gradient, and holds up at both narrow and ultra-wide viewports once the plane-sizing fix below landed. Full opacity control works (this mode respects opacity).

Known gaps fixed while building this:

  • TopoEngine used a fixed-size PlaneGeometry(30, 20), which only covers hero aspect ratios up to about 2.4 — any wider browser window ran past the plane's edge and showed bare fill color down both sides. Fixed upstream to size the plane from the camera's actual visible frustum at render time (see "Upstream fixes" below).
  • That coverage fix exposed a second bug: the noise shader samples vUv * 6.0 on both axes, and vUv is 0-1 per axis regardless of the plane's physical aspect ratio — on a wide plane each noise cycle covers more physical width than height, so contours read as horizontally stretched streaks instead of round elevation-line blobs. Fixed upstream by scaling only the x sample by the plane's aspect ratio, keeping a noise cycle the same physical size on both axes.
  • The widget's colors config is static and theme-unaware — a light-mode config rendered as a bright rectangle in dark mode. landing-hero's render.js now accepts a matching colorsDark/bgDark pair and swaps them in client-side before the widget parses its config, if the page loads with dark mode already active. Known remaining gap: switching the theme toggle live (no reload) does not retroactively recolor the already-rendered canvas — the swap only applies at load time.

aurora — atmospheric gradient

ArcBlock hero with a dark aurora/starfield gradient behind the headline, fading from white on the left to near-black on the right

mode=aurora colors="#008f7a,#2ec8ae,#0f3d38" opacity=0.5 speed=0.4 mouse=false

Verdict: visually striking but reads closer to a generic "AI product" demo than this site's restrained editorial tone. Still needs either a lower-contrast color set or a narrower subtitle measure before it's a real candidate, not just a working one.

Bug found while building this: a dark, hard-edged band ran across the top of the hero, right below the header. An earlier pass measured the section, the .landing-hero-visual target, and the canvas as pixel-identical via getBoundingClientRect(), concluded it wasn't CSS, and spent three attempts tuning camera.lookAt() on aurora / ocean / retrowave. That diagnosis was wrong. The canvas does fill the section; the missing coverage is the readability scrim on .landing-hero-copy::before. The copy sits in a padded, vertically-centered inner, and the scrim only extended ±8rem around that box — about 45px of uncovered canvas under the header at 1440px, more at other widths. Dark modes make that strip obvious; light modes like topo hide it. The published "fixed" retrowave screenshot still showed the band.

The actual fix is in landing-hero CSS: keep the scrim's horizontal sizing tied to the copy, and stretch it vertically past the section (top/bottom: -100vmax, clipped by .landing-hero { overflow: hidden }). Verified at 600/868/1221/1440/1920px. Camera tilt can still leave empty sky in the 3D scene itself; that is a different, remaining widget issue, not the header gap.

cubegrid — geometric wireframe grid

ArcBlock hero with a grid of small rotating teal wireframe cubes behind the headline, echoing the ArcBlock cube/pyramid mark

mode=cubegrid colors="#008f7a" opacity=0.6 speed=0.5 mouse=false

Verdict: the strongest thematic fit — the rotating wireframe cubes echo the actual ArcBlock cube/pyramid mark instead of being an unrelated texture, and a single accent color keeps it quiet. Worth testing against positioning.md's "would this still make sense on a generic AI site" question before committing — the geometry argument is specific to us, but the effect alone is a common pattern.

Dead ends

Rendered and screenshotted, not just described from reading the source — a mode that "should" work on paper can still fail on screen, and the reverse (see rings below, corrected after actually looking). Also live (internal, not in nav) for the same local-build caveat as above: /en/hero-lab-network/, /en/hero-lab-wave/, /en/hero-lab-rings/.

network — dead, ignores brand color entirely

ArcBlock hero with a dark starfield/network-node background of thin white lines and glowing points, ignoring the configured teal color entirely

mode=network colors="#008f7a,#0f3d38" opacity=0.5 speed=0.4 mouse=false

Verdict: dead end, not a style judgment — NetworkEngine hardcodes its palette directly in the GLSL fragment shader and never reads cfg.colors, so the teal config above has zero effect; what renders is a generic blue-white constellation look with no connection to this site's palette. Not usable until that color-hardcoding gap is fixed upstream (tracked in the issue, not fixed in this PR — bigger change than the mechanical opacity fix).

wave — dead, too sparse to read as a background

ArcBlock hero with a sparse starburst of thin teal lines radiating from a point behind the headline, mostly empty canvas around it

mode=wave colors="#008f7a,#1f7a6e" bg="#fcfdfc" opacity=0.85 speed=0.4 mouse=false

Verdict: dead end. Technically the best-behaved mode (respects both opacity and colors, no upstream bugs), but the wireframe sphere is small and sparse relative to a 1440×600+ full-bleed canvas — it reads as a tiny starburst floating in mostly-empty space, not a background.

rings — not chosen, but wrongly assumed sparse before actually rendering it

ArcBlock hero with a large wireframe sphere made of many overlapping teal orbital rings behind the headline

mode=rings colors="#008f7a" bg="#fcfdfc" opacity=0.85 speed=0.4 mouse=false

Verdict: correction — an earlier draft of this page grouped rings with wave as "too sparse" based on reading the engine's source, without actually rendering it. It isn't sparse at all: 18 overlapping rings read as a bold, cohesive wireframe globe. Not chosen for a different reason, checked against positioning.md's self-test ("would this still make sense on any generic AI site?") — a wireframe globe/orbit is a common tech-marketing cliché with no connection to this site's own content, unlike cubegrid's actual cube/pyramid mark. Left out on that basis, not because it doesn't render well.

Also surveyed

webgl-hero ships 24 modes total. The six above are the ones worth a real decision; the rest were rendered and screenshotted for completeness, not left as an assumption from reading the source. Same config shape throughout unless noted: teal-family colors, bg="#fcfdfc", opacity=0.6, speed=0.4, mouse=false. Every mode covered on this page has a matching live page (internal, not in nav) at /en/hero-lab-<mode>/, same local-build caveat as above.

Ignores the color config entirely (confirmed via source, not just the render)

crystal, phantom, lightcube, reflect, gyroid, tunnel, and abstract never read cfg.colors — each hardcodes its own palette in-shader, the same class of bug as network. None are usable without that fix landing upstream (not attempted here — bigger surface than the mechanical opacity fix).

ModeScreenshotNote
crystalcrystal: purple/blue glass shards flying, ignoring the teal configOff-brand purple/blue glass shards.
phantomphantom: white glowing bokeh shapes on a dark backgroundOff-brand white bokeh glow.
lightcubelightcube: muddy orange and blue blurred cube gridMuddy, off-brand, part of the frame renders flat black.
reflectreflect: stacked colorful boxes resembling cardboard cartonsReads as stacked cardboard boxes, not abstract.
gyroidgyroid: psychedelic red and blue fractal surfacePsychedelic, jarring, wrong tone entirely.
tunneltunnel: dark abstract tunnel with magenta and gold edgesOff-brand magenta/gold, mostly a black void.
abstractabstract: iridescent oil-slick magenta and gold gradientOff-brand iridescent oil-slick look.

Too sparse or too small to read as a background

blob: a small pale faceted rock shape floating off to the side collapse: a sparse scatter of falling dots, mostly empty canvas meshline: scattered short diagonal line fragments, mostly empty canvas

blob, collapse, meshline — same failure mode as wave: technically fine, geometrically too thin against a full-bleed 1440×600+ canvas to register as a background at a glance.

Renders fine but reads as a generic tech-marketing cliché

galaxy: a dense gray and teal particle network sphere

galaxy — a bold, dense network-globe. Same call as rings: common "blockchain network" stock imagery, not specific to this site.

landscape: a stock photo–style mountain range and road at sunset, colors ignored

landscape — full-bleed mountain/road/sunset scene. Reads as generic stock photography; also ignored the teal config (rendered in neutral grays/tans regardless). Still not a candidate for the stock-photo reason.

retrowave: an 80s-style synthwave sunset over hills, with the grid floor still in view

retrowave — the textbook synthwave sunset. The most generic "AI demo site" cliché in the whole set; also overlaps the subtitle enough to hurt readability. The header-gap on this mode is the CSS scrim bug described under aurora (screenshot above is after that fix; the grid floor is still in the scene). Still not a candidate for the cliché reason.

Chaotic / visually noisy

cube: a large distorted, glitchy-looking wireframe cube

cube — a wireframe box with heavy vertex jitter. Reads as a rendering glitch rather than an intentional effect, and its right edge sits under the subtitle text.

On-brand color, decent render, not chosen for content reasons

ocean: a teal ocean horizon with a sunset sky

ocean — actually picks up the teal config correctly (the "water" fill is on-brand) and looks calm. Not chosen because the content itself — a literal ocean/sunset scene — has no connection to software or this site's subject matter.

metaball: soft glowing teal blobs floating on a dark background

metaball — also correctly on-brand (soft teal glow blobs), the best-looking of this group. Reads as a generic "lava lamp" ambient effect; kept as a fallback option worth reconsidering if none of the three main candidates survive further design review.

marble: a single large glossy mint-colored sphere

marble — originally rendered nothing at all: two texture files it loader.load()s (marble-noise.jpg, marble-noise3d.jpg) 404'd in every environment, never shipped anywhere in the widget package. Filed as ArcBlock/arc#4417 and fixed upstream in ArcBlock/arc#4440 (merged) by replacing the missing textures with procedural noise. Now renders — a single large glossy sphere, on-brand color, but no visible marble veining came through from the procedural swap; reads as a generic glass/chrome orb rather than anything specific to this site. Not chosen for the same reason as metaball: a correct, on-brand render of a generic effect.

Broken

clouds: a flat teal gradient with no visible cloud detail

clouds — rendered as a flat gradient wash with no visible volumetric detail. CloudsEngine has GPU tier detection that drops march-step quality on a detected low-end/software renderer; this ran under headless Chromium (SwiftShader), which may explain it — inconclusive without a real-GPU comparison, noted here rather than guessed at.

Upstream fixes behind this

Four webgl-hero bugs surfaced while building the above, all now fixed upstream:

  • ArcBlock/arc#4392 — the widget's own injected CSS (.wh{position:relative}) silently overrode this site's position:absolute;inset:0 on the target element (equal specificity, later in the cascade), collapsing it to height:0 in every mode regardless of config. Also: 17 of ~24 modes discarded the opacity config via a duplicate setClearColor(x, 1) call. Fix: ArcBlock/arc#4402 (merged) — applies cfg.opacity via canvas CSS opacity instead of WebGL clear alpha, since three.js's WebGLBackground hardcodes clear alpha to 1 for any scene.background Color regardless of setClearColor's alpha argument. An earlier attempt at this same fix (#4403, closed as a duplicate) took the per-engine route of nulling scene.background on all 17 modes — #4402's single shared-function fix is the one that actually shipped.
  • topo's plane was a fixed PlaneGeometry(30, 20), covering only ~2.4 aspect ratio — any wider hero ran past the plane's edge and showed bare clear color as a margin down both sides. Once fixed to size from the camera's actual frustum, this exposed a second bug: the noise shader sampled both axes at the same rate, stretching contours horizontally on any wide hero. Fix: ArcBlock/arc#4490.
  • marble loaded two texture files that don't exist anywhere in the widget package, rendering nothing. Filed as ArcBlock/arc#4417, fixed in ArcBlock/arc#4440 (merged) — see its entry above.

The header-band artifact investigated under aurora above was in arcblock-site's own readability scrim, not this widget — webgl-hero's camera behavior was never the cause. See that section for the fix.

Until the fixes above ship in a release, the candidates on this page only render correctly on a locally-built arc — see the site's arc-upstream skill for what "upstream closed" vs. "we can actually use it" means in practice.