---
title: SC Neon Wave Shader
description: A WebGL shader drawing a glowing neon wave that reacts to hover.
url: https://secretocho.design/lab/sc-neon-wave-shader/
type: SoftwareSourceCode
status: working
published: 2025-09-01
updated: 2025-09-01
---

# SC Neon Wave Shader

> A WebGL shader drawing a glowing neon wave that reacts to hover.

component 06 / 28 · WORKING

- **type**: Code Component
- **platform**: Framer
- **last update**: 2025-09-01
- **license**: SecretoCho Design

![A still of the SC Neon Wave Shader demo, as its module draws it with reduced motion.](https://secretocho.design/_astro/still.DvDufscR_2k4Iua.webp)

*fig 00 · live demo, ported from **SC\_NeonWaveShader.tsx***

Dynamic WebGL shader rendering a glowing neon wave with interactive hover and configurable parameters.

A WebGL-based neon shader effect for Framer. Renders an animated glowing wave with hue-shifted neon colors, interactive hover response, and real-time distortion. Ideal for futuristic hero sections, reactive backgrounds, or experimental UI flourishes.

- UI
- Visual
- FX
- Shaders
- Neon

## Main

### Overview

- **Built With**: React, WebGL (GLSL shaders), Framer Code Component API
- **Layout Support**: Fills parent frame, responsive to resizing
- **Orientation**: Full background canvas
- **Ideal Use Case**: Hero banners, experimental motion backdrops, cyberpunk UI

### Tags

- shader
- neon
- wave
- webgl
- glow
- interactive

### Code comment

*SC\_NeonWaveShader.tsx · lines 4–8 · the file’s header comment*

```tsx
/**
 * @framerDisableUnlink
 * @framerSupportedLayoutWidth any
 * @framerSupportedLayoutHeight any
 */
```

### Dependencies

- **Technologies**: WebGL + GLSL
- **Notes**: No external libs; pure WebGL shader compiled at runtime.

### Complexity

- **Logic Level**: High (custom GLSL, shader compilation, event handling)
- **Runtime Cost**: Medium–High (continuous render loop; GPU-intensive)
- **Component Size**: ~15–20 KB (shader code heavy)
- **Notes**: Disable on mobile if battery/perf concerns.

## Guide

### Instructions

1. Add to your Framer project and place on the canvas.
2. Configure **Base Color** + **Hover Color** (Vec3 strings, e.g., "0.2,0.4,1.0").
3. Adjust distortion: **Vertical Distortion**, **Wave Frequency**, **Glow Alpha**.
4. Toggle **Mouse Reactive** and **Reset on Leave** for interaction control.
5. Use Section ID to isolate multiple instances without input conflicts.

### Examples / Presets

- Preset A (Default Glow)
  
  - **base**: 0.2,0.4,1.0
  - **hover**: 1.0,0.3,0.8
  - **speed**: 1.0
  
- Preset B (Cyber Pink)
  
  - **base**: 0.8,0.0,0.8
  - **hover**: 0.2,0.8,1.0
  - **glow**: 1.5
  - **bgAlpha**: 0.8
  
- Preset C (Subtle Lines)
  
  - **base**: 0.1,0.6,0.9
  - **hover**: 0.9,0.1,0.2
  - **speed**: 0.5
  - **distortion**: 0.2
  

## Mechanics

### How it Works

- Compiles **vertex** and **fragment** shaders on mount.
- Fragment shader computes neon wave using **sine distortion** + **rect masks**.
- Colors hue-shifted via YIQ → RGB matrix transform.
- **Mouse position** injected into shader uniforms for hover/interaction.
- Continuous requestAnimationFrame updates iTime, wave distortion, and glow.

### Performance & Tuning

- Lower **Wave Frequency** + **Glow Alpha** = less GPU stress.
- Keep animationSpeed ≤ 2 for smoothness across devices.
- On low-end hardware, disable **Mouse Reactive** to reduce uniform updates.

### Compatibility & Limits

- Requires **WebGL** (desktop and most mobile browsers).
- Firefox may render slightly differently due to composite differences.
- Pointer events disabled (pointerEvents: none on canvas).

## Quality

### Accessibility

- Purely decorative; mark container aria-hidden="true" if non-essential.
- Avoid excessive motion in contexts with reduced motion settings (can wrap with prefers-reduced-motion check).

### Security & Privacy

- No external calls; all shader code runs locally.
- No eval/dangerous APIs.
- Cleans up event listeners + RAF loop on unmount.

## Reference

### Props

| name | type | default | description |
| --- | --- | --- | --- |
| baseNeonColor | string(Vec3) | “0.2,0.4,1.0” | RGB vec3 string for base neon color. |
| hoverNeonColor | string(Vec3) | “1.0,0.3,0.8” | RGB vec3 string for hover neon color. |
| baseHue | number(0–1) | 0.0 | Hue shift factor for base color. |
| hoverHue | number(0–1) | 0.0 | Hue shift factor for hover color. |
| animationSpeed | number | 1.0 | Global animation time multiplier. |
| verticalDistortion | number | 0.4 | Wave vertical distortion (scroll amplitude). |
| waveFrequency | number | 10.0 | Frequency of the wave oscillation. |
| glowAlpha | number | 1.0 | Glow strength multiplier. |
| bgAlpha | number | 1.0 | Background alpha blend. |
| mouseReactive | boolean | true | Enable mouse tracking reactivity. |
| resetOnMouseOut | boolean | true | Fade out effect after leaving canvas. |
| sectionId | string | “default” | Unique ID to avoid conflicts with multiple shaders. |

### Notes & Tips

- Use **Hex→Vec3 converter** for colors: [Hex to Vec3 Tool](https://airtightinteractive.com/util/hex-to-glsl/?ref=threejsresources).
- To reduce power drain, throttle animationSpeed or disable mouse tracking.
- For layered designs, wrap with opacity masks or blend modes in Framer.

### Troubleshooting / FAQ

“WebGL not supported”

Browser/device doesn’t support WebGL; try enabling it in settings.

Shader not showing

Check color strings are valid R,G,B floats.

Motion stutters

Lower frequency/speed; test on GPU-accelerated browsers.

## Source

### Header comment

SC\_NeonWaveShader.tsx has no doc comment: its header, lines 4–8, holds only Framer’s annotations (shown under \[MAIN\]).

[props \[REF\]](#reference)

### Key excerpt

The fragment shader: a sine wave bends a blurred band, a wider blur makes the glow, and the colour mixes toward the hover colour near the pointer.

*SC\_NeonWaveShader.tsx · lines 114–159 · glsl*

```glsl
            void mainImage(out vec4 fragColor, in vec2 fragCoord) {
                vec2 uv = fragCoord / iResolution.xy;
                vec2 mouse = iMouse.xy / iResolution.xy;
                float t = iTime * animationSpeed;
                float isClicked = iMouse.z;

                float waveOffsetX = 0.16;
                float waveOffsetY = 0.0;

                if (isClicked > 0.0) {
                    waveOffsetX = mix(0.16, mouse.x, 0.3);
                }

                vec2 offsetUV = uv - vec2(waveOffsetX, waveOffsetY);
                offsetUV.y *= 15.0;
                float x = offsetUV.x;

                float waveAmplitude = scrollAmplitude;
                if (isClicked > 0.0) {
                    waveAmplitude = scrollAmplitude + 0.1 * sin(t * 2.0);
                }
                float m = sin(t / .9 + x * waveFrequency) * waveAmplitude;
                float y = offsetUV.y - 0.4 * m;

                float blur = pow(remap(-0.4, 0.4, 0.1, 1.2, x), 2.0);
                float mask = rect(-0.4, 0.4, -0.4, 0.1, vec2(x,y), blur);
                float glowMask = rect(-0.4, 0.4, -0.4, 0.1, vec2(x,y), blur * 3.0);

                vec2 wavePos = vec2(x, y/15.0) + vec2(waveOffsetX, 0.0);
                float mouseDist = length(mouse - wavePos);
                float hoverEffect = smoothstep(0.15, 0.0, mouseDist);

                vec3 baseCol = hueShift(baseColor, baseHue);
                vec3 hoverCol = hueShift(hoverColor, hoverHue);
                vec3 finalNeonColor = mix(baseCol, hoverCol, hoverEffect);

                vec3 col = vec3(1.0) * mask;
                float glowIntensity = min(1.0, 0.6 + hoverEffect * 0.3) * glowAlpha;
                col += finalNeonColor * glowMask * glowIntensity;
                col *= 1.15 + hoverEffect * 0.15;
                if (hoverEffect > 0.05) col *= 1.0 + 0.07 * sin(t * 3.0) * hoverEffect;

                float darkness = 1.0 - clamp(length(col), 0.0, 1.0);
                float bgBlend = mix(1.0, bgAlpha, darkness);
                fragColor = vec4(col, bgBlend);
            }
```

## Credits

### Credits

- Shader math adapted from GLSL neon and wave distortion patterns.
- Implementation & Framer adaptation by SecretoCho Design.

- **license**: SecretoCho Design

SecretoCho Design 2025

### Disclaimer

Provided “as is” for visual/UX purposes. Validate performance impact, accessibility, and GPU compatibility before production use.

## Proves

- [Creative coding](https://secretocho.design/about/#capabilities)

## Hiring a design engineer?

I’m open to senior design engineer roles: remote from Belgrade, or relocation with visa sponsorship. Write to me, or read the CV first. Client work stays selective, one project at a time.

[sc@secretocho.design](mailto:sc@secretocho.design)

[read the CV](https://secretocho.design/cv/) · [LinkedIn](https://www.linkedin.com/in/secretocho/)
