GLSL Dissolve Shader Documentation

I wrote a dissolve shader to use in mTheroyGame, and shared it with the jME community, this is all the supporting documention I drew up. It’s a bit of an insight into behind the scenes of working on the game. Documentation takes far longer than developing of the shader itself but its just part of development.

The Dissolve Shader uses a simple grey scale image as an animated mask to hide a material. It’s internal workings are deviously simple but immensely powerful.

Test Project output:

Starting at the top left we have :

  • simple linear dissolve
  • organic dissolve
  • pixel desolve

and bottom row :

  • organic growth
  • texture masking
  • organic burn

screenshot of the test and all the texture maps used in the test, layed out to reflect their usage in within the test scene

The best way to get an understanding of what this is and how it works, is to first watch the video while paying close attention to the top left linear dissolve, then look at the linear dissolve map in the graphic above… done that – see what I’m saying ?


Test Project Setup

The test is occolating the dissolve amount between 0 and 1. It demonstrates 6 different uses for the shader, all running at the same speed. The top row are straight forward dissolves. The bottom row shows 3 potential applications:

  • Organic Growth (bottom left) over a mesh, this could work both animating rapidly for a fast grow effect, or set to a fixed value e.g. set to 0.5f is “50% covered in growth”;
  • Texture Masking (bottom middle) , I see this is probably where the most practical applications will come from. The demonstration shows a poorely photoshoped clean street, peices of garbage are then scattered around dependant on the dissolve amount, this would work best with a fixed value eg set to .75 is “75% dirty”. Texture Masking could be also be used for:
    –  paint damage on a car;
    –  lacerations on a character;
    –  the blood shot eye effect that creeps in from the sides of the screen when you’ve taken too much damage in a modern FPS.
  • Organic Burn (bottom right) is comprised of 2 cubes, one blue, one orange, both with the same organic dissolve, however the orange one is slightly offset ahead of the blue so it shows first (ie the dissolve amount is always slight advanced).


The shader requires 2 parameters:

  • a Texture2D texture map to use as the dissolve map; and
  • a Vector2 of internal params params:
    –  the first a float value being the amount of dissolve, a value from 0-1 : 0 being no dissolve, being fully dissolved; and
    –  the second value is an int use as an inversion switch, 1 to invert the dissolve/discard, 0 to leave as is.

How it Works

The shader incrementally clamps off the colour value, dark to light, and uses that for a masking texture to discard pixels. It is currently capped for convenience at 255 frames of animation and is only using one colour channel. In simple terms, in starts by only discarding the darkest parts of the texture map, then the slightly lighter parts, then the slightly lighter again and again until it eventually cant get any lighter (white), at which point the proccess is complete.



Performance is cheakily quicker than the orignal Lighting material, because frags are getting discarded before any additional lighting processing is being applied, but this will fluctuate depending on how much of an object is being discarded which is something to be very weary of, and is actually a bit crap on my behalf – slower reliable performance is far more desirable than fast fluky performance.


Future plans

There are still 3 colour channels in a normal image left to play with, I havent decided how to utilise them yet but they could be used to extend the length of the animtion, allow more complex animation frames, enable alpha fading rather than a binary discard, impose max and min value limits, several animations per image, more comprehensive map data (eg map + inv map + alt map + alt inv map), reverse animation flag…. not really sure yet.





I have included a full download of the source and assets for the test project.

The shader is currently piggy backed on the back of the standard Lighting material shader (until I can figure a more efficient method than one behemoth material to rule them all).

Here is a list of the changes made to the standard lighting material, the source download includes an already customized variant.



        // the env map is a spheremap and not a cube map
        Boolean EnvMapAsSphereMap

+        // Dissolve Map
+        Texture2D DissolveMap
+        Vector2 DissolveParams;

    Technique {


            USE_REFLECTION : EnvMap
            SPHERE_MAP : SphereMap

+            DISSOLVE_MAP : DissolveMap
+            DISSOLVE_PARAMS : DissolveParams



    uniform ENVMAP m_EnvMap;

+    uniform sampler2D m_DissolveMap;
+        uniform vec2 m_DissolveParams;
+    #endif

float tangDot(in vec3 v1, in vec3 v2){


    newTexCoord = texCoord;

+    #ifdef DISSOLVE_MAP
+        if (texture2D(m_DissolveMap, newTexCoord).r < m_DissolveOptions.x && m_DissolveOptions.y == 0) {
+            discard;
+        }
+        if (texture2D(m_DissolveMap, newTexCoord).r > m_DissolveOptions.x && m_DissolveOptions.y == 1) {
+            discard;
+        }
+    #endif

   #ifdef DIFFUSEMAP
      vec4 diffuseColor = texture2D(m_DiffuseMap, newTexCoord);

package dissolvetest;

import com.jme3.material.Material;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.*;
import com.jme3.light.*;
import com.jme3.math.*;
import com.jme3.texture.*;

 * @author thetoucher

public class Main extends SimpleApplication {

    // speed of animation
    private float speed = .125f;

    private float count = 0;
    private int dir = 1;

    private Vector2f DSParams, DSParamsInv, DSParamsBurn;

    public static void main(String[] args) {
        Main app = new Main();

    public void simpleInitApp() {

        Texture t;
        Material mat;

        cam.setLocation(new Vector3f(0,1.5f,10f));

        // reusable params
        DSParams = new Vector2f(0,0); // standard
        DSParamsInv = new Vector2f(0,1); // inverted
        DSParamsBurn = new Vector2f(0,0); // used for offset organic burn map

        // linear dissolve
        addTestCube(-3f,3f,assetManager.loadTexture("Textures/linear.png"), DSParams);

        // organic dissolve
        addTestCube(0,3f,assetManager.loadTexture("Textures/burnMap.png"), DSParamsInv);

        // pixel dissolve
        t = assetManager.loadTexture("Textures/pixelMap.png");
        t.setMagFilter(Texture.MagFilter.Nearest); // this is needed to retain the crisp pixelated look
        addTestCube(3f, 3f, t, DSParams);        

        // organic growth
        mat = addTestCube(-3f,0,assetManager.loadTexture("Textures/growMap.png"), DSParamsInv).getMaterial();
        mat.setColor("Ambient", ColorRGBA.Green);
        mat.setTexture("DiffuseMap", assetManager.loadTexture("Textures/growMap.png"));

        addTestCube(-3f,0,assetManager.loadTexture("Textures/growMap.png"), DSParams);

        // texture mask
        mat = addTestCube(0,0,assetManager.loadTexture("Textures/streetBurn.png"), DSParams).getMaterial();
        mat.setTexture("DiffuseMap", assetManager.loadTexture("Textures/streetClean.png"));
        mat.setColor("Ambient",  ColorRGBA.White);

        mat = addTestCube(0f,0f,assetManager.loadTexture("Textures/streetBurn.png"), DSParamsInv).getMaterial();
        mat.setTexture("DiffuseMap", assetManager.loadTexture("Textures/street.png"));
        mat.setColor("Ambient",  ColorRGBA.White);

        // organic burn
        addTestCube(3f, 0, assetManager.loadTexture("Textures/burnMap.png"), DSParamsBurn).getMaterial().setColor("Ambient",  ColorRGBA.Red);
        addTestCube(3f, 0, assetManager.loadTexture("Textures/burnMap.png"), DSParams);

        AmbientLight a = new AmbientLight();


    private Geometry addTestCube(float xPos, float yPos, Texture map, Vector2f DSParams) {
        Box b = new Box(Vector3f.ZERO, 1, 1, 1);
        Geometry geom = new Geometry("Box", b);
        geom.setLocalTranslation(new Vector3f(xPos,yPos,0));

        Material mat = new Material(assetManager, "Materials/Lighting.j3md");
        mat.setColor("Ambient",  ColorRGBA.Blue);
        mat.setColor("Diffuse",  ColorRGBA.White);
        mat.setColor("Specular", ColorRGBA.Black);
        mat.setBoolean("UseMaterialColors", true);
        mat.setTexture("DissolveMap", map);
        mat.setVector2("DissolveParams", DSParams);


        return geom;

    public void simpleUpdate(float tpf) {


       // animation ossolation
       if (count > 1f) {
           dir = -1;
       } else if (count < 0) {
           dir = 1;

       // update the dissolve amounts



36 thoughts on “GLSL Dissolve Shader Documentation

  1. Have you ever considered about adding a little bit more than just your articles? I mean, what you say is fundamental and all. But think about if you added some great images or videos to give your posts more, “pop”! Your content is excellent but with images and clips, this website could certainly be one of the most beneficial in its niche. Great blog!

  2. Hello! This post couldn’t be written any better! Reading this post reminds me of my good old room mate! He always kept talking about this. I will forward this write-up to him. Pretty sure he will have a good read. Thank you for sharing!

  3. Hmm it seems like your site ate my first comment (it was extremely long) so I guess I’ll just sum it up what I wrote and say, I’m thoroughly enjoying your blog. I too am an aspiring blog writer but I’m still new to the whole thing. Do you have any helpful hints for inexperienced blog writers? I’d genuinely appreciate it.

  4. Hmm it appears like your site ate my first comment (it was super long) so I guess I’ll just sum it up what I wrote and say, I’m thoroughly enjoying your blog. I too am an aspiring blog writer but I’m still new to everything. Do you have any points for newbie blog writers? I’d genuinely appreciate it.

  5. Hi there! I just wanted to ask if you ever have any problems with hackers? My last blog (wordpress) was hacked and I ended up losing a few months of hard work due to no back up. Do you have any methods to prevent hackers?

  6. Along with almost everything which appears to be developing throughout this particular area, all your viewpoints are generally quite stimulating. Even so, I appologize, because I do not give credence to your entire strategy, all be it exhilarating none the less. It would seem to us that your opinions are actually not totally rationalized and in fact you are generally your self not really completely certain of the assertion. In any event I did enjoy looking at it.

  7. Hi! Someone in my Myspace group shared this site with us so I came to look it over. I’m definitely loving the information. I’m bookmarking and will be tweeting this to my followers! Excellent blog and great style and design.

  8. Hey there! Someone in my Facebook group shared this site with us so I came to check it out. I’m definitely loving the information. I’m bookmarking and will be tweeting this to my followers! Excellent blog and brilliant design.

  9. Hi there, i read your blog occasionally and i own a similar one and i was just curious if you get a lot of spam remarks? If so how do you prevent it, any plugin or anything you can advise? I get so much lately it’s driving me insane so any support is very much appreciated.

  10. Do you have a spam problem on this blog; I also am a blogger, and I was wanting to know your situation; many of us have created some nice methods and we are looking to swap methods with others, why not shoot me an e-mail if interested.

  11. Hey just wanted to give you a quick heads up and let you know a few of the pictures aren’t loading properly. I’m not sure why but I think its a linking issue. I’ve tried it in two different internet browsers and both show the same outcome.

  12. Greetings! I’ve been reading your weblog for a long time now and finally got the courage to go ahead and give you a shout out from Kingwood Texas! Just wanted to say keep up the good job!

  13. Do you mind if I quote a couple of your articles as long as I provide credit and sources back to your site? My blog site is in the very same area of interest as yours and my users would definitely benefit from some of the information you provide here. Please let me know if this okay with you. Thanks!

  14. Toms Outlet Online Louis Vuitton Outlet Online Kevin Durant Shoes For Sale Louis Vuitton Outlet Store Kate Spade Outlet Online Kate Spade Outlet Online Spinfile-C:\Dropbox\Keywords\Websites\Celinebag.Us.Com.Txt Prada Handbags Coach Outlet Online Michael Kors

  15. I know this if off topic but I’m looking into starting my own weblog and was wondering what all is required to get setup? I’m assuming having a blog like yours would cost a pretty penny? I’m not very web smart so I’m not 100% positive. Any tips or advice would be greatly appreciated. Thanks

  16. Howdy I am so thrilled I found your site, I really found you by error, while I was looking on Aol for something else, Nonetheless I am here now and would just like to say thanks a lot for a marvelous post and a all round enjoyable blog (I also love the theme/design), I don’t have time to browse it all at the minute but I have saved it and also added your RSS feeds, so when I have time I will be back to read a great deal more, Please do keep up the fantastic work.

  17. I just want to mention I’m beginner to blogging and site-building and actually liked this blog site. Likely I’m going to bookmark your blog . You definitely have terrific article content. Kudos for sharing with us your website.

  18. I simply want to tell you that I am very new to blogs and truly liked this page. Probably I’m planning to bookmark your site . You amazingly have terrific article content. Regards for sharing with us your website.

  19. After looking into a number of the blog articles on your site, I honestly like yourway of writing a blog. I bookmarked it to my bookmark site list and will bechecking back soon. Please check out my web site tooand tell me what you think.

  20. You really make it seem really easy with your presentation however I to find this matter to be really something which I believe I might by no means understand. It sort of feels too complicated and extremely huge for me. I am looking forward on your subsequent publish, I will try to get the cling of it!

Leave a Reply

Your email address will not be published.