PGraphics + noSmooth () + alpha = рисование артефактов - PullRequest
0 голосов
/ 28 января 2019

Примечание: Я также задавал этот вопрос на форуме по обработке здесь .

У меня есть этот пример кода:

PGraphics pg;

void setup() {
  size(400, 500);
  pg = createGraphics(width, height);

  pg.noSmooth();
  pg.beginDraw();
  pg.background(0, 0, 255);
  pg.endDraw();
}

void draw() {

  if (mousePressed) {
    pg.beginDraw();
    pg.stroke(255, 254);
    pg.point(mouseX, mouseY);
    pg.endDraw();
  }

  image(pg, 0, 0, width, height);
}

Iожидается, что этот код покажет точку, где пользователь нажимает мышь.Вместо этого я могу видеть только точки в нескольких прямоугольных областях:

buggy window

Если я удалю вызов на pg.noSmooth() или если я удалю альфа-значение в pg.stroke() вызовите, тогда он работает нормально:

working window

Если я заменим вызов pg.point() на pg.ellipse() или pg.rect(), то он также будет работать нормально.

Кажется, что комбинация использования PGraphics, функции noSmooth(), функции point() и значения альфа приводит к этому ошибочному поведению.Я пробовал в обработке 3.3 и обработке 3.5.2, и я вижу одинаковое поведение в обоих.

Я что-то упускаю очевидное?

1 Ответ

0 голосов
/ 29 января 2019

После небольшого откапывания получается, что средство визуализации JAVA2D рисует точку в виде диагональной линии (line(x, y, x + EPSILON, y + EPSILON);) с очень очень очень небольшой интервал (static final float EPSILON = 0.0001f;).Я предполагаю, что именно в этой конфигурации отсутствие наложения может означать, что обе точки этой диагональной линии окажутся на одном пикселе и в конечном итоге не будут отображаться в верхней правой области.Почему эта область и почему это небольшое расстояние, я не знаю, но это звучит немного похоже на головные боли Якубу Валтару , и Андрес Колубри должен был иметь дело с этим.: используя большее расстояние, которое визуализируется с прозрачностью и без наложения:

PGraphics pg;

void setup() {
  size(400, 500);
  noSmooth();

  pg = createGraphics(width/20, height/20);
  pg.beginDraw();
  // just for debug purposes: rectangle with edge
  pg.fill(0, 0, 255);
  pg.rect(0,0,pg.width-1,pg.height-1);
  pg.stroke(255,255,255, 128);
  pg.endDraw();

}

void pointNoSmooth(PGraphics pg, float x,float y){
  pg.beginShape();
  pg.vertex(x,y);
  pg.vertex(x + 0.75,y);//any less than 0.75 distance between vertices and there's nothing to render with aliasing
  pg.endShape();
}

void draw() {
  background(255);
  if (mousePressed) {
    pg.beginDraw();
    pointNoSmooth(pg,mouseX,mouseY);
    pg.endDraw();
  }
  // render upscaled
  image(pg, 0, 0, width, height);
  // render small preview in TL corner
  image(pg,0,0);
}

Обратите внимание, что я установил разрешение PGraphics в 20 раз меньше, затем нарисовал его в увеличенном масштабе, чтобы было легче увидеть, где приземляются пиксели.на PGraphics.Однако я не масштабирую координаты mouseX,mouseY, поэтому при тестировании вам нужно будет нарисовать небольшой верхний левый предварительный просмотр.Это 0.75 расстояние делает свое дело: из того, что я проверил, все, что меньше 0.7499995, снова начинает работать с ошибками.

...