### REGL Rendering Pipeline Setup and Render Loop Source: https://context7.com/rezmason/matrix/llms.txt Sets up a rendering pipeline using REGL, mapping effects to specific passes. It initializes the pipeline, waits for passes to be ready, and runs a render loop that handles viewport changes and executes the pipeline. ```javascript import makeRain from "./rainPass.js"; import makeBloomPass from "./bloomPass.js"; import makePalettePass from "./palettePass.js"; // Effect mapping const effects = { none: null, palette: makePalettePass, stripes: makeStripePass, pride: makeStripePass, image: makeImagePass, mirror: makeMirrorPass }; // Build pipeline const fullScreenQuad = makeFullScreenQuad(regl); const effectName = config.effect in effects ? config.effect : "palette"; const context = { regl, config }; const pipeline = makePipeline(context, [ makeRain, makeBloomPass, effects[effectName] ]); // Wait for all passes to be ready await Promise.all(pipeline.map((step) => step.ready)); // Render loop const tick = regl.frame(({ viewportWidth, viewportHeight }) => { // Handle viewport changes if (dimensions.width !== viewportWidth || dimensions.height !== viewportHeight) { dimensions.width = viewportWidth; dimensions.height = viewportHeight; for (const step of pipeline) { step.setSize(viewportWidth, viewportHeight); } } // Execute pipeline fullScreenQuad(() => { for (const step of pipeline) { step.execute(shouldRender); } drawToScreen(); }); }); ``` -------------------------------- ### Serve Project Locally with Python HTTP Server Source: https://github.com/rezmason/matrix/blob/master/README.md This command demonstrates how to serve the Matrix project locally using Python's built-in HTTP server. Navigate to the project directory in your terminal and execute the command. This is useful for testing and development without needing a full web server setup. ```bash cd /path/to/the/project python3 -m http.server ``` -------------------------------- ### Custom Palette URL Parameters Source: https://github.com/rezmason/matrix/blob/master/README.md This example demonstrates how to define a custom color palette for the Matrix effect using URL parameters. The `palette` parameter takes a comma-separated list of RGB values and percentages, defining the gradient or specific colors used in the rain. ```url https://rezmason.github.io/matrix/?palette=0.1,0,0.2,0,0.2,0.5,0,0.5,1,0.7,0,1 ``` -------------------------------- ### Custom Image Effect URL Parameters Source: https://github.com/rezmason/matrix/blob/master/README.md This example shows how to use a custom image as the background for the Matrix effect. The `effect=image` parameter enables image mode, and the `url` parameter specifies the URL of the image to be used. ```url https://rezmason.github.io/matrix/?effect=image&url=https://upload.wikimedia.org/wikipedia/commons/f/f5/EagleRock.jpg ``` -------------------------------- ### CMake Project Setup and SDK Path Configuration Source: https://github.com/rezmason/matrix/blob/master/playdate/matrix_c/CMakeLists.txt Configures the minimum CMake version, C standard, and dynamically determines the Playdate SDK path. It checks for the PLAYDATE_SDK_PATH environment variable or attempts to find the SDK path from the Playdate configuration file. If the SDK is not found, it throws a fatal error. ```cmake cmake_minimum_required(VERSION 3.14) set(CMAKE_C_STANDARD 11) set(ENVSDK $ENV{PLAYDATE_SDK_PATH}) if (NOT ${ENVSDK} STREQUAL "") # Convert path from Windows file(TO_CMAKE_PATH ${ENVSDK} SDK) else() execute_process( COMMAND bash -c "egrep '^\\s*SDKRoot' $HOME/.Playdate/config" COMMAND head -n 1 COMMAND cut -c9- OUTPUT_VARIABLE SDK OUTPUT_STRIP_TRAILING_WHITESPACE ) endif() if (NOT EXISTS ${SDK}) message(FATAL_ERROR "SDK Path not found; set ENV value PLAYDATE_SDK_PATH") return() endif() ``` -------------------------------- ### Custom Stripes Effect URL Parameters Source: https://github.com/rezmason/matrix/blob/master/README.md This example shows how to use URL parameters to create custom stripe colors in the Matrix effect. The `effect=stripes` parameter activates the stripe mode, and `stripeColors` accepts a comma-separated list of RGB values (0 or 1) to define the colors of the stripes. ```url https://rezmason.github.io/matrix/?effect=stripes&stripeColors=1,0,0,1,1,0,0,1,0 ``` -------------------------------- ### Basic REGL (WebGL) Setup for Matrix Effect (JavaScript) Source: https://context7.com/rezmason/matrix/llms.txt Initializes the Matrix digital rain effect using REGL (a WebGL library). It creates a canvas, appends it to the DOM, and sets up the renderer based on browser support for WebGPU or falling back to WebGL. It also configures necessary WebGL extensions for rendering. ```javascript import makeConfig from "./config.js"; // Create canvas element const canvas = document.createElement("canvas"); document.body.appendChild(canvas); // Initialize on page load document.body.onload = async () => { const urlParams = new URLSearchParams(window.location.search); const config = makeConfig(Object.fromEntries(urlParams.entries())); // Choose renderer based on support and configuration const useWebGPU = (await supportsWebGPU()) && ["webgpu"].includes(config.renderer?.toLowerCase()); const solution = import(`./${useWebGPU ? "webgpu" : "regl"}/main.js`); // Start the effect (await solution).default(canvas, config); }; // REGL initialization with required extensions const extensions = [ "OES_texture_half_float", "OES_texture_half_float_linear" ]; const regl = createREGL ({ canvas, pixelRatio: 1, extensions, optionalExtensions: ["EXT_color_buffer_half_float"] }); ``` -------------------------------- ### Customize Matrix Animation Behavior via URL Parameters Source: https://context7.com/rezmason/matrix/llms.txt Provides examples of customizing animation parameters through URL query strings. This includes adjusting fall speed, cycle speed, number of columns, raindrop length, slant angle, volumetric rendering, and performance settings like resolution and FPS. ```javascript // Slow, meditative rain const slowRain = "?fallSpeed=0.05&cycleSpeed=0.01&animationSpeed=0.5&raindropLength=1.2"; // Fast, chaotic effect const fastRain = "?fallSpeed=1.2&cycleSpeed=0.35&numColumns=120&raindropLength=0.3"; // Static, frozen code const frozen = "?fallSpeed=0&cycleSpeed=0&animationSpeed=0"; // Slanted rain at 45 degrees const slanted = "?slant=45&fallSpeed=0.8"; // 3D volumetric with depth const volumetric3D = "?volumetric=true&forwardSpeed=0.5&density=2&raindropLength=0.3"; // Low performance mode const lowPerf = "?resolution=0.5&bloomSize=0.2&bloomStrength=0.3&numColumns=40&fps=30"; ``` -------------------------------- ### WebGPU Rendering Pipeline Initialization and Loop Source: https://context7.com/rezmason/matrix/llms.txt Initializes the WebGPU device, creates a time buffer for animations, and sets up a rendering pipeline. The render loop controls frame rate and submits command encoders for rendering. ```javascript // WebGPU initialization const canvasFormat = navigator.gpu.getPreferredCanvasFormat(); const adapter = await navigator.gpu.requestAdapter(); const device = await adapter.requestDevice(); const canvasContext = canvas.getContext("webgpu"); canvasContext.configure({ device, format: canvasFormat, alphaMode: "opaque", usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_DST }); // Create time buffer for animations const timeUniforms = structs.from(`struct Time { seconds : f32, frames : i32, };`).Time; const timeBuffer = makeUniformBuffer(device, timeUniforms); // Build rendering pipeline const context = { config, device, canvasContext, timeBuffer, canvasFormat }; const pipeline = await makePipeline(context, [ makeRain, makeBloomPass, makePalettePass, makeEndPass ]); // Render loop with frame rate control const targetFrameTimeMilliseconds = 1000 / config.fps; let frames = 0; const renderLoop = (now) => { const shouldRender = config.fps >= 60 || now - last >= targetFrameTimeMilliseconds; if (shouldRender) { device.queue.writeBuffer(timeBuffer, 0, timeUniforms.toBuffer({ seconds: now / 1000, frames })); frames++; const encoder = device.createCommandEncoder(); pipeline.run(encoder, shouldRender); device.queue.submit([encoder.finish()]); } if (!config.once) { requestAnimationFrame(renderLoop); } }; requestAnimationFrame(renderLoop); ``` -------------------------------- ### Camera Integration for Mirror Effects (WebGPU and REGL) Source: https://context7.com/rezmason/matrix/llms.txt Sets up webcam input using `getUserMedia` and integrates the camera feed into both WebGPU and REGL rendering pipelines. It handles camera initialization, canvas drawing, and texture updates for each API. ```javascript import { setupCamera, cameraCanvas, cameraAspectRatio } from "./camera.js"; // Initialize camera when needed if (config.useCamera) { await setupCamera(); } // Camera initialization with getUserMedia const setupCamera = async () => { try { const stream = await navigator.mediaDevices.getUserMedia({ video: { width: { min: 800, ideal: 1280 }, frameRate: { ideal: 60 } }, audio: false }); const videoTrack = stream.getVideoTracks()[0]; const { width, height } = videoTrack.getSettings(); video.width = width; video.height = height; cameraCanvas.width = width; cameraCanvas.height = height; cameraAspectRatio = width / height; video.srcObject = stream; video.play(); // Continuously draw video to canvas const drawToCanvas = () => { requestAnimationFrame(drawToCanvas); context.drawImage(video, 0, 0); }; drawToCanvas(); } catch (e) { console.warn(`Camera not initialized: ${e}`); } }; // Use camera texture in REGL const cameraTex = regl.texture(cameraCanvas); // Update camera texture each frame if (config.useCamera) { cameraTex(cameraCanvas); } // Use camera texture in WebGPU const cameraTex = device.createTexture({ size: cameraSize, format: "rgba8unorm", usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT }); // Copy camera data each frame if (config.useCamera) { device.queue.copyExternalImageToTexture( { source: cameraCanvas }, { texture: cameraTex }, cameraSize ); } ``` -------------------------------- ### Create Custom Color Schemes via URL Parameters Source: https://context7.com/rezmason/matrix/llms.txt Demonstrates how to define custom color schemes using URL parameters. This includes creating effects like stripes with specified colors and gradients (RGB or HSL) with defined stops and positions. ```javascript // Custom Pride flag effect via URL const url = "?effect=stripes&stripeColors=1,0,0,1,1,0,0,1,0,0,0,1"; // Creates vertical stripes: red, yellow, blue // Custom gradient palette const gradientURL = "?palette=0.1,0,0.2,0,0.2,0.5,0,0.5,1,0.7,0,1"; // RGB format: (R,G,B,position) for each stop // Stop 1: RGB(0.1,0,0.2) at position 0 // Stop 2: RGB(0.2,0.5,0) at position 0.5 // Stop 3: RGB(1,0.7,0) at position 1 // Custom HSL palette for warmer tones const hslURL = "?paletteHSL=0.1,0.8,0.3,0,0.05,1.0,0.5,0.5,0.0,0.9,0.7,1.0"; ``` -------------------------------- ### Color Specification Helpers (JavaScript) Source: https://context7.com/rezmason/matrix/llms.txt Provides utility functions (`hsl`, `rgb`) for defining colors in HSL and RGB color spaces, returning structured color objects. It also demonstrates the usage of an external `colorToRGB` function to convert HSL colors to normalized RGB values for rendering purposes. ```javascript // HSL color definition const hsl = (...values) => ({ space: "hsl", values }); const myColor = hsl(0.242, 1, 0.73); // { space: "hsl", values: [0.242, 1, 0.73] } // RGB color definition const rgb = (...values) => ({ space: "rgb", values }); const myRGBColor = rgb(0, 255, 128); // { space: "rgb", values: [0, 255, 128] } // Convert HSL to RGB for rendering import colorToRGB from "./colorToRGB.js"; const rgbValues = colorToRGB({ space: "hsl", values: [0.3, 0.9, 0.7] }); // Returns: [0.63, 0.945, 0.135] (normalized RGB) ``` -------------------------------- ### Parse URL Parameters for Matrix Configuration (JavaScript) Source: https://context7.com/rezmason/matrix/llms.txt Parses URL search parameters to dynamically create a configuration object for the Matrix effect. It allows customization of various aspects like version, number of columns, and fall speed. The output is a configuration object, and it depends on the `makeConfig` function and `URLSearchParams`. ```javascript const urlParams = new URLSearchParams(window.location.search); const config = makeConfig(Object.fromEntries(urlParams.entries())); // Example URL with parameters: // https://example.com/matrix/?version=resurrections&numColumns=100&fallSpeed=0.5&effect=pride // Configuration structure returned: // { // version: "resurrections", // font: "resurrections", // numColumns: 100, // fallSpeed: 0.5, // effect: "pride", // animationSpeed: 1, // bloomStrength: 0.7, // bloomSize: 0.4, // volumetric: false, // resolution: 0.75, // fps: 60, // palette: [ // { color: { space: "hsl", values: [0.3, 0.9, 0.0] }, at: 0.0 }, // { color: { space: "hsl", values: [0.3, 0.9, 0.7] }, at: 0.7 } // ], // // ... additional configuration properties // } ``` -------------------------------- ### Detect SwiftShader and Warn User (JavaScript) Source: https://context7.com/rezmason/matrix/llms.txt Checks if the WebGL renderer is SwiftShader (software rendering) and displays a warning to the user if hardware acceleration is disabled and warnings are not suppressed. It dynamically creates a notice element with educational information and links. ```javascript const isRunningSwiftShader = () => { const gl = document.createElement("canvas").getContext("webgl"); const debugInfo = gl.getExtension("WEBGL_debug_renderer_info"); const renderer = gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL); return renderer.toLowerCase().includes("swiftshader"); }; // Display warning to user if running in software mode if (isRunningSwiftShader() && !config.suppressWarnings) { const notice = document.createElement("notice"); notice.innerHTML = `
Wake up, Neo... you've got hardware acceleration disabled.
This project will still run, but at a low framerate.
Free me