1. Hey! Guest! The 36th GMC Jam will take place between February 27th, 12:00 UTC - March 2nd, 12:00 UTC. Why not join in! Click here to find out more!
    Dismiss Notice
  2. NOTICE: We will be applying a Xenforo update on Tuesday 25th of February. This means that from approximately 10:00 to 14:00 BST the forums will be offline (or possibly longer). Sorry for the inconvenience! Official Announcement here.

Shaders Distortion Shader offsets the texture

Discussion in 'Programming' started by kupo15, Jan 28, 2020.

  1. kupo15

    kupo15 Member

    Joined:
    Jun 20, 2016
    Posts:
    925
    I'm trying to learn some shader stuff, first I'd thought about learning the simple distortion shader. It works but I also got a strange side effect that isn't good. When I apply the strength of the shader to the texture, the texture shifts instead of staying in place. Is this intended or am I doing something wrong? How do I keep the effect without shifting the texture and revealing the stretch marks?

    https://imgur.com/z94cbrw
     
  2. IGameArt

    IGameArt Member

    Joined:
    Jun 21, 2016
    Posts:
    171
    Paste your shader code please.
     
  3. squircle

    squircle Member

    Joined:
    Nov 17, 2019
    Posts:
    3
    I can't test it right away, so sorry if this is the incorrect solution, but have you checked out gpu_set_texrepeat (link)?
     
  4. kupo15

    kupo15 Member

    Joined:
    Jun 20, 2016
    Posts:
    925
    Here you go, I probably should have mentioned it was also in the video
    upload_2020-1-28_8-51-42.png
    I didn't look into that though I was wondering if that was something I needed to do. I checked the "tile" boxes in the sprite editor and that did nothing. If that is what is needed that would be great, though it would also be nice to know if its expected that the texture is to be offset. I'm expecting that I should be able to draw the texture at the coor I want without having to counter an offset
     
  5. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,523
    that's probably because all you distrotion ammounts are positive, so the average shift is not 0. (your random values are 0-1)
    what you want are random values -1 - 1.
    just add this snippet to (hopefully) improve things:
    Code:
    distort = (distort * 2) - 1;
    

    but really its gonna depend on what is in that distortion texture and time value.
    (by just adding time it seems you will just end up with a scrolling texture)
     
    squircle and kupo15 like this.
  6. kupo15

    kupo15 Member

    Joined:
    Jun 20, 2016
    Posts:
    925
    Oh awesome, that must be it and it makes sense, thanks!. Can't wait to get home and give it a try. And yeah you are right, I'm just trying to create a scrolling texture with this example
     
  7. kupo15

    kupo15 Member

    Joined:
    Jun 20, 2016
    Posts:
    925
    This didn't work and looking further into it, this applies to the distortion texture and not the stone texture. I realized my shader code takes into account tiling with the fract part so its never sampling outside of the range


    This didn't work and gave me this. Adjusting the strength tab (bottom one) still moved the stone texture around as well. The sliders from top to bottom are time, scale and strength
    [​IMG]


    upload_2020-1-28_16-42-0.png

    @The Reverend Any thoughts? I was using your tutorial as a guide to learning this
     
    Last edited: Jan 28, 2020
  8. GMWolf

    GMWolf aka fel666

    Joined:
    Jun 21, 2016
    Posts:
    3,523
    What is in your distortion texture?
    Why are you sampling it at two different points for the X and y component?
     
  9. kupo15

    kupo15 Member

    Joined:
    Jun 20, 2016
    Posts:
    925
    It's just a grayscale noise map. Part of it is shown in the image.

    Im honestly not sure, I was trying to pull what I could from the reverend's haze shader tut but it's possible I used stuff I didn't need now you mention it. He used color channels in addition to gray scale map I think? All im trying to do is a scrolling noise texture and sample that to distort the image.

    Do I have extra code in there that i don't need to do that? I do find it weird the stone texture shakes around when the strength is at 0 (without distortion of course)
     
  10. Ido-f

    Ido-f Member

    Joined:
    Feb 19, 2018
    Posts:
    146
    Distort in your original code ranges between (0,0) to (1*strength, 1*strength*1.3).
    I also think GMwolf's idea is a good try, but "distort = distort*2 - 1" doesn't quite get you to the (-1, -1) to (1,1) range, as it's not in (0,0) to (1,1) in the first place.

    if instead of multiplying by strength you'll use pow(scrolling_noise_tex_value, 1/strength), the result will be kept at 0 to 1 (while getting closer to 1 the higher strength is).
    (edit: It's a problematic idea though because you won't be able to have strength=0 then, so maybe find another way to normalise it).

    Then you can apply distort = distort*2 - 1 and get that (-1,-1) to (1,1) range.
    Not sure it solves your problem, but it's worth a try, I think.
     
    Last edited: Jan 28, 2020
  11. Ido-f

    Ido-f Member

    Joined:
    Feb 19, 2018
    Posts:
    146
    Ok, so you want distort on either negative or positive.
    You also want strength to affect how far distort is from 0, rather than just make it a higher number.

    Multiplying by strength a value that is still in the 0 to 1 range will always increases or always decreases the final distort value, even if you remap it to the -1 to 1 range afterwards (for example, a strength of 1.5 would get a noise texture value from 0.2 from 0.3. When remmaped to -1 to 1, 0.2 would have resulted at -0.6, but instead we got 0.3 that remmaped to -0.4. So a large strength value actually reduces the distort effect for negative distort).

    So what I think you could do is sample the noise texture offset by time, like you did, but don't apply the strength uniform yet.
    instead apply "distort = distort*2 -1" first, which gets it to (-1, 1).
    Only then apply distort *= (strength, strength*1.3).

    I don't know if it will keep the same distortion feeling, but I believe it will solve the final image being shifted around issue.
     
    Last edited: Jan 28, 2020
  12. kupo15

    kupo15 Member

    Joined:
    Jun 20, 2016
    Posts:
    925
    Ok I think I figured out what's going on and what's SUpposed to happen. I believe you all were correct initially AND either GM's shader is wrong, this youtuber (which is amazing nonetheless) is wrong or both is correct and Nintendo's shader works differently....OR all the shaders work the same except Nintendo modified to what @GMWolf initially said about the -1 to 1. My guess is that all shaders work the same and that Nintendo created their code to be offset by 0.5 so that middle gray did nothing


    According to the video, the displacement shader moves everything up left for pure black and downright for pure white. However, GM's pure black does nothing and pure white pulls downright twice the distance. So that was confusion #1

    Lastly, the purple border is correct behavior after all. I modified the output line to include the Fract() code to double make sure the texture was repeating and that solved the purple issue. Confusion #2 is that I thought this issue was fixed in the distort setting lines, I'm still not sure why that didn't work unless both are needed?

    So to recap, the purple issue was due to running outside the tex coor and it wasn't acting like a repeating, tiled texture until I added that fract() in the output line
    The shifting movement wasn't exactly lining up (or rather, was shifting too much) because it was uncentered going from 0-1. I was using a texture map designed to shift from -0.5-0.5.

    I'm going to make these changes and post the result here, if anyone can answer why the distort setting lines didn't mimick the repeating pattern or if fract() is needed in both places and why/why not, that would be good to know!
     
    Last edited: Jan 29, 2020
  13. kupo15

    kupo15 Member

    Joined:
    Jun 20, 2016
    Posts:
    925
    Alright, figured it out with all your help! Thanks guys!
    https://imgur.com/HiO3aAn

    Code:
    //
    // Simple passthrough fragment shader
    //
    varying vec2 v_vTexcoord;
    varying vec4 v_vColour;
    uniform sampler2D distort_tex;
    uniform float time;
    uniform float size;
    uniform float strength;
    uniform float result;
    void main()
    {
        vec2 distort;
        distort.x = (texture2D(distort_tex,fract(v_vTexcoord *  size  +  vec2(0.0,time))).r - 0.5)   *  strength;
        distort.y = (texture2D(distort_tex,fract(v_vTexcoord *  size *  3.4 +   vec2(0.0,time  *  1.6))).r - 0.5)  *  strength  *  1.3;  
      
        gl_FragColor = v_vColour * texture2D( gm_BaseTexture, fract(v_vTexcoord + distort));
      
       // gl_FragColor.rgb = mix(vec3(distort/max(strength,0.0001), 0.0), gl_FragColor.rgb,result);
    }
    
    
     
  14. rIKmAN

    rIKmAN Member

    Joined:
    Sep 6, 2016
    Posts:
    5,043
    Interesting video, thanks for linking it kupo.

    Nice work with your shader (and the other responders) - final result looks good!
     
    kupo15 likes this.
  15. kupo15

    kupo15 Member

    Joined:
    Jun 20, 2016
    Posts:
    925
    Thanks and your welcome! Between that and his recent WW video, those are some good learning experiments to duplicate I'm currently doing.

    I'm going to build out the scene more, kinda half recreate that scene to experiment and explore more. Looking forward to sharing that when its further along!
     

Share This Page