• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Shaders Distortion Shader offsets the texture

kupo15

Member
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
 

kupo15

Member
Paste your shader code please.
Here you go, I probably should have mentioned it was also in the video
upload_2020-1-28_8-51-42.png
I can't test it right away, so sorry if this is the incorrect solution, but have you checked out gpu_set_texrepeat (link)?
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
 

GMWolf

aka fel666
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)
 

kupo15

Member
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)
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
 

kupo15

Member
I can't test it right away, so sorry if this is the incorrect solution, but have you checked out gpu_set_texrepeat (link)?
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


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)
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



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:

GMWolf

aka fel666
What is in your distortion texture?
Why are you sampling it at two different points for the X and y component?
 

kupo15

Member
What is in your distortion texture?
Why are you sampling it at two different points for the X and y component?
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)
 

Ido-f

Member
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:

Ido-f

Member
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:

kupo15

Member
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.
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:

kupo15

Member
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);
}
 

kupo15

Member
Interesting video, thanks for linking it kupo.

Nice work with your shader (and the other responders) - final result looks good!
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!
 
Top