6
$\begingroup$

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?

$\endgroup$
  • $\begingroup$ 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? $\endgroup$ – trichoplax Jul 6 '16 at 19:19
  • $\begingroup$ 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. $\endgroup$ – aceslowman Jul 6 '16 at 19:22
  • $\begingroup$ 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? $\endgroup$ – trichoplax Jul 6 '16 at 22:39
  • $\begingroup$ 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. $\endgroup$ – aceslowman Jul 6 '16 at 22:45
  • 1
    $\begingroup$ This is much clearer. Could you edit the question to reflect this more specific requirement? Comments aren't guaranteed to last forever. $\endgroup$ – trichoplax Jul 6 '16 at 22:50
5
$\begingroup$

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

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.