【问题标题】:How may I workaround this failure of alpha?我该如何解决这个 alpha 的失败?
【发布时间】:2016-06-17 20:55:15
【问题描述】:

根据 Z 顺序,如何解决密度求和失败的问题?

void setup() {
  size(600, 480, P3D);
}

void draw()
{
  background(0); 

  translate(width/2, height/2);
  stroke(color(255,255,255),128); // 50% alpha
  strokeWeight(130.0);

  point(0,0,0);
  point(-100,0,1); // density sums http://i.imgur.com/NfFv9SJ.png - expected
  point(100,0,-1); // density does not sum http://i.imgur.com/Eyq2qdZ.png - unexpected
}

在 V3 上测试。

【问题讨论】:

  • 我认为你的 cmets 倒退了。第二个point() 是右侧的行为异常的那个。第三个point() 是左侧的行为符合预期的那个。不过很有趣的问题。
  • Processing.js 做了类似的事情,尽管它将其巨大的点呈现为正方形而不是圆形。 Here 是一个可以玩的画板。
  • “我认为你的 cmets 倒退了”谢谢 - 已修复。
  • "它将大点呈现为正方形而不是圆形" 感谢您的警告。提醒一下我避免使用 processing.js 的原因很有用 :)
  • 就像我在您的其他一个问题中所说的那样,Processing.js 将它们绘制为正方形这一事实并不是真正的错误。一个像素在放大 130 倍后应该是什么形状并没有明确的定义。我可以看到圆形或正方形的论据。顺便说一句,我在你的问题中添加了opengl 标签,也许有 OpenGL 背景的人可以用你理解的方式解释发生了什么。

标签: opengl processing


【解决方案1】:

这和your other question是一样的问题。

我在您的另一个问题中对此进行了更详细的解释,但请记住,处理使用 深度缓冲 来确定何时 绘制已绘制像素后面的像素。

假设您要绘制两个点:一个在0,0,0,另一个在第一个前面0,0,100。以下是 OpenGL 的作用:

  • 获取在0,0,0处绘制第一个点的请求
  • 看到尚未绘制任何内容,因此绘制该点。
  • 获取在0,0,100处绘制第二个点的请求
  • 看到第一个点这个新点之后,所以绘制这个新点。

这就是左点起作用的原因。它在中间点的前面,然后你在画它。

但是,如果您遇到相反的情况,请再说两点:一个在 0,0,0,另一个 BEHIND 第一个在 0,0,-100。以下是 OpenGL 的作用:

  • 获取在0,0,0处绘制第一个点的请求
  • 看到尚未绘制任何内容,因此绘制该点。
  • 获取在0,0,-100处绘制第二个点的请求
  • 看到第一个点这个新点之前,所以跳过绘制这个新点。

您的代码中混合了第一种情况和第二种情况。你画出中心点,画得很好。然后,您将左点 绘制在中心点的前面,这样就可以正常工作了。但是然后您尝试在中心点后面绘制正确的点,但这是行不通的。 你必须从后往前画。

如果你使用不同的颜色,这会变得更加明显:

  //red middle
  stroke(255, 0, 0 ,128);
  point(0,0,0);

  //green left front
  stroke(0, 255, 0 ,128);
  point(-100,0,1);

  //blue right back
  stroke(0, 0, 255 ,128);
  point(100,0,-1); 

这里我们看到你在中间画了一个红点,然后在它前面画了一个绿点,这样就可以了。然后,您尝试在其后面绘制蓝点,但这不起作用。 OpenGL看到它已经在蓝点前面画了一个红点,所以跳过它。

这适用于不透明对象,但不适用于透明对象,这就是您遇到这么多麻烦的原因。 你必须把东西拉回前面。

通常您可以只使用hint(ENABLE_DEPTH_SORT),但在这种情况下这不起作用。这些可能看起来像圆圈,但事实并非如此。它们是您正在制作的巨大像素。这也是 Processing.js 将它们绘制为正方形而不是圆形的原因——这并不是一个真正的错误,因为您可以将“一个像素放大 130 次”的情况设为正方形或圆形。无论如何,Processing 似乎不会为您对像素的子像素进行排序。

您有三个选择:

选项 1:停止使用透明度。这就是你所有问题的原因。

选项 2: 自己进行排序。如果您从后向前绘制像素,您的问题就会消失:

  //blue right back
  stroke(0, 0, 255 ,128);
  point(100,0,-1); 

  //red middle
  stroke(255, 0, 0 ,128);
  point(0,0,0);

  //green left front
  stroke(0, 255, 0 ,128);
  point(-100,0,1);

选项 3: 自己动手做。你依靠strokeWeight() 来画大点。这不起作用,因为 Processing 的内置排序算法无法为您处理这个问题。相反,使用更规则大小的像素自己绘制大形状。 the reference 中有很多用于构建 3D 形状的函数。

【讨论】:

  • 您可能会认为面向图形的语言在版本 3 中就已经具备了这些基础知识,不是吗?为第 4 版祈祷。
  • @ChrisJJ 这不是真正的处理问题。这是一个OpenGL问题。它的工作方式与设计完全一致。我同意它的行为并不完全明显,但它也不是一个真正的错误。我很想知道为什么我被否决了。我认为你的问题很好,我认为我回答得很好。我猜这是因为您不喜欢答案,但这并不代表它不正确。嘿,我没有设计 OpenGL!不要把它拿在我身上!
  • “它的工作方式与设计完全一致。”如果您建议此处的处理按预期进行,那么我希望看到支持该主张的证据。我在处理文档中看不到任何表明这种行为是有意的。
  • @ChrisJJ 我已经回答了你好几次了,向你展示了 OpenGL 文档,它表明这正是它的设计工作方式。如果您认为这是一个错误,请随时提交错误报告,但我已经尝试解释它不是。但是,如果您要做的只是忽略我并否决我的答案,因为您不喜欢这种情况的现实,那么我将把时间花在其他地方。祝你好运。
猜你喜欢
  • 2020-02-29
  • 1970-01-01
  • 2010-12-16
  • 2023-01-30
  • 1970-01-01
  • 1970-01-01
  • 2021-07-26
  • 2021-01-09
  • 1970-01-01
相关资源
最近更新 更多