design.md 5.0 KB

Context

The reference page vertigo.html is a fullscreen WebGL effect that renders a tunnel illusion entirely in the fragment shader. Its recognizable look comes from:

  • converting centered UVs into polar coordinates
  • building ring bands that scroll by depth
  • slicing those rings with angular segment lines
  • modulating ring brightness with multiple wave layers
  • adding sparse flash spikes and neon edge highlights
  • mixing a dark purple / crimson base with amber and red accents

For this repository, the right translation is a component-scoped shader on a single square PlaneGeometry. The component should preserve the motion language and palette feel of the reference while removing DOM shell concerns, fullscreen sizing, and pointer-drag rotation behavior.

Goals / Non-Goals

Goals:

  • Add a new independent component instead of editing existing panel components.
  • Render the effect on a square plane that sits flat on the ground by default.
  • Preserve the reference page's polar tunnel illusion, segmented rings, wave pulses, and flashing highlights.
  • Keep the effect autonomous with no click, hover, touch, or drag behavior.
  • Expose a concise set of safe controls through src/dcsConfig.ts.

Non-Goals:

  • Do not reproduce the fullscreen canvas shell, page label, or document styling from the reference page.
  • Do not modify src/views/previewEntry.vue or src/views/templateComponet.vue.
  • Do not replace dreamyFluidPanelComponent or any existing panel component.
  • Do not introduce extra mesh layers or geometry-heavy ring instancing.
  • Do not port unused or page-specific interaction parameters from the reference file.

Decisions

  1. Decision: Implement the effect as one square PlaneGeometry with a custom shader material.

    • Rationale: The source effect is fundamentally fragment-driven, and a single plane keeps the port lightweight and aligned with repository conventions.
    • Alternative considered: Building the tunnel from repeated ring meshes or instanced geometry. This was rejected because it adds complexity and does not improve the intended floor-surface use case.
  2. Decision: Use square dimensions controlled by a single size prop.

    • Rationale: The user explicitly requested a square plane, so a single size control is clearer than separate length and width values.
    • Alternative considered: Keeping independent width and length controls. This was rejected because it weakens the requested square-plane contract.
  3. Decision: Preserve the reference structure by reusing polar mapping, depth scrolling, ring segmentation, layered pulse waves, flash spikes, vignette, haze, and grain in adapted form.

    • Rationale: Those elements are what make the reference visually identifiable as vertigo.html.
    • Alternative considered: Replacing the shader with generic radial noise and bloom. This would lose the reference identity.
  4. Decision: Remove pointer drag and keep the rotation drift autonomous.

    • Rationale: A reusable service component should animate on its own and ignore preview pointer events unless interactivity is explicitly required.
    • Alternative considered: Preserving a user-driven rotation offset. This was rejected because it depends on page-level event wiring and contradicts the requested migration style.
  5. Decision: Expose a compact control set centered on motion, density, glow, and palette.

    • Rationale: size, tunnelSpeed, rotationSpeed, ringFrequency, segmentCount, pulseIntensity, flashIntensity, edgeGlow, opacity, and four palette colors are enough to reshape the effect without overloading the config panel.
    • Alternative considered: Exposing every internal threshold and timing constant from the source shader. This was rejected because it would create a noisy, harder-to-use control surface.

Risks / Trade-offs

  • Risk: Because the source is a fullscreen shader, mapping it onto a finite square plane can make the edges feel more abrupt.

    • Mitigation: Add a soft square edge mask and keep haze / vignette active so the pattern sits naturally inside the plane.
  • Risk: High ring density combined with high flash intensity can produce over-bright or noisy visuals.

    • Mitigation: Clamp all exposed numeric props to conservative ranges in both the component and the registry config.
  • Risk: The tunnel illusion can look flatter from a perfectly top-down view than from an angled camera.

    • Mitigation: Preserve strong pulse contrast, edge highlights, and atmospheric darkening so the plane still reads clearly from typical scene cameras.

Migration Plan

  • Create the OpenSpec change artifacts for the new component.
  • Add src/components/vertigoHaloComponent.vue with safe prop clamping, uniform syncing, and time updates.
  • Add src/shader/vertigoHaloComponent/panel.vert and panel.frag.
  • Register the component in src/dcsConfig.ts with defaults, config controls, and default object transform.
  • Add a preview asset under public/preview/.
  • Run npm run build and update tasks.md with completion status.

Open Questions

  • None for the current scope.