slime-simulation
Version:
Interactive WebGL slime simulation with PBR rendering
288 lines (241 loc) • 9.04 kB
Markdown
# Slime Simulation

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.