Four live WebGL shaders, each targeting a different visual cortex mechanism. Sliders change shader parameters in real time. Set them before tapping Enter VR since controls are hidden in immersive mode.
1. Moiré interference grid (emergent motion)
Exploits: V1 spatial frequency channel beating + apparent motion without source movement
Core GLSL (fragment shader)
vec2 p = (vUv-0.5); p.x *= uRes.x/uRes.y;
float t = uTime*uAngleSpeed*0.3;
vec2 g1 = p*uScale;
float grid1 = sin(g1.x*6.283)*sin(g1.y*6.283);
float ca=cos(t),sa=sin(t);
vec2 g2 = vec2(p.x*ca-p.y*sa, p.x*sa+p.y*ca)*uScale*1.037;
float grid2 = sin(g2.x*6.283)*sin(g2.y*6.283);
float moire = grid1*grid2;
float amp = moire*0.5+0.5;
vec3 col = hsv2rgb(vec3(amp*0.5+uTime*0.03, uSaturation, pow(amp,0.65)));
gl_FragColor = vec4(col,1.0);
Create a self-contained Three.js r169 WebGL demo showing a psychedelic moiré interference field. Fullscreen quad, ShaderMaterial. Fragment: two sinusoidal grids — grid1 = sin(p.x*scale*6.283)*sin(p.y*scale*6.283), grid2 same but rotated by uTime*uAngleSpeed and scaled by 1.037. Multiply grids for interference value. HSV color from interference amplitude cycling with uTime. uScale, uAngleSpeed, uSaturation sliders. 300px canvas.
2. Infinite tunnel (depth cue overload)
Exploits: looming response + vergence-accommodation conflict
Core GLSL (fragment shader)
vec2 uv = vUv * 2.0 - 1.0; uv.x *= uRes.x / uRes.y;
float r = length(uv); float angle = atan(uv.y, uv.x);
float depth = 0.4 / (r + 0.005);
float td = mod(depth - uTime * uRushSpeed, 1.0);
float ta = mod(angle / (PI / uSymmetry), 1.0);
float stripes = sin(ta*28.0+uTime*0.5)*0.5+0.5;
float rings = sin(td*22.0-uTime*2.0)*0.5+0.5;
vec3 col = hsv2rgb(vec3(td*0.55+uTime*0.07, 0.97, 1.0))
* stripes * rings * uBrightness;
col *= 1.0 - smoothstep(0.6, 1.05, r);
gl_FragColor = vec4(col, 1.0);
Create a self-contained Three.js r169 WebGL demo showing a psychedelic infinite tunnel. Fullscreen quad, ShaderMaterial. Fragment: polar coordinate mapping, depth = 0.4/r, animate with mod(depth - uTime*uRushSpeed, 1.0). uSymmetry angular sectors. Stripe and ring interference. HSV color cycling. uRushSpeed, uSymmetry, uBrightness sliders. Vignette at edges. 300px canvas.
3. Displacement mapping (breathing surfaces)
Exploits: surface normal processing (V2/V3) + proprioceptive conflict
Core GLSL (vertex shader)
vec3 pos = position; float ws = uWaveSpeed;
float h = sin(pos.x*2.2+uTime*0.6*ws) * sin(pos.y*2.2+uTime*0.45*ws) * uAmplitude;
h += sin(pos.x*6.0+uTime*1.3*ws) * sin(pos.y*4.5+uTime*1.1*ws) * uAmplitude * 0.33;
h += sin((pos.x+pos.y)*5.5+uTime*1.9*ws) * uAmplitude * 0.16;
pos.z += h; vH = h;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
Create a self-contained Three.js r169 WebGL demo showing a psychedelic breathing displacement surface. PlaneGeometry(4,4,64,64), perspective camera looking down at an angle. ShaderMaterial: vertex displaces Z with 3 sin() wave frequencies * uAmplitude * uWaveSpeed. Fragment: HSV color-by-height with uTime hue cycling, plus fract(vUv*uGridDensity) grid overlay. uAmplitude, uWaveSpeed, uGridDensity sliders. 300px canvas.
4. Polar sine field (rotational standing wave)
Exploits: V1 orientation selectivity + pattern completion loop
Core GLSL (fragment shader)
vec2 p = vUv*2.0-1.0; p.x *= uRes.x/uRes.y;
float r = length(p); float a = atan(p.y,p.x);
float radial = sin(r*uRadFreq - uTime*uSpeed);
float angular = sin(a*uAngFreq + uTime*uSpeed*0.43);
float diag = sin((r*uRadFreq*0.7 + a*uAngFreq*0.5)*1.2 + uTime*uSpeed*0.6);
float field = (radial*angular + diag*0.6)/1.6;
float brightness = field*0.5+0.5;
vec3 col = hsv2rgb(vec3(field*0.4+r*0.1+uTime*0.05, 0.97, brightness));
col *= 1.0-smoothstep(0.82,1.05,r);
gl_FragColor = vec4(col,1.0);
Create a self-contained Three.js r169 WebGL demo showing a psychedelic polar sine interference field. Fullscreen quad, ShaderMaterial. Fragment: polar coords, three overlapping sine waves: radial = sin(r*uRadFreq - uTime*uSpeed), angular = sin(a*uAngFreq + uTime*uSpeed*0.43), diagonal = sin((r*uRadFreq*0.7 + a*uAngFreq*0.5)*1.2 + uTime*uSpeed*0.6). Combine and map to HSV. uRadFreq, uAngFreq, uSpeed sliders. Vignette. 300px canvas.
About these techniques
1. Moiré interference grid
Two sinusoidal grids at slightly different scales overlap, producing a low-frequency beat pattern that appears to travel across the field even though neither underlying grid moves fast. V1 contains dedicated spatial-frequency detectors tuned to specific grating wavelengths. Two slightly different wavelengths produce a beat at their difference frequency, generating motion signals in MT/V5 from sources that are not actually moving. Scale sets grid density; Angle Speed rotates one grid against the other; Saturation controls color depth.
2. Infinite tunnel
A tunnel rendered in polar coordinates with continuously advancing depth creates persistent looming motion the brain cannot habituate to, because it never arrives. The vergence-accommodation system drives the eyes to converge on approaching geometry and finds nothing solid. Rush Speed controls how fast the tunnel appears to advance; Symmetry sets angular sector count; Brightness scales overall output without changing the color balance.
3. Displacement mapping
Animated vertex displacement across a 64x64 mesh creates the "breathing floor" effect. V2 and V3 cortical areas process surface curvature and depth discontinuities; a gently undulating mesh creates continuous non-zero input with no stable resting state. The grid overlay makes the vertex density visible. In Quest VR with head tracking, tilting your head toward the mesh amplifies the proprioceptive conflict between visual motion and vestibular stillness.
4. Polar sine field
Three overlapping sine waves in polar coordinates (radial, angular, and diagonal) generate a lattice of nodes that appears to rotate, breathe, and reorganize simultaneously. V1 contains orientation-selective columns tuned to specific grating angles. When three orientations are simultaneously active at full saturation, the cortex attempts to form a stable percept, identifies a pattern, then finds it has shifted before the identification completes. Radial Freq controls ring density; Angular Freq sets sector count; Speed drives all three waves.
Key takeaways
- Visual cortex saturation: Psychedelic VR works by overloading multiple parallel visual processing streams simultaneously rather than engaging any single one, exceeding the cortex's capacity to form stable representations.
- 4 live WebGL demos: Every technique runs as an interactive Three.js r169 demo with real-time shader parameter sliders. No install or build step required.
- Works across VR headsets via WebXR: Quest 2/3/Pro, Pico 4, and any PC VR headset (Valve Index, Varjo, Pimax) running Chrome or Edge with SteamVR active.
- Quest 2 frame budget is 13.9ms: A single fullscreen GLSL shader costs 2-5ms. Combining 3-4 effects requires adaptive quality management to stay within budget.
- Three.js over Unity for browser VFX: Three.js ShaderMaterial exposes raw GLSL with no build pipeline, making it faster to iterate and easier to generate with AI assistance.
Why Three.js for browser VR
Three.js r169 exposes raw GLSL shader control via ShaderMaterial, handles WebXR stereo rendering for the Quest browser natively, and is deliverable as a single HTML file with CDN imports. Babylon.js is a viable alternative with stronger built-in scene management for complex multi-object environments. For raw shader VFX with minimal overhead and the highest quality of AI code generation, Three.js wins on simplicity. No build pipeline. No install. The demos on this page load Three.js from jsDelivr CDN and initialize lazily as you scroll.
Which VR headsets can run these demos?
All four demos use the WebXR Device API immersive-vr session type with no proprietary SDK or native install.
- Meta Quest 2, 3, 3S, Pro: Native via Meta Quest Browser. Quest 3 at 90Hz has the most GPU headroom for layering multiple effects.
- Pico 4 / Pico 4 Ultra: Pico Browser ships with WebXR support. Open this page, tap Enter VR. Identical flow to Quest, no setup required.
- Valve Index, HTC Vive Pro 2, HP Reverb G2: Open Chrome or Edge on the connected Windows PC with SteamVR running. WebXR routes through SteamVR's OpenXR runtime automatically.
- Varjo XR-4 / VR-3: Same path: Chrome plus SteamVR. The XR-4 renders at 51 PPD. At that pixel density the Moiré interference patterns resolve at a fidelity consumer headsets cannot match.
- Pimax Crystal / 8KX: Chrome plus SteamVR plus PiTool. Fragment shaders cost 2-5ms GPU time per effect, well within budget at full Pimax resolution.
- Apple Vision Pro: Safari does not currently support
immersive-vrWebXR sessions. The demos run as flat WebGL in the visionOS browser window.
What is the WebXR performance budget on Meta Quest?
| Technique | Type | Quest 3 (90Hz) | Quest 2 (72Hz) |
|---|---|---|---|
| Infinite tunnel | Fragment shader | 1-2ms | 2-3ms |
| Displacement (64x64) | Vertex + fragment | 2-3ms | 3-4ms |
| Moiré interference grid | Fragment shader | 1ms | 1-2ms |
| Polar sine field | Fragment shader | 1ms | 1-2ms |
| Practical stack (3-4 combined) | 6-9ms | 9-13ms |
Quest 2 budget is 13.9ms total per frame. Combining more than 3-4 effects requires adaptive quality: monitor performance.now() per frame and step down shader complexity (reduce loop iterations, halve resolution) if frame time exceeds 11ms. Quest 3 has approximately 2x GPU throughput, making 4-5 combined effects feasible at 90Hz.
Frequently asked questions
What makes VR visual effects psychedelic?
Psychedelic VR effects work by simultaneously overwhelming multiple visual cortex processing streams: motion detection in MT/V5, color processing in V4, scale-invariant pattern recognition, and temporal integration. The visual cortex dedicates 50-55% of the cerebral cortex to vision, making it highly susceptible to calibrated perceptual overload. See the full neuroscience breakdown.
Can I run these VR effects in the browser without Unity?
Yes. Three.js with ShaderMaterial exposes raw GLSL and supports the WebXR Device API natively in Meta Quest Browser. All 4 demos on this page are self-contained. On Quest, open this page in the browser, scroll to any demo, and tap Enter VR to start an immersive-VR session with stereo rendering and head tracking.
How do I enter VR from the browser on Meta Quest?
Open this page in Meta Quest Browser. Scroll to any demo and tap the Enter VR button below the canvas. The browser requests permission for an immersive-vr session via the WebXR Device API. The demo renders in full stereo at the Quest's native refresh rate (72Hz on Quest 2, 90Hz on Quest 3). Press the menu button to exit and return to the page.
What is the performance budget for psychedelic VR on Meta Quest?
Quest 3 targets 90Hz (11.1ms frame budget); Quest 2 targets 72Hz (13.9ms). Fullscreen GLSL fragment shaders cost 2-5ms. GPU particles cost 1-3ms. Running 3-4 combined effects is feasible with adaptive quality reducing shader iteration counts at runtime when frame time exceeds 11ms.
Which visual effects cause the strongest perceptual response in VR?
Infinite tunnel effects are consistently the strongest because they exploit the looming response, vergence-accommodation conflict, and forward self-motion signals simultaneously. Combining any two techniques produces the most intense perceptual response within a safe frame budget.
Which VR headsets can run these WebXR demos?
Any headset with a WebXR-capable browser. Meta Quest 2, 3, 3S, and Pro work natively via Meta Quest Browser. Pico 4 and Pico 4 Ultra work via Pico Browser with the same Enter VR flow. PC VR headsets including Valve Index, HTC Vive Pro 2, HP Reverb G2, Varjo XR-4, and Pimax Crystal work by opening Chrome or Edge on the connected Windows PC while SteamVR is running: WebXR routes automatically through SteamVR's OpenXR runtime with full stereo rendering and head tracking. The shaders are fragment-bound, so higher-resolution headsets like Varjo and Pimax resolve finer interference and tunnel detail at no additional GPU geometry cost. Apple Vision Pro does not currently support immersive-vr WebXR sessions in Safari.
Sources
- Vision Dominates Half Your Brain's Processing Power (this site, 2025).
- Meta Quest Performance Optimization. Frame budget specs for Quest 2 and Quest 3.
- Three.js ShaderMaterial documentation. GLSL uniform system and WebXR integration.