Shader help - how to flip axes?

Ive copied https://webgl-shaders.com/badtv-example.html (you can download all source files there and https://github.com/jagracar/webgl-shader-examples), and this determines the strength of the effect, apparently by x axis.

If mouse is at center screen, theres no effect but at either end, effect is strong. INSTEAD What I need is this, determined by y axis and only at bottom section:

Ive tried changing the x and y values in strength like:

float strength = (0.3 + 0.7 * noise1d(0.3 * u_time)) * u_mouse.y / u_resolution.x;

float strength = (0.3 + 0.7 * noise1d(0.3 * u_time)) * u_mouse.x / u_resolution.y;

From:

	<script type="x-shader/x-fragment" id="fragmentShader">
#define GLSLIFY 1
// Common uniforms
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
uniform float u_frame;

// Texture uniforms
uniform sampler2D u_texture;

// Texture varyings
varying vec2 v_uv;

/*
 * Random number generator with a float seed
 *
 * Credits:
 * http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0
 */
highp float random1d(float dt) {
    highp float c = 43758.5453;
    highp float sn = mod(dt, 3.14);
    return fract(sin(sn) * c);
}

/*
 * Pseudo-noise generator
 *
 * Credits:
 * https://thebookofshaders.com/11/
 */
highp float noise1d(float value) {
	highp float i = floor(value);
	highp float f = fract(value);
	return mix(random1d(i), random1d(i + 1.0), smoothstep(0.0, 1.0, f));
}

/*
 * Random number generator with a vec2 seed
 *
 * Credits:
 * http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0
 * https://github.com/mattdesl/glsl-random
 */
highp float random2d(vec2 co) {
    highp float a = 12.9898;
    highp float b = 78.233;
    highp float c = 43758.5453;
    highp float dt = dot(co.xy, vec2(a, b));
    highp float sn = mod(dt, 3.14);
    return fract(sin(sn) * c);
}

/*
 * The main program
 */
void main() {
	// Calculate the effect relative strength
	float strength = (0.3 + 0.7 * noise1d(0.3 * u_time)) * u_mouse.x / u_resolution.x;
		//float strength = (0.3 + 0.7 * noise1d(0.3 * u_time)) * u_mouse.x / u_resolution.x;

	// Calculate the effect jump at the current time interval
	float jump = 500.0 * floor(0.3 * (u_mouse.x / u_resolution.x) * (u_time + noise1d(u_time)));

	// Shift the texture coordinates
	vec2 uv = v_uv;

	uv.y += 0.2 * strength * (noise1d(5.0 * v_uv.y + 2.0 * u_time + jump) - 0.5);
	uv.x += 0.1 * strength * (noise1d(100.0 * strength * uv.y + 3.0 * u_time + jump) - 0.5);
	// uv.y += 0.2 * strength * (noise1d(5.0 * v_uv.y + 2.0 * u_time + jump) - 0.5);
	// uv.x += 0.1 * strength * (noise1d(100.0 * strength * uv.y + 3.0 * u_time + jump) - 0.5);

	// Get the texture pixel color
	vec3 pixel_color = texture2D(u_texture, uv).rgb;

	// Add some white noise
	pixel_color += vec3(5.0 * strength * (random2d(v_uv + 1.133001 * vec2(u_time, 1.13)) - 0.5));

	// Fragment shader output
	gl_FragColor = vec4(pixel_color, 1.0);
}

But the shader remains how it was. How can I achieve this?

How about something like this: https://jsfiddle.net/n9k1p5w4/

The idea is to use step() to define the screen area which should be affected by the flicker.

2 Likes

Thank you so much for both your answers, incredible help!
For whatever reason when I copy this over, it works backwards. So there is no effect only at the bottom of the screen. I’m currently changing the 0.8, but can only affect the top of the screen or the whole screen. Do you know why this is?

1 Like

Take a look at the onMouseMove event handler. The implementation might be different compared to your code.

1 Like

That was it, thanks!