Link Search Menu Expand Document

Drawing a Circle

Enter the following code into the editor:

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
  // Compute coordinates that range from x = -1 to 1 and y = -1 to 1.
  vec2 uv = fragCoord / iResolution.xy;
  uv = 2. * (uv - 0.5);

  // The signed distance to the edge of a circle.
  float radius = 0.8 + 0.1 * sin(6.28318530 * iTime / iDuration);
  float circleDist = length(uv) - radius;

  // Compute the color of the pixel as a mix of red and blue,
  // depending on the distance to the circle.
  vec3 col = mix(
    vec3(0.800, 0.184, 0.277),  // red
    vec3(0.049, 0.111, 0.215),  // dark blue
    smoothstep(0., 2. / iResolution.x, circleDist)
  );

  fragColor = vec4(col, 1.0);
}

Click the build button, or press shift+enter to recompile the code. Press play to see a pulsing circle. Read the comments to understand how each pixel is colored depending on whether it is computed to be inside or outside the circle.

Using textures

Let’s draw the circle using a texture, rather than a flat color. Replace the definition of col with:

vec3 col = mix(
  texture(iTexture0, uv).rgb,  // red
  vec3(0.049, 0.111, 0.215),  // dark blue
  smoothstep(0., 2. / iResolution.x, circleDist)
);

Recompile, to see a black square. Open the Textures tab, and change iTexture0 from a black texture to something else.

Using a texture

Textures are accessed using the texture function, and they are mapped to x = 0 to 1 and y = 0 to 1, repeating at every integer. You can use textureSize to get the dimensions of any texture in pixels.

Manipulating UV Coordinates

A common trick in shader programming is to achieve effects by manipulating the coordinate system itself.

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
  // Compute coordinates that range from x = 0 to 1 and y = 0 to 1.
  vec2 uv = fragCoord / iResolution.xy;

  // Manipulate the uv coordinates.
  float scale = 2.0;
  vec2 offset = vec2(0.5, 0.5);

  uv = scale * (uv - offset);

  // The signed distance to the edge of a circle.
  float radius = 0.8 + 0.1 * sin(6.28318530 * iTime / iDuration);
  float circleDist = length(uv) - radius;

  // Compute the color of the pixel as a mix of red and blue,
  // depending on the distance to the circle.
  vec3 col = mix(
    texture(iTexture0, uv).rgb,  // red
    vec3(0.049, 0.111, 0.215),  // dark blue
    smoothstep(0., 2. / iResolution.x, circleDist)
  );

  fragColor = vec4(col, 1.0);
}

Note that the uv coordinates are manipulated with an offset and a scale factor. Play with these values to observe their effects. (Clicking on their values brings up a UI that allows you to dynamically modify them in the code).

We can also cause the image to tile by appling fract or mod to the uv variable. For example, you can draw 16 × 16 circles on the canvas using:

// Manipulate the uv coordinates.
float scale = 16.;
uv *= scale;
uv = fract(uv);
uv = 2. * (uv - 0.5);

This is much more efficient than computing circleDist for all 256 circles.

256 circles

Next


Copyright © 2020-2021 smoothstep.io.