UNPKG

slime-simulation

Version:

Interactive WebGL slime simulation with PBR rendering

288 lines (241 loc) 9.04 kB
# Slime Simulation ![slime](https://github.com/user-attachments/assets/443565d5-e0fa-45f3-b3f4-2b22f83392d6) A WebGL slime simulation that creates an interactive, fluid-like background effect with physically-based rendering (PBR). ## Installation ```bash npm install slime-simulation ``` ## Basic Usage ### Using with NPM/Module Bundler ```javascript import { SlimeSimulation } from 'slime-simulation'; const container = document.getElementById('container'); const sim = new SlimeSimulation(container, { baseResolution: 256 }); ``` ### Using via CDN ```html <!DOCTYPE html> <html> <head> <style> body { margin: 0; } #container { width: 100vw; height: 100vh; position: relative; } </style> </head> <body> <div id="container"></div> <!-- Required dependencies --> <script src="https://unpkg.com/three@0.158/build/three.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/lil-gui@0.19"></script> <!-- Slime Simulation --> <script src="dist/slime-simulation.js"></script> <script> const container = document.getElementById('container'); const sim = new SlimeSimulationLib.SlimeSimulation(container, { baseResolution: 256, showGui: true }); </script> </body> </html> ``` ## Configuration ### Constructor Options | Option | Default | Description | |--------|---------|-------------| | baseResolution | 128 | Base resolution (higher = better quality but slower) | | stretchFactor | 1.0 | Adjust resolution aspect ratio | | showGui | false | Show/hide control panel | | imagePath | null | Optional background image path (will load asynchronously) | | preset | 'default' | Name of preset to use | | params | {} | Override any simulation parameters (see Parameters section) | ### Available Presets - `default`: Standard liquid metal effect with purple base - `purple`: High contrast purple with red accents - `emerald`: Green, crystalline effect - `glass`: Transparent glass-like effect (works best with background image) ### Simulation Parameters All parameters can be updated using `updateSettings()`: ```javascript sim.updateSettings({ // Simulation uNoiseFactor: 0.005, // 0.0-0.1 uBirthRate: 0.9, // 0.0-1.0 uDeathRate: 0.6, // 0.0-1.0 uSustainRate: 0.985, // 0.0-1.0 uSpeed: 0.1, // 0.0-1.0 uSampleRadius: 4.0, // 0-15 uGrowthTarget: 10.0, // 0.0-100.0 uMouseMass: 0.6, // 0.2-1.0 uMouseRadius: 0.05, // 0.01-0.2 uGaussianWeight: 8.0, // 4-20 // Visual uBaseColor: new THREE.Vector3(0.1, 0.01, 0.8), uSecondaryColor: new THREE.Vector4(0.0, 0.0, 0.0, 0.0), uSpecularColor: new THREE.Vector3(0.725, 0.725, 0.725), uRoughness: 0.2, // 0.05-0.95 uMetalness: 0.0, // 0-1 uToneMappingDenominator: 2.2, // 1.8-2.4 uLightPosZ: 2.0, // 1-3 uHeightMultiplier: 1.0, // 0.5-3 uNormalMultiplier: 2.0, // 1-8 uNormalZComponent: 1.0, // 0.2-1.5 // Effects uGlassEffect: false, uShowImage: true, uSmoothNormals: true, uSpotlightDampening: true }); ``` ## API ### Methods #### updateSettings(settings) Update simulation parameters: ```javascript sim.updateSettings({ // Simulation parameters uNoiseFactor: 0.005, // Amount of noise/randomness uBirthRate: 0.9, // Rate at which new cells appear uDeathRate: 0.6, // Rate at which cells die uSustainRate: 0.985, // How long cells persist uSpeed: 0.1, // Overall simulation speed uMouseMass: 0.6, // Strength of mouse interaction uMouseRadius: 0.05, // Size of mouse influence // Visual parameters uBaseColor: new THREE.Vector3(0.1, 0.01, 0.8), // Primary color (RGB) uSecondaryColor: new THREE.Vector4(0.0, 0.0, 0.0, 0.0), // Secondary color (RGBA) uRoughness: 0.2, // Material roughness uMetalness: 0.0, // Material metalness uGlassEffect: false // Enable glass-like effect }); ``` #### applyPreset(presetName) Apply a predefined set of parameters: ```javascript sim.applyPreset('purple'); // Available presets: 'default', 'purple' ``` #### destroy() Clean up and remove the simulation: ```javascript sim.destroy(); ``` ## Advanced Usage ### Async Initialization Sometimes you may need to wait for the simulation to fully initialize before updating settings: ```javascript async function init() { const container = document.getElementById('container'); const sim = new SlimeSimulationLib.SlimeSimulation(container, { baseResolution: 256 }); // Wait for simulation to initialize await new Promise(resolve => { const checkInit = () => { if (sim.simulationMaterial && sim.renderMaterial) { resolve(); } else { setTimeout(checkInit, 100); } }; checkInit(); }); // Now safe to update settings or apply presets sim.updateSettings({ uBaseColor: new THREE.Vector3(0.1, 0.01, 0.8), uRoughness: 0.2 }); } ``` ### Using with Background Image The simulation can distort a background image with a glass-like effect: ```javascript const sim = new SlimeSimulation(container, { baseResolution: 256, preset: 'glass', // Glass preset is optimized for image distortion imagePath: 'https://picsum.photos/1024/768', // Your background image params: { uGlassEffect: true, // Enable glass effect uShowImage: true, // Show the background image uMetalness: 0.1, // Lower metalness for more transparency uRoughness: 0.05 // Lower roughness for clearer refraction } }); // Note: The image should be: // - CORS-enabled (accessible from your domain) // - Ideally power-of-two dimensions (e.g., 1024x1024) // - Not too large (1024x1024 is usually sufficient) ``` ## Controls ### Simulation Parameters | Parameter | Range | Description | |-----------|--------|-------------| | Resolution | 4-1024 | Controls the simulation resolution. Higher values increase detail but impact performance | | Noise Factor | 0.0-1.0 | Amount of random noise added to the simulation | | Birth Rate | 0.0-1.0 | Threshold for new cells to appear (similar to Conway's Game of Life) | | Death Rate | 0.0-1.0 | Threshold for cells to disappear | | Sustain Rate | 0.0-1.0 | How well existing cells maintain their state | | Speed | 0.0-1.0 | Overall simulation speed | | Sample Radius | 0-15 | How far each cell looks for neighbors | | Growth Target | 0.0-100.0 | Maximum value for cell growth | | Mouse Mass | 0.2-1.0 | Strength of mouse/touch interaction | | Mouse Radius | 0.01-0.2 | Size of mouse/touch influence area | | Gaussian Weight | 4-20 | Smoothness of neighbor sampling | ### Render Parameters | Parameter | Range | Description | |-----------|--------|-------------| | Roughness | 0.05-0.95 | Surface roughness for PBR rendering | | Metalness | 0-1 | Metallic quality of the surface | | Tone Mapping | 1.8-2.4 | Overall brightness/contrast adjustment | | Light Height | 1-3 | Height of the moving light source | | Height Multiplier | 0.5-3 | Intensity of height displacement | | Normal Multiplier | 1-8 | Strength of surface normal effects | | Normal Z Strength | 0.2-1.5 | Vertical component of surface normals | ## Technical Details The simulation uses a ping-pong buffer technique with two render targets to update the state. The state consists of: - Red channel: Mass/density - Green channel: Velocity - Blue channel: Height - Alpha channel: Fixed at 1.0 The rendering pipeline implements PBR (Physically Based Rendering) with custom normal calculation and various material properties that can be adjusted in real-time. ## Browser Support Requires WebGL 2.0 support. Works in all modern browsers including mobile browsers (with reduced resolution). ## Dependencies - Three.js (^0.158.0) - lil-gui (^0.19.0) ## Performance Tips - Lower `baseResolution` for better performance on mobile devices - Adjust `stretchFactor` to balance quality and performance - Disable GUI in production for better performance ```javascript // Example with full configuration const sim = new SlimeSimulation(container, { baseResolution: 256, showGui: true, preset: 'blue', params: { // Override any preset parameters uBaseColor: new THREE.Vector3(0.0, 0.3, 0.8), uMetalness: 0.5 } }); // Or use preset only const sim = new SlimeSimulation(container, { preset: 'glass' }); // Or configure everything manually const sim = new SlimeSimulation(container, { params: { uNoiseFactor: 0.005, uBirthRate: 0.9, // ... all other parameters } }); ``` Note: When using `imagePath`, the simulation will initialize asynchronously after the image loads. All other options (including presets and params) will be applied automatically after initialization.