Why are text and graphics so ugly and blocky?

Why are text and graphics so ugly and blocky?

Often in the forum we have similar questions:
"Why is the text so blocky?"
"Why these lines are not anti-aliased?"
"Why is this circle almost squarish?"

And when asked, the user shows code looking like:

void setup()
{
  size(400, 400);
  background(255);
}

void draw()
{
  stroke(#000055);
  fill(#000055);

  ellipse(width / 2, height / 2, width / 10, height / 10);

  textSize(50);
  text("Blocky\nText", 100, 2 * height / 3);
  textSize(10);
  text("Other\nText", 20, height / 3);

  line(100, 50, 300, 150);
  line(150, 150, 350, 100);
}

If you are an experienced user, you immediately spot the problem, and advise to move the call to background() at the start of draw();

void setup()
{
  size(400, 400);
}

void draw()
{
  background(255);
  stroke(#000055);
  fill(#000055);

  ellipse(width / 2, height / 2, width / 10, height / 10);

  textSize(50);
  text("Blocky\nText", 100, 2 * height / 3);
  textSize(10);
  text("Other\nText", 20, height / 3);

  line(100, 50, 300, 150);
  line(150, 150, 350, 100);
}

In versions before 2.0, adding a call to smooth() helped, but it is the default now.

Why does it makes a difference?

Processing does its drawings in anti-aliased mode: the borders are smoothed by drawing semi-transparent, toned down pixels on the borders, making a nicer transition with the background. draw() is called 60 times per second (by default). It doesn't erase the background if not asked explicitly. So it draws over and over the graphics at the same place. The semi-transparent pixels cumulate on the borders, so they progressively become completely opaque. Hence the blocky look with steps.

Nearly all the Processing sketches (except some special effects playing on the accumulation of graphics) start draw() with a call to background(). There can be exceptions, but they are the done by people understanding deeply how Processing works.

Comments

  • edited January 21

    Addendum: Pixel Graphics.

    By default any images will use bicubic interpolation when you enlarge them. Sometimes this isn't what you want, sometimes you want linear or nearest neighbour. This will do that

    PImage img = loadImage("someTinyImage.png");
    
    void setup() {
      size(500, 500, P2D);
      ((PGraphicsOpenGL)g).textureSampling(3); // the magic
    }
    
    void draw() {
      background(255);
      image(img, 0, 0, img.width * 20, ing.height * 20);  // 20 times bigger
    }
    

    from here:
    https://forum.processing.org/two/discussion/comment/22761/#Comment_22761

Sign In or Register to comment.