I know that I can perform a transformation(rotation,scale) in the vertex shader. However I wonder if I can do the similar thing in the fragment
shader.
shadertoy.com - transformation_in_fragment_shade
I tried to apply transformation in fragment shader by multiply the uv
but being confused by the result.
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.xy;
uv = fract(uv * 2.);
vec4 img = texture(iChannel0, uv);
// Output to screen
fragColor = img;
}
I expected the image will be scaled by 2x instead of zoom out, and I'm also confused by the meaning of fract
here, why apply this function can split image into 4 chunks.
So the question is, can I apply rotation or scaling in the fragment shader here? Should I use different approach to do the rotation, scaling here?
Texture coordinates are in range [0.0, 1.0]. (0, 0) is the bottom left and (1, 1) is the top right. The texture
looks up the texture at a particular coordinate and returns the color from that coordinate.
If you multiply the texture coordinates by 2, the coordinates will be in the range [0.0, 2.0]. The coordinates from 1.0 to 2.0 are not on the texture and clamped to 1.0.
The fract
function skips the integral part. For example, 1.5 becomes 0.5. So uv = fract(uv * 2.)
maps the coordinates from the interval [0.0, 1.0] to 2 intervals [0.0, 1.0], [0.0, 1.0].
If you want to zoom in (2x) to the center you need to project the texture between the coordinates (0.25, 0.25) and (0.75, 0.75) in the view:
uv = uv / 2.0 + 0.25; // maps [0.0, 1.0] to [0.25, 0.75]
You can do the same with a 3x3 matrix:
mat3 zoom = mat3(
vec3(0.5, 0.0, 0.0),
vec3(0.0, 0.5, 0.0),
vec3(0.25, 0.25, 1.0));
uv = (zoom * vec3(uv, 1.0)).xy;