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!