Distortion Shader strange behaviour

I’m trying to test a distortion shader but I’m having a really strange behaviour. The effect, at the start is fine but it begins to disappear diagonally.

The material definition:

MaterialDef Distortion {
    MaterialParameters {
        Texture2D ColorMap
        Texture2D NoiseMap
    }

    Technique {
        VertexShader GLSL100: MatDefs/Distortion/Distortion.vert
        FragmentShader GLSL100: MatDefs/Distortion/Distortion.frag

        WorldParameters {
            WorldViewProjectionMatrix
            Time
        }
    }
}

The vertex shader is:

attribute vec3 inPosition;
uniform mat4 g_WorldViewProjectionMatrix;
attribute vec2 inTexCoord;
varying vec2 texCoord1;

/**
 * Vertex Shader
 */
void main() {
    texCoord1 = inTexCoord;
    gl_Position = g_WorldViewProjectionMatrix * vec4(inPosition, 1.0);
}

And the fragment one:

uniform sampler2D m_ColorMap;
uniform sampler2D m_NoiseMap;
uniform float g_Time;
varying vec2 texCoord1;

/**
 * Fragment Shader
 */
void main (void)
{
   vec3 noiseVec;
   vec2 displacement;
   float scaledTimer;

   scaledTimer = g_Time*0.1;

   displacement = texCoord1.st;
   displacement.x += scaledTimer;
   displacement.y -= scaledTimer;

   noiseVec = normalize(texture2D(m_NoiseMap, displacement.xy).xyz);
   noiseVec = (noiseVec * 2.0 - 1.0) * 0.035;

   gl_FragColor = texture2D(m_ColorMap, texCoord1.st + noiseVec);
}

In the application:

        Box b = new Box(2, 2, 2);

        Geometry geom = new Geometry("Shaded Geometry", b);
        Material mat = new Material(assetManager,"MatDefs/Distortion/Distortion.j3md");
        mat.setTexture("NoiseMap", assetManager.loadTexture("Textures/distortion_noise.jpg"));
        mat.setTexture("ColorMap", assetManager.loadTexture("Textures/distortion_noise.jpg"));
       
        geom.setMaterial(mat);
        rootNode.attachChild(geom);

I just translated it from here (the noise map is the one in the site).
I’m just a newbie on shaders and I can’t fully understand how they work (I though I know but the problem I’m experimenting with this one is against that thoughts).
I can see that displacement part is the one that is causing the strange behaviour, but I don’t know why.

Any help is welcome.

For starters you have:

gl_FragColor = texture2D(m_ColorMap, texCoord1.st + noiseVec);

that might need to be:

gl_FragColor = texture2D(m_ColorMap, texCoord1.st + noiseVec.xy);

And you can get rid of the .st on texCoord1. texCoord1 is a vec2, the only time you really need to specify which elements of the vector you’re working on is when you’re not working on all of them so texCoord1 + noiseVec.xy = texCoord1.st + noiseVec.xy

noiseVec is a vec3 and you only want to add the first two elements of the 3 element vector to the two element vector texCoord1. texCoord1 + noiseVec = texCoord1 + noiseVec.xyz, but you want just the x and y elements of noiseVec so you want texCoord1 + noiseVec.xy

You are right, I didn’t realize on those (that part I can understand) but the resulting effect is the same with that changes. The same diagonally disappear through the time problem.

I’m not sure what you mean by diagonally disappear, can you post a couple of screen shots showing what it looks like at first, when it works, and then what it looks like after it stops working?

You know what, it occurred to me that you may need to set the texture wrap mode:

 Box b = new Box(2, 2, 2);
    
 Geometry geom = new Geometry("Shaded Geometry", b);
 Material mat = new Material(assetManager,"MatDefs/Distortion/Distortion.j3md");
 Texture noise = assetManager.loadTexture("Textures/distortion_noise.jpg");
 noise.setWrap(WrapMode.Repeat)
 mat.setTexture("NoiseMap", noise);
 mat.setTexture("ColorMap", noise);
           
 geom.setMaterial(mat);
 rootNode.attachChild(geom);

I guess I’m not sure if WrapMode.Repeat is the default mode or not.

It doesn’t change anything. I uploaded the testcase and three images so it’s clearer the behaviour.

Okay I set up my own test scene with all the code that you provided and experienced the same issue. Then I changed the wrap mode on the noise texture to WrapMode.Repeat and it worked.

You need to make sure that you’re setting the wrap mode on the noise texture, not the diffuse/color texture.

Texture noise = assetManager.loadTexture("Textures/distortion_noise.jpg");
noise.setWrap(WrapMode.Repeat);
mat.setTexture("NoiseMap", noise);
mat.setTexture("ColorMap", assetManager.loadTexture("Textures/diffuse.jpg"));

You also need to make sure that in the mat.setTexture(“NoiseMap”…) call you’re using the variable that you stored the loaded texture in, in this example “noise”, not doing another assetManager.loadTexture(…).

may be something useful in this post : Applying post effect to only selected objects + Screen Space Displacement Filter

    Material mat = new Material(assetManager,"MatDefs/Distortion/Distortion.j3md");
    Texture noise = assetManager.loadTexture("Textures/distortion_noise.jpg");
    noise.setWrap(WrapMode.Repeat);
    mat.setTexture("NoiseMap", noise);
    mat.setTexture("ColorMap", assetManager.loadTexture("Textures/diffuse.jpg"));

Ok, that’s weird, this code is just a copy/paste of the code I try. It’s giving me the same results. Maybe you changed anything more?.

Could you edit the post and update the code blocks so they are more readable?. That post may be help with some shaders I would like to have, thanks :wink:

Nevermind!. It worked. I was trying it using as “ColorMap” the same image that the noise so I had the same effect than before the wrap mode (Silly me). With different images it goes pretty fine and, analyzing it it makes sense :D.
Again, thanks very much, without your help I would hate shaders forever xD.

Glad I could be of assistance, I rather enjoy writing shaders myself and technically there was nothing wrong with your shader code :smile:

I know how it is though, when something’s not working and you’re sitting there staring directly at the problem for an hour and a half not seeing it then all of a sudden it hits you, make the simplest little change and voilà then you slam your hand against your face like wondering how you could’ve missed it after looking right at it that whole time heh.

I’d say a large percentage of time, for me at least, the biggest problems are caused by the simplest little thing, a - instead of +, forgotten break, an ‘if’ that should’ve been one line up or down…

Oddly enough it looks as though a lot of programmers are embarrassed by mistakes like those, but I mean come on, happens to all of us. No one is perfect, no need to pretend to be.

1 Like

sorted

1 Like