【问题标题】:PGraphics + noSmooth() + alpha = drawing artifactsPGraphics + noSmooth() + alpha = 绘图工件
【发布时间】:2019-01-28 18:36:05
【问题描述】:

注意:我也在处理论坛here上问过这个问题。

我有这个示例代码:

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);
}

我希望这段代码在用户按下鼠标的任何地方都显示一个点。相反,我只能看到几个矩形区域中的点:

如果我删除了对pg.noSmooth() 的调用,或者如果我删除了pg.stroke() 调用中的alpha 值,那么它可以正常工作:

如果我用pg.ellipse()pg.rect() 替换pg.point() 调用,那么它也可以正常工作。

似乎使用PGraphicsnoSmooth() 函数、point() 函数和 alpha 值的组合会导致这种错误行为。我在 Processing 3.3 和 Processing 3.5.2 中进行了尝试,我发现两者的行为相同。

我是否遗漏了一些明显的东西?

【问题讨论】:

  • 看起来确实是 noSmooth() 导致了这个问题。 FAIK,对于 PGraphics,您应该在 beginDraw() endDraw() 调用中调用它。可能是 Java2D 渲染器的错误
  • @GeorgeProfenza 嘿,乔治!有趣的是,如果我将调用 pg.noSmooth() 移动到调用 pg.beginDraw() 之后,我会收到一条警告说 smooth() can only be used before beginDraw() 并且调用被忽略(一切仍然是抗锯齿的)。
  • Hey Kevin :) 关于pg.noSmooth(),你是对的,我的错,反其道而行之。我得说这是个奇怪的错误。
  • @GeorgeProfenza 是的,docs 同意你的第一句话,smooth() / noSmooth() 应该在 beginDraw()endDraw() 之间调用。这可能是文档过期的一个单独问题?
  • FWIW,P2D 渲染器(((PGraphicsOpenGL) g).textureSampling(2); 并据我所知FX2D 渲染器doesn't have smooth 不会出现此问题?这似乎是与单独的 Java2D 渲染器

标签: processing pgraphics


【解决方案1】:

经过一点点挖掘,JAVA2D 渲染器绘制了一个非常非常 非常 small spacingstatic final float EPSILON = 0.0001f;)。我的猜测是这种特殊配置,缺少锯齿可能意味着这条对角线的两个点都落在同一个像素上,最终不会在右上角区域渲染。我不知道为什么是那个区域以及为什么会出现这么短的距离,但这听起来有点像 Jakub Valtar 和 Andres Colubri 不得不处理的头痛问题。

FWIW 这里有一个 hacky 解决方法:使用更大的距离来渲染透明且没有锯齿:

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 的东西都会再次出现故障。

【讨论】:

  • 这是一个很好的答案,感谢您的研究!情况似乎确实如此——如果我们使用嵌套的 for 循环来用点填充PGraphics,它会变得更加明显。有趣的是,如果我删除 alpha 参数,我就根本看不到点,即使是 0.75 的 epsilon。我要将此信息添加到the bug。再次感谢乔治!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 2021-10-14
  • 2011-02-06
  • 2012-06-26
  • 1970-01-01
相关资源
最近更新 更多