### Install Dependencies and Start Development Server Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/README.md Installs project dependencies using pnpm and starts the development server. Ensure Node.js LTS and pnpm are installed. ```bash pnpm install pnpm dev ``` -------------------------------- ### Start Development Server Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/configuration.md Launches the development server for local development and testing. ```bash # Start development server pnpm dev ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/configuration.md Installs all necessary project dependencies using pnpm. ```bash # Install dependencies pnpm install ``` -------------------------------- ### Render Pass Configuration Example Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/types.md Example demonstrating how to define multiple render passes with shaders and input texture routing. ```typescript const configs: RenderPassConfig[] = [ { name: 'bgPass', shader: { vertex: bgVert, fragment: bgFrag } }, { name: 'blurPass', shader: { vertex: blurVert, fragment: blurFrag }, inputs: { u_prevPassTexture: 'bgPass' } }, { name: 'mainPass', shader: { vertex: mainVert, fragment: mainFrag }, inputs: { u_blurredBg: 'blurPass' }, outputToScreen: true } ]; ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/configuration.md Installs project dependencies using pnpm based on the lock file. ```bash pnpm install ``` -------------------------------- ### WebGPU Detection Examples Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/types.md Illustrates the structure of the WebGPU detection result for both successful and failed scenarios. ```typescript // Successful detection { supported: true, adapter: GPUAdapter, device: GPUDevice } // Failed detection { supported: false, reason: 'WebGPU API not available' } { supported: false, reason: 'No GPU adapter found' } ``` -------------------------------- ### LevaButton Usage Example with Handler Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-custom-components.md Provides a concrete example of using LevaButton, including defining the onClick handler function and passing it along with other props and children. ```typescript const handleExport = () => { exportPreset(controls, 'preset.json'); }; {lang['editor.export']} ``` -------------------------------- ### Example Environment Variables Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/configuration.md Illustrates potential environment variables for future configuration, such as API endpoints and feature flags. ```env # API endpoint for preset storage VITE_PRESET_API_URL=https://api.example.com/presets # Analytics/telemetry VITE_ANALYTICS_KEY=... # Feature flags VITE_ENABLE_WEBGPU=true VITE_ENABLE_PRESETS=true ``` -------------------------------- ### Example Preset JSON Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/types.md An example of a JSON object conforming to the PresetData structure, illustrating typical control values. This can be used for testing or as a template. ```json { "version": "1.0.0", "timestamp": "2026-06-02T10:30:15.123Z", "controls": { "refThickness": 25, "refFactor": 1.5, "refDispersion": 8, "blurRadius": 5, "shapeWidth": 250, "shapeHeight": 250, "bgType": 3, "tint": { "r": 255, "g": 255, "b": 255, "a": 0 } } } ``` -------------------------------- ### Check Node.js and npm/pnpm Versions Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/configuration.md Verifies that Node.js (LTS recommended) and npm or pnpm are installed and accessible in the environment. ```bash # Node.js version check (LTS recommended) node --version # Should be v18.x or later npm --version # Or use pnpm pnpm --version ``` -------------------------------- ### Example of RENAMED Requirement Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/openspec/AGENTS.md Illustrates how to format a RENAMED requirement, specifying the 'FROM' and 'TO' states. ```markdown ## RENAMED Requirements - FROM: `### Requirement: Login` - TO: `### Requirement: User Authentication` ``` -------------------------------- ### Backend-Agnostic Renderer Usage Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/types.md Example of instantiating either a WebGL2 or WebGPU renderer based on a condition. ```typescript let renderer: IMultiPassRenderer; if (useWebGPU) { renderer = new GPUMultiPassRenderer(canvas, configs, device); } else { renderer = new MultiPassRenderer(canvas, configs); } ``` -------------------------------- ### Preset File Format Example Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-controls.md Illustrates the JSON structure of an exported preset file, containing version, timestamp, and control values. ```json { "version": "1.0.0", "timestamp": "2026-06-02T10:30:00.000Z", "controls": { "refThickness": 20, "refFactor": 1.4, "bgType": 3, "shapeWidth": 250, ... } } ``` -------------------------------- ### Build for Production Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/README.md Builds the project for production deployment using pnpm. Ensure Node.js LTS and pnpm are installed. ```bash pnpm build ``` -------------------------------- ### Custom Component File Structure Example Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-custom-components.md Shows the typical file structure for a custom Leva component, including the main component file, an index export file, and optional SCSS module for styling. ```typescript src/components/ComponentName/ ├── ComponentName.tsx (Main component) ├── index.ts (Export barrel file) └── [ComponentName].module.scss (Styles, if needed) ``` ```typescript // index.ts export { LevaButton } from './LevaButton'; ``` -------------------------------- ### Texture Loading with ITextureHandle Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/types.md Example of loading a texture and storing it as an ITextureHandle, adapting to the detected backend (WebGL or WebGPU). ```typescript let bgTexture: ITextureHandle; if (backend === 'webgl') { const gl = canvas.getContext('webgl2'); bgTexture = (await loadTextureFromURL(gl, url)).texture; } else { const { device } = await detectWebGPU(); bgTexture = (await gpuLoadTextureFromURL(device, url)).texture; } ``` -------------------------------- ### Example of ADDED Requirement for Two-Factor Authentication Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/openspec/AGENTS.md Shows how to define a new requirement for Two-Factor Authentication, including a specific scenario. ```markdown ## ADDED Requirements ### Requirement: Two-Factor Authentication Users MUST provide a second factor during login. #### Scenario: OTP required - **WHEN** valid credentials are provided - **THEN** an OTP challenge is required ``` -------------------------------- ### Example of ADDED Requirement for OTP Email Notification Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/openspec/AGENTS.md Demonstrates defining a new requirement for OTP Email Notification. ```markdown ## ADDED Requirements ### Requirement: OTP Email Notification ... ``` -------------------------------- ### Styling Integration with Leva Theme Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-custom-components.md Example of how to integrate custom component styles with Leva's theming system by passing theme properties like sizes and spacing to the Leva component. ```typescript const levaGlobal = ( ); ``` -------------------------------- ### Monitor Uniforms with setUniforms Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/quick-reference.md Batch update uniforms using `setUniforms` for efficiency. This example sets resolution, device pixel ratio, and time. Check the browser console for shader compilation errors. ```typescript renderer.setUniforms({ u_resolution: [w, h], u_dpr: dpr, u_time: performance.now() }); // Check DevTools > Console for shader compilation errors ``` -------------------------------- ### Main Application Entry Point Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-app.md Sets up the React application by rendering the root component into the DOM. It initializes the app within a strict mode environment and loads global styles. ```typescript import React from 'react' import ReactDOM from 'react-dom/client' import App from './App.tsx' import './index.css' ReactDOM.createRoot(document.getElementById('root')!).render( , ) ``` -------------------------------- ### Build Project for Production Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/configuration.md Compiles and bundles the project for production deployment. ```bash # Build for production pnpm build ``` -------------------------------- ### Initialize OpenSpec Project Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/openspec/AGENTS.md Use this command to initialize a new OpenSpec project in the specified path. If no path is provided, it initializes in the current directory. ```bash openspec init [path] ``` -------------------------------- ### List Specifications Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/openspec/AGENTS.md Use this command to list all available specifications. This is useful for understanding the existing capabilities and schemas within the project. ```bash openspec list --specs ``` -------------------------------- ### TextureLoadResult Usage Example Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/types.md Demonstrates using TextureLoadResult with specific texture types for both WebGL and WebGPU. ```typescript const result: TextureLoadResult = await loadTextureFromURL(gl, url); const gpuResult: TextureLoadResult = await gpuLoadTextureFromURL(device, url); ``` -------------------------------- ### Handle Renderer Initialization with Fallback Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/errors-and-exceptions.md This snippet demonstrates a robust renderer initialization process. It attempts to use WebGPU if supported and available, falling back to WebGL2 if WebGPU initialization fails or is not supported. Errors during the entire initialization are caught and logged. ```typescript try { let renderer: IMultiPassRenderer; if (webgpuSupported && device) { try { renderer = new GPUMultiPassRenderer(canvas, configs, device); } catch (err) { console.error('WebGPU init failed, falling back to WebGL:', err); renderer = new MultiPassRenderer(canvas, configs); } } else { renderer = new MultiPassRenderer(canvas, configs); } } catch (err) { console.error('Renderer initialization failed:', err); // Show error UI } ``` -------------------------------- ### Initialize GPUMultiPassRenderer Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-gpu-multipass-renderer.md Instantiate the GPUMultiPassRenderer with a canvas, render pass configurations, and a WebGPU device. Ensure WebGPU is detected and available. ```typescript import { GPUMultiPassRenderer } from './utils/GPUUtils'; const { device } = await detectWebGPU(); const configs = [ { name: 'bgPass', shader: { vertex: wgslVertex, fragment: wgslBg } }, { name: 'mainPass', shader: { vertex: wgslVertex, fragment: wgslMain }, inputs: { u_blurredBg: 'hBlurPass' }, outputToScreen: true } ]; const renderer = new GPUMultiPassRenderer(canvas, configs, device); ``` -------------------------------- ### isUzbekLanguage Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-utilities.md Detects if the browser's current language setting is Uzbek. It checks if the `navigator.language` property starts with 'uz'. ```APIDOC ## isUzbekLanguage ### Description Detects if the browser's current language setting is Uzbek. It checks if the `navigator.language` property starts with 'uz'. ### Signature ```typescript export function isUzbekLanguage(): boolean ``` ### Returns - **boolean** — `true` if the browser language is Uzbek, `false` otherwise. ### Usage ```typescript if (isUzbekLanguage()) { setLanguage('uz-UZ'); } ``` ``` -------------------------------- ### isChineseLanguage Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-utilities.md Detects if the browser's current language setting is Chinese. It checks if the `navigator.language` property starts with 'zh'. ```APIDOC ## isChineseLanguage ### Description Detects if the browser's current language setting is Chinese. It checks if the `navigator.language` property starts with 'zh'. ### Signature ```typescript export function isChineseLanguage(): boolean ``` ### Returns - **boolean** — `true` if the browser language is Chinese, `false` otherwise. ### Usage ```typescript if (isChineseLanguage()) { defaultLanguage = 'zh-CN'; } ``` ``` -------------------------------- ### Initialize and Render with GPUMultiPassRenderer (WebGPU) Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/quick-reference.md Instantiate the GPUMultiPassRenderer for WebGPU, set uniforms, execute render passes, and clean up resources. It shares the same interface as MultiPassRenderer. ```typescript import { GPUMultiPassRenderer } from './utils/GPUUtils'; const renderer = new GPUMultiPassRenderer(canvas, configs, device); renderer.setUniforms({ u_resolution: [w, h] }); renderer.render({ bgPass: { u_bgType: 0 } }); renderer.dispose(); ``` -------------------------------- ### Backend Switch Flow for Renderers Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-app.md Illustrates the sequence of events when switching between WebGL2 and WebGPU rendering backends. A remount is necessary because a canvas cannot support both contexts simultaneously. ```text User selects WebGPU in controls ↓ onRendererChange() callback ↓ setRendererBackend('webgpu') ↓ setCanvasKey(k => k + 1) // Remount canvas ↓ Canvas destroyed, new canvas created ↓ useEffect triggered by canvasKey ↓ New renderer initialized ``` -------------------------------- ### Detect Uzbek Language Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-utilities.md Detects if the browser's current language setting is Uzbek. Returns true if the navigator.language starts with 'uz'. ```typescript export function isUzbekLanguage(): boolean ``` ```typescript if (isUzbekLanguage()) { setLanguage('uz-UZ'); } ``` -------------------------------- ### Detect Chinese Language Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-utilities.md Detects if the browser's current language setting is Chinese. Returns true if the navigator.language starts with 'zh'. ```typescript export function isChineseLanguage(): boolean ``` ```typescript if (isChineseLanguage()) { defaultLanguage = 'zh-CN'; } ``` -------------------------------- ### detectWebGPU Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-utilities.md Asynchronously detects WebGPU support and acquires a GPU device. It checks for navigator.gpu, requests an adapter and device, and caches the result. If WebGPU is unavailable, it provides a reason. ```APIDOC ## detectWebGPU ### Description Asynchronously detects WebGPU support and acquires a GPU device. It checks for `navigator.gpu`, requests an adapter and device, and caches the result. If WebGPU is unavailable, it provides a reason. ### Signature ```typescript export async function detectWebGPU(): Promise ``` ### Returns - **WebGPUDetectResult** — An object containing detection results. ### Response Example ```json { "supported": true, "adapter": { /* GPUAdapter object */ }, "device": { /* GPUDevice object */ } } ``` ### Error Handling If WebGPU is not supported, `supported` will be false and `reason` will contain an explanation. ### Usage ```typescript const result = await detectWebGPU(); if (result.supported && result.device) { // Initialize renderer with WebGPU device } else { console.log('WebGPU unavailable:', result.reason); // Fall back to WebGL2 } ``` ``` -------------------------------- ### ResizeWindowCtrlRefType Interface Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/types.md Specifies the reference type for the ResizableWindow component, exposing methods to get its current size and set its position offset. ```typescript interface ResizeWindowCtrlRefType { getSize(): { width: number; height: number }; setMoveOffset(offset: { x: number; y: number }): void; } ``` -------------------------------- ### Get ShaderProgram Attribute Location Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-shader-and-pass.md Retrieves the location index for a given vertex attribute name. Used to enable vertex attribute arrays. ```typescript const posLocation = program.getAttributeLocation('a_position'); gl.enableVertexAttribArray(posLocation); ``` -------------------------------- ### GPUMultiPassRenderer Constructor Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-gpu-multipass-renderer.md Initializes the GPUMultiPassRenderer with a canvas, render pass configurations, and a WebGPU device. ```APIDOC ## Constructor GPUMultiPassRenderer ### Description Initializes the GPUMultiPassRenderer with a canvas, render pass configurations, and a WebGPU device. ### Parameters #### Path Parameters - **canvas** (HTMLCanvasElement) - Required - Target canvas element - **configs** (RenderPassConfig[]) - Required - Array of render pass configurations - **device** (GPUDevice) - Required - Active WebGPU device ### Throws - Error if WebGPU context is unavailable on canvas ### Usage ```typescript import { GPUMultiPassRenderer } from './utils/GPUUtils'; const { device } = await detectWebGPU(); const configs = [ { name: 'bgPass', shader: { vertex: wgslVertex, fragment: wgslBg } }, { name: 'mainPass', shader: { vertex: wgslVertex, fragment: wgslMain }, inputs: { u_blurredBg: 'hBlurPass' }, outputToScreen: true } ]; const renderer = new GPUMultiPassRenderer(canvas, configs, device); ``` ``` -------------------------------- ### OpenSpec Scenario Formatting - Incorrect Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/openspec/AGENTS.md Examples of incorrect markdown formatting for scenarios, highlighting what to avoid (e.g., bullets, bolding, wrong header levels). ```markdown - **Scenario: User login** ❌ **Scenario**: User login ❌ ### Scenario: User login ❌ ``` -------------------------------- ### Create Empty WebGL2 Texture Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-texture-utils.md Creates an empty WebGL2 texture that can be filled later, for example, with video frames. It's configured with specific filters and wrapping modes. ```typescript export function createEmptyTexture( gl: WebGL2RenderingContext ): WebGLTexture ``` ```typescript const texture = createEmptyTexture(gl); // Later: update with video frame updateVideoTexture(gl, texture, videoElement); ``` -------------------------------- ### Initialize and Render with MultiPassRenderer (WebGL2) Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/quick-reference.md Instantiate the MultiPassRenderer for WebGL2, set uniforms, execute render passes, and clean up resources. ```typescript import { MultiPassRenderer } from './utils/GLUtils'; const renderer = new MultiPassRenderer(canvas, configs); renderer.setUniforms({ u_resolution: [w, h] }); renderer.render({ bgPass: { u_bgType: 0 } }); renderer.dispose(); ``` -------------------------------- ### Initialize Renderer with WebGPU Fallback Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/quick-reference.md Initializes the multi-pass renderer, attempting to use WebGPU and falling back to WebGL2 if initialization fails or WebGPU is not supported. ```typescript let renderer: IMultiPassRenderer; const result = await detectWebGPU(); if (result.supported && result.device) { try { renderer = new GPUMultiPassRenderer(canvas, configs, result.device); } catch (e) { console.error('WebGPU init failed, using WebGL2:', e); renderer = new MultiPassRenderer(canvas, configs); } } else { renderer = new MultiPassRenderer(canvas, configs); } ``` -------------------------------- ### Get Cached WebGPU Detection Result Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-utilities.md Retrieves the cached WebGPU detection result without performing a new detection. Use this to quickly check if WebGPU is already available. ```typescript export function getWebGPUDetectResult(): WebGPUDetectResult | null ``` ```typescript const result = getWebGPUDetectResult(); if (result && result.supported) { // WebGPU is available } ``` -------------------------------- ### Detect WebGPU Support and Acquire Device Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-utilities.md Asynchronously detects WebGPU support and acquires a device. It checks for navigator.gpu, requests an adapter and device, and caches the result. Use this when you need to initialize WebGPU rendering. ```typescript export async function detectWebGPU(): Promise ``` ```typescript const result = await detectWebGPU(); if (result.supported && result.device) { const renderer = new GPUMultiPassRenderer(canvas, configs, result.device); } else { console.log('WebGPU unavailable:', result.reason); // Fall back to WebGL2 } ``` -------------------------------- ### render Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-gpu-multipass-renderer.md Executes all render passes in sequence with WebGPU command encoding. ```APIDOC ## render ### Description Execute all render passes in sequence with WebGPU command encoding. ### Parameters #### Path Parameters - **passUniforms** (Record[] | Record>) - Optional - Pass-specific uniforms. Can be array (indexed by pass order) or object (keyed by pass name). ### Behavior - Creates command encoder and render passes - Merges global uniforms with per-pass uniforms - Resolves input textures from previous passes - Automatically builds appropriate bind groups based on pass type (bg, blur, main) - Submits command buffer to GPU queue ### Array Format Usage ```typescript renderer.render([ { u_bgType: 0 }, { u_prevPassTexture: texture1 }, { u_prevPassTexture: texture2 }, { u_blurredBg: texture3 } ]); ``` ### Object Format Usage ```typescript renderer.render({ bgPass: { u_bgType: 2 }, mainPass: { u_tint: [1, 1, 1, 0.5] } }); ``` ``` -------------------------------- ### useLevaControls Hook Usage Example Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-controls.md Demonstrates how to use the useLevaControls hook in a React component. It shows how to pass custom render components and renderer options, and how to destructure the returned controls and API. ```typescript const { controls, controlsAPI, lang, levaGlobal } = useLevaControls({ containerRender: { bgType: ({ value, setValue }) => (
setValue(value + 1)}>Select Background
) }, rendererOptions: { webgpuSupported: true, onRendererChange: (backend) => console.log('Switched to', backend) } }); ``` -------------------------------- ### Import and Validate Preset Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/quick-reference.md Import a preset configuration file and log its version, timestamp, and available control keys. This helps in validating the preset's structure and content. ```typescript const preset = await importPreset(file); console.log('Preset version:', preset.version); console.log('Preset timestamp:', preset.timestamp); console.log('Control keys:', Object.keys(preset.controls)); ``` -------------------------------- ### OpenSpec Scenario Formatting - Correct Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/openspec/AGENTS.md Correct markdown formatting for scenarios within spec files, using '####' headers and specific WHEN/THEN keywords. ```markdown #### Scenario: User login success - **WHEN** valid credentials provided - **THEN** return JWT token ``` -------------------------------- ### Get Output Texture from a Pass Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-shader-and-pass.md Retrieves the color texture rendered by a pass. Use this to pass the output of one pass as input to another. Returns null if the pass outputs directly to the screen. ```typescript const outputTexture = pass.getOutputTexture(); if (outputTexture) { nextPass.render({ u_prevPassTexture: outputTexture }); } ``` -------------------------------- ### Create RenderPass Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-shader-and-pass.md Initializes a RenderPass. It automatically sets up a ShaderProgram, framebuffer (if not rendering to screen), and a VAO for a fullscreen quad. ```typescript import { RenderPass } from './utils/GLUtils'; const pass = new RenderPass(gl, shaderSource, false); // Renders to framebuffer by default ``` -------------------------------- ### Project Structure Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/architecture-overview.md Illustrates the directory layout of the Liquid Glass Studio project, highlighting key files and directories for components, shaders, utilities, and assets. ```tree src/ ├── App.tsx # Main React component, renderer orchestration ├── Controls.tsx # Leva control panel management ├── main.tsx # React app entry point ├── components/ │ ├── LevaButton/ # Custom button component │ ├── LevaCheckButtons/ # Custom button group component │ ├── LevaContainer/ # Custom container component │ ├── LevaImageUpload/ # Image upload component (unused) │ ├── LevaVectorNew/ # Custom vector input component │ ├── PresetControls/ # Preset import/export UI │ └── ResizableWindow/ # Draggable window wrapper ├── shaders/ # GLSL 3.00 ES shaders │ ├── vertex.glsl # Fullscreen quad vertex shader │ ├── fragment-bg.glsl # Background rendering shader │ ├── fragment-main.glsl # Main glass effect shader │ ├── fragment-bg-vblur.glsl # Vertical blur shader │ └── fragment-bg-hblur.glsl # Horizontal blur shader ├── shaders-wgsl/ # WGSL shaders (WebGPU) │ ├── vertex.wgsl │ ├── fragment-bg.wgsl │ ├── fragment-main.wgsl │ ├── fragment-bg-vblur.wgsl │ └── fragment-bg-hblur.wgsl ├── utils/ │ ├── GLUtils.ts # WebGL2 renderer & shader utilities │ ├── GPUUtils.ts # WebGPU renderer │ ├── RendererInterface.ts # Common types & interfaces │ ├── gpuDetect.ts # WebGPU capability detection │ ├── index.ts # Utility function exports │ ├── languages.ts # Localization strings │ ├── presetUtils.ts # Preset save/load │ └── useResizeObserver.ts # React resize hook └── assets/ # Images and videos ``` -------------------------------- ### Load Texture from URL (WebGPU) Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/quick-reference.md Load an image texture from a URL for use with WebGPU. Also demonstrates creating an empty texture for video and updating it, which may return a new texture. ```typescript import { gpuLoadTextureFromURL, gpuCreateEmptyTexture, gpuUpdateVideoTexture } from './utils/GPUUtils'; // Load image const { texture, ratio } = await gpuLoadTextureFromURL(device, imageUrl); // Create empty for video const videoTexture = gpuCreateEmptyTexture(device, width, height); // Update video each frame const info = await gpuUpdateVideoTexture(device, videoTexture, videoElement); if (info) { videoTexture = info.texture; // May be new texture } ``` -------------------------------- ### Detect and Use WebGPU Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/quick-reference.md Asynchronously detect if WebGPU is supported. If supported, initialize the renderer with the detected device; otherwise, log the reason and fall back to WebGL2. Cached results can also be retrieved. ```typescript import { detectWebGPU, getWebGPUDetectResult } from './utils/gpuDetect'; // Async detection const result = await detectWebGPU(); if (result.supported && result.device) { // Use WebGPU renderer = new GPUMultiPassRenderer(canvas, configs, result.device); } else { console.log(result.reason); // Why not supported // Fall back to WebGL2 } // Or get cached result const cachedResult = getWebGPUDetectResult(); ``` -------------------------------- ### Import Preset Configuration Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/INDEX.md Loads a saved configuration from a JSON object. This restores the application's settings to a previous state. ```typescript import { importPreset } from "./utils/presetUtils"; const presetJson = '{"param1": 10, "param2": "value"}'; // Example preset data const presetData = JSON.parse(presetJson); importPreset(presetData); console.log("Preset imported successfully."); ``` -------------------------------- ### Build Scripts for Liquid Glass Studio Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/configuration.md Defines the npm scripts for building, developing, linting, and previewing the Liquid Glass Studio project. ```json { "scripts": { "dev": "vite", "build": "tsc -b && vite build", "lint": "eslint .", "preview": "vite preview" } } ``` -------------------------------- ### Texture Loading Lifecycle Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-app.md Outlines the process from setting a background texture URL to its display in the shader. This involves asynchronous loading and updating readiness flags. ```text bgTextureUrl set (user selects background) ↓ Render loop detects change ↓ Load texture (async) ↓ bgTextureReady = true ↓ Shader receives texture ↓ Display updates ``` -------------------------------- ### Key Imports: Types Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/quick-reference.md Imports type definitions for renderers, textures, and presets, including WebGPU detection results. ```typescript import type { IMultiPassRenderer, RenderPassConfig, ITextureHandle, TextureLoadResult } from './utils/RendererInterface'; import type { WebGPUDetectResult } from './utils/gpuDetect'; import type { PresetData } from './utils/presetUtils'; ``` -------------------------------- ### LevaButton Component Usage Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-custom-components.md Demonstrates how to import and use the LevaButton component for triggering actions, including passing an onClick handler and children for content. ```typescript // Import and usage in PresetControls.tsx import { LevaButton } from './components/LevaButton/LevaButton'; Export ``` -------------------------------- ### gpuCreateEmptyTexture Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-texture-utils.md Create an empty WebGPU texture for later filling. Allows specifying initial width and height, and the texture is created with texture binding and copy usage flags. ```APIDOC ## gpuCreateEmptyTexture ### Description Create an empty WebGPU texture for later filling. Allows specifying initial width and height, and the texture is created with texture binding and copy usage flags. ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Parameters - **device** (GPUDevice) - Required - WebGPU device - **width** (number) - Optional - Initial width (default: 1) - **height** (number) - Optional - Initial height (default: 1) ### Response #### Success Response (200) - **texture** (GPUTexture) - GPUTexture with texture binding and copy usage ### Request Example ```typescript let videoTexture = gpuCreateEmptyTexture(device, videoWidth, videoHeight); ``` ### Response Example ```json { "texture": "GPUTexture object" } ``` ``` -------------------------------- ### Initialize Leva Controls Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-app.md Initializes the Leva control panel, managing renderer options and custom container rendering. It returns control values, language settings, and an API for updating controls. ```typescript const { controls, lang, langName, levaGlobal, controlsAPI } = useLevaControls({ rendererOptions: { webgpuSupported: webgpuDetect?.supported ?? false, webgpuUnavailableReason: webgpuDetect?.reason, onRendererChange: (backend) => { setRendererBackend(backend); setCanvasKey((k) => k + 1); }, }, containerRender: { bgType: ({ value, setValue }) => ( // Custom background selection UI ), }, }); ``` -------------------------------- ### OpenSpec CLI Essentials Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/openspec/AGENTS.md Commonly used OpenSpec CLI commands for listing changes, viewing details, validating, and archiving. ```bash openspec list # What's in progress? ``` ```bash openspec show [item] # View details ``` ```bash openspec validate --strict # Is it correct? ``` ```bash openspec archive [--yes|-y] # Mark complete (add --yes for automation) ``` -------------------------------- ### Load Background Texture with Fallback Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/errors-and-exceptions.md Loads a texture for the background, attempting WebGL2 or WebGPU based on backend availability. Logs errors and returns null on failure. ```typescript async function loadBackgroundTexture(url: string) { try { if (backend === 'webgl') { const gl = canvas.getContext('webgl2'); const { texture, ratio } = await loadTextureFromURL(gl, url); return { texture, ratio }; } else { const { device } = await detectWebGPU(); return await gpuLoadTextureFromURL(device, url); } } catch (err) { console.error('Texture load failed:', url, err); // Use placeholder or fallback return null; } } ``` -------------------------------- ### Component Integration Pattern in useLevaControls Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-custom-components.md Illustrates the common pattern for integrating custom Leva components within the useLevaControls hook, showing how components return Leva configurations. ```typescript const [controls, controlsAPI] = useControls(() => ({ 'basicSettings': folder({ renderer: LevaCheckButtons({...}), // Returns Leva config language: LevaCheckButtons({...}), }), shadowPosition: LevaVectorNew({...}), // Returns Leva config bgType: LevaContainer({...}), // Returns Leva config // ... more controls })); ``` -------------------------------- ### Initialize MultiPassRenderer Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-multipass-renderer.md Instantiate the MultiPassRenderer with a target canvas and an array of render pass configurations. Ensure WebGL2 context and the EXT_color_buffer_float extension are available. ```typescript import { MultiPassRenderer } from './utils/GLUtils'; const configs = [ { name: 'bgPass', shader: { vertex: vertShader, fragment: fragShader } }, { name: 'blurPass', shader: { vertex: vertShader, fragment: blurShader }, inputs: { u_prevPassTexture: 'bgPass' } }, { name: 'mainPass', shader: { vertex: vertShader, fragment: mainShader }, inputs: { u_blurredBg: 'blurPass' }, outputToScreen: true } ]; const renderer = new MultiPassRenderer(canvas, configs); ``` -------------------------------- ### Handle Video Not Ready Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/errors-and-exceptions.md Check the return value of `updateVideoTexture` to determine if the video has loaded enough data. If it returns a falsy value, the video is still loading and should be retried. ```typescript const result = updateVideoTexture(gl, texture, video); if (result) { renderer.setUniform('u_bgTextureRatio', result.ratio); } else { // Video still loading, try again next frame } ``` -------------------------------- ### Handle WebGPU Context Unavailable (TypeScript) Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/errors-and-exceptions.md Catches errors during WebGPU context initialization, allowing for a fallback to the WebGL2 renderer if WebGPU is not available or fails to initialize. ```typescript try { renderer = new GPUMultiPassRenderer(canvas, configs, device); } catch (err) { console.error('WebGPU initialization failed:', err); // Fall back to WebGL2 } ``` -------------------------------- ### Interactive Show Command Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/openspec/AGENTS.md Running 'openspec show' without arguments will prompt the user to select which change or spec they want to view details for. ```bash openspec show ``` -------------------------------- ### Export and Import Presets Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/quick-reference.md Export the current control settings to a JSON file and import a preset file to apply settings. Includes basic error handling for import. ```typescript import { exportPreset, importPreset } from './utils/presetUtils'; // Export exportPreset(controls, 'my-preset.json'); // Import try { const preset = await importPreset(file); controlsAPI(preset.controls); } catch (err) { console.error('Import failed:', err.message); } ``` -------------------------------- ### Create WebGPU Renderer Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-app.md A useCallback hook that creates a WebGPU renderer. It utilizes the same pass configuration as the WebGL renderer but employs WGSL shaders for the GPU pipeline. ```typescript const createWebGPURenderer = useCallback((canvasEl: HTMLCanvasElement, device: GPUDevice) => { return new GPUMultiPassRenderer(canvasEl, [ { name: 'bgPass', shader: { vertex: WgslVertex, fragment: WgslFragBg } }, { name: 'vBlurPass', shader: { vertex: WgslVertex, fragment: WgslFragVblur }, inputs: { u_prevPassTexture: 'bgPass' } }, { name: 'hBlurPass', shader: { vertex: WgslVertex, fragment: WgslFragHblur }, inputs: { u_prevPassTexture: 'vBlurPass' } }, { name: 'mainPass', shader: { vertex: WgslVertex, fragment: WgslFragMain }, inputs: { u_blurredBg: 'hBlurPass', u_bg: 'bgPass' }, outputToScreen: true }, ], device); }, []); ``` -------------------------------- ### Backend Selection Logic Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/architecture-overview.md Selects the appropriate renderer (WebGL or WebGPU) based on the chosen backend and browser support. The canvas must be remounted when switching renderers due to context exclusivity. ```typescript const [rendererBackend, setRendererBackend] = useState<'webgl' | 'webgpu'>('webgl'); useEffect(() => { if (rendererBackend === 'webgpu' && webgpuDetect?.supported) { renderer = createWebGPURenderer(canvas, device); } else { renderer = createWebGLRenderer(canvas); } // Note: Canvas must be remounted (destroyed/recreated) when switching // because WebGL2 and WebGPU contexts are mutually exclusive }, [rendererBackend, canvasKey, webgpuDetect]); ``` -------------------------------- ### Key Imports: Utility Functions Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/quick-reference.md Imports various utility functions for tasks like Gaussian kernel computation, language detection, string capitalization, WebGPU detection, and preset management. ```typescript import { computeGaussianKernelByRadius, isChineseLanguage, isUzbekLanguage, capitalize } from './utils/index'; import { detectWebGPU, getWebGPUDetectResult } from './utils/gpuDetect'; import { exportPreset, importPreset } from './utils/presetUtils'; ``` -------------------------------- ### Load Texture from URL (WebGL2) Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/quick-reference.md Load an image texture from a URL for use with WebGL2. Also shows how to create an empty texture for video and update it. ```typescript import { loadTextureFromURL, createEmptyTexture, updateVideoTexture } from './utils/GLUtils'; // Load image const { texture, ratio } = await loadTextureFromURL(gl, imageUrl); // Create empty for video const videoTexture = createEmptyTexture(gl); // Update video each frame const info = updateVideoTexture(gl, videoTexture, videoElement); ``` -------------------------------- ### importPreset Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-controls.md Loads control settings from a JSON preset file. This function is essential for restoring previously saved states or applying new configurations. ```APIDOC ## importPreset ### Description Loads control settings from a JSON preset file. This function is essential for restoring previously saved states or applying new configurations. ### Method ```typescript export function importPreset(file: File): Promise ``` ### Parameters #### Path Parameters - **file** (File) - Required - Preset JSON file ### Response #### Success Response - **PresetData** (Promise) - Promise resolving to PresetData object #### Error Handling - Promise rejects with descriptive error if: - File is not valid JSON - JSON lacks `version` or `controls` fields - File read fails ### Usage ```typescript const handleImport = async (file: File) => { try { const preset = await importPreset(file); controlsAPI(preset.controls); } catch (err) { alert(`Import failed: ${err.message}`); } }; ``` ``` -------------------------------- ### RenderPass Constructor Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-shader-and-pass.md Initializes a RenderPass, setting up a shader program and optionally a framebuffer for rendering. By default, it renders to an internal framebuffer unless `outputToScreen` is set to true. ```APIDOC ## RenderPass Constructor ### Description Manages a single render pass with framebuffer, shader program, and VAO. Initializes a RenderPass, setting up a shader program and optionally a framebuffer for rendering. By default, it renders to an internal framebuffer unless `outputToScreen` is set to true. ### Parameters - **gl** (WebGL2RenderingContext) - WebGL2 rendering context - **shaderSource** (ShaderSource) - Vertex and fragment shader source - **outputToScreen** (boolean) - If true, renders to screen; if false, to framebuffer (default: false) ### Automatic Setup - Creates and configures ShaderProgram - Creates framebuffer with RGBA16F color and DEPTH_COMPONENT24 depth if not outputToScreen - Creates VAO with fullscreen quad geometry ### Usage ```typescript import { RenderPass } from './utils/GLUtils'; const pass = new RenderPass(gl, shaderSource, false); // Renders to framebuffer by default ``` ``` -------------------------------- ### Import Preset with Error Handling Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/errors-and-exceptions.md Handles the import of a preset file, updating controls and showing success or failure alerts. Displays user-friendly error messages. ```typescript const handleImport = async (file: File) => { try { const preset = await importPreset(file); controlsAPI(preset.controls); alert('Preset loaded successfully'); } catch (err) { const errorMsg = err instanceof Error ? err.message : 'Unknown error'; alert(`Failed to import preset: ${errorMsg}`); } }; ``` -------------------------------- ### Detect WebGPU Support on Mount Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/api-reference-app.md Uses `useEffect` to detect WebGPU support and acquire the GPU device once when the component mounts. This ensures WebGPU capabilities are available if supported. ```typescript useEffect(() => { detectWebGPU().then(setWebgpuDetect); }, []); ``` -------------------------------- ### Dual-Backend Architecture Diagram Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/architecture-overview.md Illustrates the separation of concerns between the React layer, the rendering abstraction, and the underlying WebGL2 and WebGPU APIs. ```text ┌─────────────────────────────────────────────────┐ │ App.tsx (React Layer) │ │ - Canvas management, state, lifecycle │ │ - Texture loading and updates │ │ - Input handling (mouse, file upload) │ └────────────────────┬────────────────────────────┘ │ ┌──────────┴──────────┐ ↓ ↓ ┌──────────────┐ ┌──────────────┐ │ MultiPass │ │ GPUMulti │ │ Renderer │ │ PassRenderer │ │ (WebGL2) │ │ (WebGPU) │ └──────┬───────┘ └───────┬──────┘ ↓ ↓ ┌──────────────┐ ┌──────────────┐ │ ShaderProgram│ │ GPURender │ │ RenderPass │ │ PassObj │ │ FrameBuffer │ │ GPUFrameBuffer └──────┬───────┘ └───────┬──────┘ ↓ ↓ WebGL2 API WebGPU API ``` -------------------------------- ### Update All Dependencies Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/configuration.md Updates all project dependencies to their latest compatible versions using pnpm. ```bash pnpm update ``` -------------------------------- ### Display Change or Spec Details Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/openspec/AGENTS.md Use this command to display detailed information about a specific change or specification. Replace '[item]' with the change ID or spec ID. ```bash openspec show [item] ``` -------------------------------- ### WebGPUDetectResult Interface Source: https://github.com/iyinchao/liquid-glass-studio/blob/main/_autodocs/types.md Result of WebGPU capability detection, indicating support and providing adapter/device information if available. ```APIDOC ## WebGPUDetectResult Interface ### Description Result of WebGPU capability detection. ### Fields - **supported** (boolean) - Whether WebGPU is available and working - **reason** (string) - Human-readable error message if not supported - **adapter** (GPUAdapter) - GPU adapter (present if supported) - **device** (GPUDevice) - Active GPU device (present if supported) ### Examples ```typescript // Successful detection { supported: true, adapter: GPUAdapter, device: GPUDevice } // Failed detection { supported: false, reason: 'WebGPU API not available' } { supported: false, reason: 'No GPU adapter found' } ``` ```