{"id":17445930,"url":"https://github.com/piellardj/reaction-diffusion-webgl","last_synced_at":"2025-04-12T19:53:05.576Z","repository":{"id":90961333,"uuid":"369776119","full_name":"piellardj/reaction-diffusion-webgl","owner":"piellardj","description":"Reaction-diffusion on GPU in WebGL.","archived":false,"fork":false,"pushed_at":"2023-06-11T16:07:37.000Z","size":3705,"stargazers_count":35,"open_issues_count":0,"forks_count":3,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-12T19:53:02.217Z","etag":null,"topics":["gray-scott-model","procedural-generation","reaction-diffusion","real-time","webgl"],"latest_commit_sha":null,"homepage":"https://piellardj.github.io/reaction-diffusion-webgl/?page%3Atabs%3Amap-tabs-id=uniform\u0026page%3Aselect%3Apresets-fixed-select-id=0","language":"TypeScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/piellardj.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":"2021-05-22T10:13:45.000Z","updated_at":"2025-02-08T15:24:31.000Z","dependencies_parsed_at":"2023-07-28T00:45:53.989Z","dependency_job_id":null,"html_url":"https://github.com/piellardj/reaction-diffusion-webgl","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piellardj%2Freaction-diffusion-webgl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piellardj%2Freaction-diffusion-webgl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piellardj%2Freaction-diffusion-webgl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/piellardj%2Freaction-diffusion-webgl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/piellardj","download_url":"https://codeload.github.com/piellardj/reaction-diffusion-webgl/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248625509,"owners_count":21135513,"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":["gray-scott-model","procedural-generation","reaction-diffusion","real-time","webgl"],"created_at":"2024-10-17T18:18:09.304Z","updated_at":"2025-04-12T19:53:05.550Z","avatar_url":"https://github.com/piellardj.png","language":"TypeScript","funding_links":["https://www.paypal.com/donate/?hosted_button_id=AF7H7GEJTL95E"],"categories":[],"sub_categories":[],"readme":"# reaction-diffusion\nReaction-diffusion is a model used to simulate the interaction of two chemical substances 'A' and 'B'. 'A' transforms into 'B' when it is in contact with it. Additionally, a little 'A' is continuously injected, and a fraction of 'B' slowly destroys itself.\n\nThis is a GPU implementation of the Gray Scott model. It exhibits natural-looking patterns, reminiscent of corals or some animal coats. Use the left mouse button to interact with the simulation.\n\nSee it live [here](https://piellardj.github.io/reaction-diffusion-webgl/?page%3Atabs%3Amap-tabs-id=uniform\u0026page%3Aselect%3Apresets-fixed-select-id=0).\n\n[![Donate](https://raw.githubusercontent.com/piellardj/piellardj.github.io/master/images/readme/donate-paypal.svg)](https://www.paypal.com/donate/?hosted_button_id=AF7H7GEJTL95E)\n\n## Preview\n![Black and white mode: cat](src/readme/cat.png)\n\n![Color mode: joconde](src/readme/joconde.png)\n\n![Illustration 1](src/readme/preview_3.png)\n\n![Illustration 2](src/readme/uniform_1.png)\n\n![Illustration 3](src/readme/preview_2.png)\n\nhttps://user-images.githubusercontent.com/22922087/119693778-e5600800-be4c-11eb-978f-7387cfce0405.mp4\n\n## Reaction-diffusion\n### Model\nReaction-diffusion can be seen as a description of a simple chemical reaction between two substances 'A' and 'B'. I like to imagine they are liquid.\n\nThe rules are quite simple:\n- a molecule of 'A' turns into 'B' if it meets two molecules of 'B': `A + 2B ⟶ 3B`\n- more 'A' is continuously added (at a uniform feeding rate)\n- a fraction of 'B' continuously disappears (at a uniform killing rate)\n- 'A' and 'B' slowly diffuse at a constant rate.\n\nThis system can easily be discretized by turning it into a cellular automaton:\n- space becomes an Eulerian grid where each cell has 2 scalars for the local concentration of 'A' and 'B'.\n    - for each cell, the amount of 'A' that turns into 'B' is computed as `A x B x B`.\n    - the feeding and killing rates can be uniform or vary from cell to cell.\n    - the diffusion is a simple blur with a 3x3 kernel.\n- in each iteration, the new state of the grid is computed from the previous one all at once.\n\n### Implementation\nThe values for A and B are stored in a texture. Unfortunately, the default precision of 8 bits per channel is not enough for this simulation. A `RG16F` texture format would be ideal, however it is only available in WebGL 2. This is why I have to store each 16 bits value on 2x8 bits channels of a RGBA texture: the value for A is stored in red and green, and the value for B in blue and alpha.\n\nThis also prevents me from using a little trick to make the blurring part cheaper. The bluring is currently performed by applying a 3x3 kernel, which means 9 texture fetches. A common technique to make that faster is to take advantage of the linear interpolation performed by the GPU, in order to go down to only 5 fetches. However because the values are stored in 2 channels, this leads to numerical imprecisions, which are fine for displaying but unsuited for the computing part. \n\nAnother optimisation for the tricolor mode would be to use the `WEBGL_draw_buffers` extension to allow the fragment shader to write to all 3 textures (red, green, blue) at once. This would reduce by 3 the number of uniforms binding, of calls to `gl.draw`, and of texture fetches in the shader.\n\n## Image mode\nIn image mode, the feed and kill rates are not uniform, they vary locally based on the source image. They are interpolated between 2 presets, for white and black:\n![Illustration of interpolation values](src/readme/interpolation.png)\n\n### Results\nUsing reaction-diffusion to approximate images is computationally expensive, but it gives results that are visually interesting. The output is quite trippy, but after blurring it a bit, you can see that is is pretty good. In this example, the hue is a bit off, but notice how many fine details are preserved.\n\u003cdiv style=\"text-align:center\"\u003e\n    \u003cimg alt=\"Bird in color mode\" src=\"src/readme/joconde-comparison.jpg\"/\u003e\n    \u003cp\u003e\n        \u003ci\u003eLeft: original image. Middle: approximation with reaction-diffusion. Right: blurred version of the middle image.\u003c/i\u003e\n    \u003c/p\u003e\n\u003c/div\u003e\n\n### Black and white\nFor the black and white mode, the local brightness is sampled. I used the perceived brightness, computed as: `(0.21 × red) + (0.72 × green) + (0.07 × blue)`.\n\n### Color\nFor the color mode, there are 3 simulations that run in parallel, one for each channel. They are combined at drawing time using additive compositing.\n\n\u003cdiv style=\"text-align:center\"\u003e\n    \u003cimg alt=\"Bird in color mode\" src=\"src/readme/bird.png\"/\u003e\n    \u003cp\u003e\n        \u003ci\u003eHere is a bird in color mode.\u003c/i\u003e\n    \u003c/p\u003e\n\u003c/div\u003e\n\n\u003cdiv style=\"text-align:center\"\u003e\n    \u003cimg alt=\"Bird decomposition\" src=\"src/readme/bird-decomposition.png\"/\u003e\n    \u003cp\u003e\n        \u003ci\u003eHere the decomposition of the bird image.\u003c/i\u003e\n    \u003c/p\u003e\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiellardj%2Freaction-diffusion-webgl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpiellardj%2Freaction-diffusion-webgl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpiellardj%2Freaction-diffusion-webgl/lists"}