I am trying to get better with something as complex as glsl but it's taking some time to grasp certain concepts coming from a PHP/JS background.
In the following fragment shader code, I don't understand why are we getting a horizontal bar in the center?
The origin is shifted to the center, fine.
And when I +=
or -=
the uv.x
value, it's adding or subtracting the .x
value for each pixel. That is also understood as doing this moves the resultant circle around.
But when you change this -=
or +=
to just =
it should mean that every pixel gets its .x
value fixed to be .2
(in this case) which should give a messed up graphic as every pixel is moving itself to the .2
spot on x-axis? Could someone please explain in layman terms? Thanks.
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
void main(){
vec2 uv = gl_FragCoord.xy/u_resolution.xy;
uv.x *= u_resolution.x/u_resolution.y;
// Remap the space to -1. to 1.
uv = uv *2.-1.;
// The following will move the circle around
// uv.x += 0.2;
// uv.x -= 0.2;
// But why does this creates the horizontal bar?
uv.x = .2;
// Visualize the distance field
gl_FragColor = vec4(vec3(step( .3, length(uv))),1.0);
}
Short answer:
The result of length(vec2(0.2, uv.y))
is equal for all the pixels in one row.
The fragment shader is executed (concurrently) for each fragment and the built-in fragment shader input variable gl_FragCoord.xy
is different for each fragment. It ranges from (0, 0) for the bottom left fragment to (width, height) for the top right fragment. Therefore the uv
coordinate ranges from (-1aspect, -1) to (1acpect, 1).
vec2 uv = gl_FragCoord.xy/u_resolution.xy;
uv.x *= u_resolution.x/u_resolution.y;
The output color of the fragment shader depends on the uv
coordiante:
gl_FragColor = vec4(vec3(step( .3, length(uv))), 1.0);
length(uv)
calculates the length of the vector uv
. The result increases circularly starting from point (0, 0). If you add a constant to the components of the coordinates (e.g. length(vec2(uv.x + 0.2, uv.y - 0.2))
, the result still depends on the two components, resulting in a circle.
This changes if you set one component of the coordinate uv
to a constant value. Because then this component is no longer different for each fragment. Instead of setting uv.x = .2
, you can also replace the expression by length(vec2(0.2, uv.y))
. This way the result depends only on the y-component of the uv-coordinate, resulting in a bar instead of a circular shape.