{"id":18118414,"url":"https://github.com/michaelbrusegard/webgl-fluid-enhanced","last_synced_at":"2025-04-05T06:05:23.860Z","repository":{"id":166178552,"uuid":"641511223","full_name":"michaelbrusegard/WebGL-Fluid-Enhanced","owner":"michaelbrusegard","description":"WebGL Fluid Simulation for modern webpages (works even on mobile).","archived":false,"fork":false,"pushed_at":"2024-10-07T17:47:31.000Z","size":5672,"stargazers_count":68,"open_issues_count":2,"forks_count":9,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-03-29T05:04:11.905Z","etag":null,"topics":["background","es-module","fluid-simulation","navier-stokes","webgl"],"latest_commit_sha":null,"homepage":"https://webgl-fluid-enhanced.michaelbrusegard.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"PavelDoGreat/WebGL-Fluid-Simulation","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/michaelbrusegard.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-16T16:10:39.000Z","updated_at":"2025-03-28T17:14:46.000Z","dependencies_parsed_at":"2023-12-13T00:35:59.546Z","dependency_job_id":"2af2834d-566b-4a77-84b1-76ae8ec4a3a5","html_url":"https://github.com/michaelbrusegard/WebGL-Fluid-Enhanced","commit_stats":null,"previous_names":["michaelbrusegard/webgl-fluid-enhanced","michaelbrusegard/webgl-fluid-simulation"],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelbrusegard%2FWebGL-Fluid-Enhanced","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelbrusegard%2FWebGL-Fluid-Enhanced/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelbrusegard%2FWebGL-Fluid-Enhanced/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/michaelbrusegard%2FWebGL-Fluid-Enhanced/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/michaelbrusegard","download_url":"https://codeload.github.com/michaelbrusegard/WebGL-Fluid-Enhanced/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247294538,"owners_count":20915340,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["background","es-module","fluid-simulation","navier-stokes","webgl"],"created_at":"2024-11-01T05:11:18.520Z","updated_at":"2025-04-05T06:05:23.842Z","avatar_url":"https://github.com/michaelbrusegard.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# [WebGL Fluid Enhanced](https://www.npmjs.com/package/webgl-fluid-enhanced)\n\n[![npm version](https://img.shields.io/npm/v/webgl-fluid-enhanced.svg?color=green)](https://www.npmjs.com/package/webgl-fluid-enhanced)\n[![npm dependencies](https://img.shields.io/badge/dependencies-0-green.svg)](https://www.npmjs.com/package/webgl-fluid-enhanced)\n[![minzipped size](https://img.shields.io/bundlephobia/minzip/webgl-fluid-enhanced.svg?color=blue)](https://bundlephobia.com/package/webgl-fluid-enhanced)\n[![npm downloads](\u003chttps://img.shields.io/npm/dt/webgl-fluid-enhanced?logo=npm\u0026color=rgba(203,0,0,0.9)\u003e)](https://www.npmjs.com/package/webgl-fluid-enhanced)\n[![conventional commits](https://img.shields.io/badge/commits-Conventional-FE5196.svg?logo=conventionalcommits)](https://conventionalcommits.org)\n\n\u003e [!IMPORTANT]\n\u003e The new documentation and playground can be found [here](https://webgl-fluid-enhanced.michaelbrusegard.com).\n\n## Table of Contents\n\n1. [WebGL Fluid Enhanced](#webgl-fluid-enhanced)\n2. [Want to contribute](#want-to-contribute)\n3. [References](#references)\n4. [License](#license)\n5. [Documentation for Outdated Version (v0.6.1 and Prior)](#documentation-for-outdated-version-v061-and-prior)\n\n## Want to contribute\n\nFeel free to open an issue or a pull request! I'm always open to suggestions and improvements, and I have tried to make the development environment as good as possible with a descriptive file structure and TypeScript definitions.\n\n## References\n\n\u003chttps://github.com/PavelDoGreat/WebGL-Fluid-Simulation\u003e\n\n\u003chttps://developer.nvidia.com/gpugems/gpugems/part-vi-beyond-triangles/chapter-38-fast-fluid-dynamics-simulation-gpu\u003e\n\n\u003chttps://github.com/mharrys/fluids-2d\u003e\n\n\u003chttps://github.com/haxiomic/GPU-Fluid-Experiments\u003e\n\n## License\n\nThe code is available under the [MIT license](LICENSE)\n\n## Documentation for Outdated Version (v0.6.1 and Prior)\n\n### Install\n\n```bash\n  npm install webgl-fluid-enhanced\n```\n\n### New Features\n\n- Ability to change config after simulation has started\n- Use hover to activate\n- Choose colors used in simulation\n- Set background image\n- Set if splats generate on initial load\n- Specify how many splats should generate initially and from keypress\n- Assign specific key to splats (Can be disabled)\n- Trigger splats method\n- Pause method\n- Brightness option\n- Method to splat at specific coordinates\n- TypeScript support\n\n### Config options\n\n```js\nwebGLFluidEnhanced.config({\n  SIM_RESOLUTION: 128, // Resolution of the simulation grid\n  DYE_RESOLUTION: 1024, // Resolution of the dye grid\n  CAPTURE_RESOLUTION: 512, // Resolution of captured frames\n  DENSITY_DISSIPATION: 1, // Rate at which density dissipates\n  VELOCITY_DISSIPATION: 0.2, // Rate at which velocity dissipates\n  PRESSURE: 0.8, // Pressure value used in the simulation\n  PRESSURE_ITERATIONS: 20, // Number of pressure iterations\n  CURL: 30, // Curl value used in the simulation\n  INITIAL: true, // Enables splats on initial load\n  SPLAT_AMOUNT: 5, // Number of initial splats (Random number between n and n * 5)\n  SPLAT_RADIUS: 0.25, // Radius of the splats\n  SPLAT_FORCE: 6000, // Force applied by the splats\n  SPLAT_KEY: 'Space', // Keyboard key to spawn new splats (empty to disable)\n  SHADING: true, // Enables shading in the visualization\n  COLORFUL: true, // Enables rapid changing of colors\n  COLOR_UPDATE_SPEED: 10, // Speed of color update\n  COLOR_PALETTE: [], // Custom color palette (empty by default, uses hex colors)\n  HOVER: true, // Enables interaction on hover\n  BACK_COLOR: '#000000', // Background color of the canvas\n  TRANSPARENT: false, // Makes the canvas transparent if true\n  BRIGHTNESS: 0.5, // Color brightness (Recommend lower than 1.0 if BLOOM is true)\n  BLOOM: true, // Enables bloom effect\n  BLOOM_ITERATIONS: 8, // Number of bloom effect iterations\n  BLOOM_RESOLUTION: 256, // Resolution of the bloom effect\n  BLOOM_INTENSITY: 0.8, // Intensity of the bloom effect\n  BLOOM_THRESHOLD: 0.6, // Threshold for the bloom effect\n  BLOOM_SOFT_KNEE: 0.7, // Soft knee value for the bloom effect\n  SUNRAYS: true, // Enables sunrays effect\n  SUNRAYS_RESOLUTION: 196, // Resolution of the sunrays effect\n  SUNRAYS_WEIGHT: 1.0, // Weight of the sunrays effect\n});\n```\n\n### General info\n\n#### Usage\n\nInitialise:\n\n```js\nwebGLFluidEnhanced.simulation(document.querySelector('canvas'), {\n  // Optional options\n});\n```\n\nEdit config:\n\n```js\nwebGLFluidEnhanced.config({\n  // Options\n});\n```\n\nTrigger splats:\n\n```js\nwebGLFluidEnhanced.splats();\n```\n\nSplat at specific coordinates:\n\n```js\n// x and y are the coordinates in the HTML document where the splat should occur.\n// They represent the position of the center of the splat.\nwebGLFluidEnhanced.splat(\n  x,\n  y,\n\n  // dx and dy represent the directional components of the splat's force.\n  // They determine the direction of the fluid movement caused by the splat.\n  // These values are best in the range from -1000 to 1000, with 0 representing no force.\n  dx,\n  dy,\n\n  // color is the color of the fluid added by the splat as a string in hexadecimal format.\n  // This parameter is optional. If not provided, colors from the palette or then a random color may be used.\n  color,\n);\n```\n\nPause/resume the simulation:\n\n```js\n// drawWhilePaused is an optional boolean that determines whether it is possible to stil draw while the simulation is paused.\nwebGLFluidEnhanced.pause(drawWhilePaused);\n```\n\nDownload a screenshot:\n\n```js\nwebGLFluidEnhanced.screenshot();\n```\n\n#### Set background image\n\nTo set background image make sure the `TRANSPARENT` option is set to `true`, and in the CSS you can set `background-image: url('\u003cPHOTO-URL\u003e');` and `background-size: 100% 100%;` to fill the whole canvas.\n\n#### Background color\n\nWhen using the `BACK_COLOR` option, the color you provided will be whitened when the `BLOOM` option is set to `true`.\n\n### Examples\n\n#### HTML\n\n```html\n\u003c!doctype html\u003e\n\u003chtml\u003e\n  \u003cbody\u003e\n    \u003ccanvas style=\"width: 100vw; height: 100vh;\"\u003e\u003c/canvas\u003e\n    \u003cscript type=\"importmap\"\u003e\n      {\n        \"imports\": {\n          \"webgl-fluid-enhanced\": \"https://esm.run/webgl-fluid-enhanced@latest\"\n        }\n      }\n    \u003c/script\u003e\n    \u003cscript type=\"module\"\u003e\n      import webGLFluidEnhanced from 'webgl-fluid-simulation';\n\n      webGLFluidEnhanced.simulation(document.querySelector('canvas'), {\n        COLOR_PALETTE: ['#cc211b', '#f1c593', '#e87e54', '#f193a7', '#ec6fa9'],\n        HOVER: false,\n        SPLAT_RADIUS: 0.1,\n        VELOCITY_DISSIPATION: 0.99,\n        BLOOM: false,\n      });\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n#### React\n\n```js\nimport { useEffect, useRef } from 'react';\nimport webGLFluidEnhanced from 'webgl-fluid-enhanced';\n\nconst App = () =\u003e {\n  const canvasRef = useRef(null);\n\n  useEffect(() =\u003e {\n    webGLFluidEnhanced.simulation(canvasRef.current, {\n      SIM_RESOLUTION: 256,\n      DENSITY_DISSIPATION: 0.8,\n      PRESSURE_ITERATIONS: 30,\n      COLOR_PALETTE: ['#61dafb', '#a8dadc', '#457b9d', '#1d3557', '#f1faee'],\n    });\n  }, []);\n\n  return \u003ccanvas ref={canvasRef} style={{ width: '100vw', height: '100vh' }} /\u003e;\n};\n\nexport default App;\n```\n\n#### Next.js (tailwindcss)\n\n```tsx\n'use client';\n\nimport { useEffect, useRef } from 'react';\nimport webGLFluidEnhanced from 'webgl-fluid-enhanced';\n\nconst App = () =\u003e {\n  const canvasRef = useRef(null);\n\n  useEffect(() =\u003e {\n    webGLFluidEnhanced.simulation(canvasRef.current!, {\n      PRESSURE: 0.2,\n      SUNRAYS: false,\n      START_SPLATS: 10,\n      DENSITY_DISSIPATION: 3,\n      CURL: 100,\n      COLOR_PALETTE: ['#0000ff', '#111111', '#1d1d1d', '#eaeaea', '#4dba87'],\n    });\n  }, []);\n\n  return \u003ccanvas ref={canvasRef} className='h-screen w-screen' /\u003e;\n};\n\nexport default App;\n```\n\n#### Vue.js\n\n```vue\n\u003c!-- Not tested! --\u003e\n\u003ctemplate\u003e\n  \u003ccanvas ref=\"canvas\"\u003e\u003c/canvas\u003e\n\u003c/template\u003e\n\n\u003cscript setup\u003e\nimport { onMounted, ref } from 'vue'\nimport WebGLFluid from 'webgl-fluid'\n\nconst canvas = ref()\n\nonMounted(() =\u003e {\n  webGLFluidEnhanced.simulation(canvas, {\n        SPLAT_RADIUS: 0.5,\n        COLOR_UPDATE_SPEED: 20,\n        BLOOM: false,\n    \u003c\u003e});\n})\n\u003c/script\u003e\n\n\u003cstyle\u003e\ncanvas {\n  width: 100vw;\n  height: 100vh;\n}\n\u003c/style\u003e\n```\n\n#### Angular\n\n```ts\n// Not tested!\nimport { Component, ElementRef, OnInit, ViewChild } from '@angular/core';\nimport webGLFluidEnhanced from 'webgl-fluid-enhanced';\n\n@Component({\n  selector: 'app-root',\n  template: `\n    \u003ccanvas #canvasRef style=\"width: 100vw; height: 100vh;\"\u003e\u003c/canvas\u003e\n  `,\n})\nexport class AppComponent implements OnInit {\n  @ViewChild('canvasRef', { static: true }) canvasRef!: ElementRef;\n\n  ngOnInit(): void {\n    webGLFluidEnhanced.simulation(this.canvasRef.nativeElement, {\n      COLOR_PALETTE: ['#dd0031', '#c3002f', '#dd0031'],\n      START_SPLATS: 50,\n      TRANSPARENT: true,\n    });\n  }\n}\n```\n\n#### Svelte\n\n```svelte\n\u003c!-- Not tested! --\u003e\n\u003cscript\u003e\n  import { onMount } from 'svelte';\n\n  let canvasRef;\n\n  onMount(() =\u003e {\n    import('webgl-fluid-enhanced').then(({ default: webGLFluidEnhanced }) =\u003e {\n      webGLFluidEnhanced.simulation(canvasRef, {\n        SIM_RESOLUTION: 256,\n        VELOCITY_DISSIPATION: 0.99,\n        COLOR_PALETTE: ['#ff7f00'],\n      });\n    });\n  });\n\u003c/script\u003e\n\n\u003ccanvas bind:this={canvasRef} style=\"width: 100vw; height: 100vh;\" /\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelbrusegard%2Fwebgl-fluid-enhanced","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmichaelbrusegard%2Fwebgl-fluid-enhanced","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmichaelbrusegard%2Fwebgl-fluid-enhanced/lists"}