<p>If you want to implement this with GLSL, the general concept that could be applied is multi-pass rendering. In a first render pass, draw some ink on the screen and write the result in a frame buffer object (FBO). Then in the second render pass, draw a screen-size quad and attach the texture of the FBO. In this second render pass you could use a GLSL shader that distributes the ink. In the example below I used a simple Erode and a Gauss filter but more complicated effects are possible here. The result is then used as the background for the first render pass that draws more ink, which is passed on to the second render pass, and so on...</p>

<p><a href="https://i.sstatic.net/AFA6C.gif" rel="noreferrer"><img src="https://i.sstatic.net/AFA6C.gif" alt="ink flow animated gif"></a></p>

<p>I have generated the example above with an online tool called "GSN Composer", which uses GLSL shaders and WebGL. You find the corresponding node graph here:</p>

<p><a href="https://www.gsn-lib.org/index.html#projectName=foruminkspread&amp;graphName=erode" rel="noreferrer">https://www.gsn-lib.org/index.html#projectName=foruminkspread&amp;graphName=erode</a></p>

<p>Currently, in this very simple implementation, the spreading of ink will never stop. To achieve this you would need to remember a per-pixel state (e.g. a "mass" or "reservoir", as you have mentioned in your question) and use this per-pixel state in the shader that performs the spreading. This state could be encoded in the texture output (e.g. in the alpha channel) or could be written into a second texture that is passed along the shader pipeline.</p>

CC BY-SA 4.0
2018-10-12T13:21:44.567Z
A more complete example is now available here: https://www.gsn-lib.org/docs/gallery.php?projectName=ColorMix&graphName=ColorMix
NodeCode
CC BY-SA 3.0
2017-03-29T19:56:36.060Z
2017-03-29T19:56:36.060Z
NodeCode
<p>I have dealt with glsl before, but I still have problems with my understanding of how to achieve certain kinds of effects with per-pixel processing. What I am looking to do is use a fragment shader to emulate ink spreading across paper. Simply put, I want to emulate a large drop of ink being dropped on paper, with the ink spreading out from the source, perhaps with some capillary effect. Instead of one drop, this will apply to an entire image.</p>

<p>Ive done some brainstorming for the implementation. There is a random initial "mass" applied to each pixel, and one method I'm considering is having the texture scale outwards with the value of the initial "mass" decreasing until 0.</p>

<p>What might I be missing in trying to implement this? Does anyone know of a similar shader effect that I could consult while building this?</p>

CC BY-SA 3.0
2016-07-06T19:19:03.353Z
Could you clarify what difference you want to see each frame? Do you want the total "mass" to stay constant, and have it spread a small distance each frame until it is evenly distributed? Do you want it to spread evenly in all directions, giving a circular spread?
trichoplax is on Codidact now
CC BY-SA 3.0
2016-07-06T19:22:53.910Z
I think it would be most appropriate to have it spread outwards each frame at a constant rate, but since the initial mass for each pixel is random, all pixels will stop spreading at different times. If the "mass" is constant across all pixels, the effect would just be an even circular spread. I think a major issue I'm having is figuring out how to pass that mass value along.
aceslowman
CC BY-SA 3.0
2016-07-06T22:39:12.627Z
Maybe try to start with just describing the overall effect you want to give, rather than the implementation details. Do you want multiple drops of ink that all spread out independently and eventually overlap, or are the multiple pixels you mention part of modeling a single ink drop?
trichoplax is on Codidact now
CC BY-SA 3.0
2016-07-06T22:45:58.847Z
Thank you all for the help. The effect I want is as if a heavy drop of ink was dropped on paper, and the ink is spreading outwards. With that it spreads to different degrees, and maybe even has some sort of capillary element.
aceslowman
CC BY-SA 3.0
2016-07-06T22:50:49.060Z
This is much clearer. Could you edit the question to reflect this more specific requirement? Comments aren't guaranteed to last forever.
trichoplax is on Codidact now
CC BY-SA 3.0
2016-08-22T04:22:07.523Z
Are you wanting something like diffuse-reaction? There is a great example of this on shadertoy (https://www.shadertoy.com/view/4dcGW2)
PaulHK
<opengl><glsl><procedural-generation>
Creating an "ink spread" effect with a glsl fragment shader
aceslowman
# Creating an "ink spread" effect with a glsl fragment shader

(Asked by: username_0 on 2016-07-06)

I have dealt with glsl before, but I still have problems with my understanding of how to achieve certain kinds of effects with per-pixel processing. What I am looking to do is use a fragment shader to emulate ink spreading across paper. Simply put, I want to emulate a large drop of ink being dropped on paper, with the ink spreading out from the source, perhaps with some capillary effect. Instead of one drop, this will apply to an entire image.

Ive done some brainstorming for the implementation. There is a random initial "mass" applied to each pixel, and one method I'm considering is having the texture scale outwards with the value of the initial "mass" decreasing until 0.

What might I be missing in trying to implement this? Does anyone know of a similar shader effect that I could consult while building this?

**Tags:** opengl, glsl, procedural-generation

> **Comments:**
> **username_1**: Could you clarify what difference you want to see each frame? Do you want the total "mass" to stay constant, and have it spread a small distance each frame until it is evenly distributed? Do you want it to spread evenly in all directions, giving a circular spread?  
> **username_0**: I think it would be most appropriate to have it spread outwards each frame at a constant rate, but since the initial mass for each pixel is random, all pixels will stop spreading at different times. If the "mass" is constant across all pixels, the effect would just be an even circular spread. I think a major issue I'm having is figuring out how to pass that mass value along.  
> **username_1**: Maybe try to start with just describing the overall effect you want to give, rather than the implementation details. Do you want multiple drops of ink that all spread out independently and eventually overlap, or are the multiple pixels you mention part of modeling a single ink drop?  
> **username_0**: Thank you all for the help. The effect I want is as if a heavy drop of ink was dropped on paper, and the ink is spreading outwards. With that it spreads to different degrees, and maybe even has some sort of capillary element.  
> **username_1**: This is much clearer. Could you edit the question to reflect this more specific requirement? Comments aren't guaranteed to last forever.  
> **username_2**: Are you wanting something like diffuse-reaction? There is a great example of this on shadertoy (https://www.shadertoy.com/view/4dcGW2)  

---

## 1 answers

### Answer by username_3 on 2017-03-29. Score: 6

If you want to implement this with GLSL, the general concept that could be applied is multi-pass rendering. In a first render pass, draw some ink on the screen and write the result in a frame buffer object (FBO). Then in the second render pass, draw a screen-size quad and attach the texture of the FBO. In this second render pass you could use a GLSL shader that distributes the ink. In the example below I used a simple Erode and a Gauss filter but more complicated effects are possible here. The result is then used as the background for the first render pass that draws more ink, which is passed on to the second render pass, and so on...

[![ink flow animated gif](https://i.sstatic.net/AFA6C.gif)](https://i.sstatic.net/AFA6C.gif)

I have generated the example above with an online tool called "GSN Composer", which uses GLSL shaders and WebGL. You find the corresponding node graph here:

<https://www.gsn-lib.org/index.html#projectName=foruminkspread&graphName=erode>

Currently, in this very simple implementation, the spreading of ink will never stop. To achieve this you would need to remember a per-pixel state (e.g. a "mass" or "reservoir", as you have mentioned in your question) and use this per-pixel state in the shader that performs the spreading. This state could be encoded in the texture output (e.g. in the alpha channel) or could be written into a second texture that is passed along the shader pipeline.

> **Comments:**
> **username_3**: A more complete example is now available here: https://www.gsn-lib.org/docs/gallery.php?projectName=ColorMix&graphName=ColorMix  

---

