当减小色彩深度并以2位噪声抖动(n =] 0.5,1.5 [并且output = floor(input *(2 ^ bits-1)+ n))时,值范围的两端(输入0.0和1.0 )很吵。希望它们是纯色。

示例:https://www.shadertoy.com/view/llsfz4


(以上是shadertoy的屏幕截图,描绘了一个渐变,并且两端分别应为纯白色和黑色,但噪声很大。

当然可以通过压缩值范围来解决问题,以便两端总是四舍五入为单个值。但是,这感觉有点hacker,我想知道是否有一种方法可以“正确”实现此功能?

评论

由于某种原因,shadertoy无法在我的浏览器上运行。您能张贴一张/一些简单的图像来说明您的意思吗?

不应该更像n =]-1,1 [?

@JarkkoL那么,将浮点转换为整数的公式为output = floor(input * intmax + n),其中n = 0.5,没有噪声,因为您希望(例如)> = 0.5向上取整,但<0.5向下取整。这就是为什么噪声在0.5处“居中”的原因。
@SimonF添加了shadertoy的图像

看来您是在截断输出而不是将其舍入(就像GPU一样)-而是舍入,至少可以得到合适的白色:shadertoy.com/view/MlsfD7(图片:i.stack.imgur.com/kxQWl.png) br />

#1 楼

TL; DR:由于夹持,在0和1的边缘情况下2 * 1LSB三角pdf抖动中断。一种解决方案是在那些边缘情况下使用1bit的统一抖动。看来这个问题是“待办事项:需要限制吗?”在我的代码中,因为我在2012年从规范化切换到三角抖动...。很高兴终于看到了它:)整个帖子中使用的解决方案/图像的完整代码:https://www.shadertoy.com/view/llXfzS

首先,这是我们要解决的问题,当使用2 * 1LSB三角-pdf抖动将信号量化为3位时:


-基本上是hotmultimedia所显示的。 。



查看图形可提供更多的见解:灰色是我们要输出的信号,黄线是抖动/量化输出的平均值,红色是误差(信号平均值)。

有趣的是,不仅平均输出没有极限为0/1,也不是线性的(如归因于噪声的三角形pdf)。观察下端,可以直观地看出输出为何会发散:随着抖动信号开始包含负值,钳位输出会更改输出的较低抖动部分的值(即负值),从而增加平均值。图示似乎井然有序(均匀,对称的2LSB抖动,平均仍为黄色):

现在,如果我们仅使用1LSB归一化抖动,在边缘情况下完全没有问题,但是然后我们当然失去了三角形抖动的良好特性(请参见本演示文稿)。



然后(一种实用的,经验的)解决方案(hack)将恢复为[-0.5; 0.5 [边缘抖动的均匀抖动:



 float dithertri = (rnd.x + rnd.y - 1.0); //note: symmetric, triangular dither, [-1;1[
float dithernorm = rnd.x - 0.5; //note: symmetric, uniform dither [-0.5;0.5[

float sizt_lo = clamp( v/(0.5/7.0), 0.0, 1.0 );
float sizt_hi = 1.0 - clamp( (v-6.5/7.0)/(1.0-6.5/7.0), 0.0, 1.0 );

dither = lerp( dithernorm, dithertri, min(sizt_lo, sizt_hi) );
 


修正边沿的情况,同时在剩余范围内保持三角抖动不变:



因此,请不要回答您的问题:我不知道是否存在数学上更可靠的解决方案,并且同样希望知道过去的大师们做了什么:)直到那时,至少我们有这个可怕的技巧来保持我们的代码正常运行。因为在边缘情况下平均值不是线性的,所以简单地压缩输入信号并不能产生理想的结果-尽管它确实可以修复端点:
/>
https://www.shadertoy.com/view/llXfzS
http://loopit.dk/rendering_inside.pdf
http://loopit.dk/banding_in_games.pdf
http://32ipi028l5q82yhj72224m8j-wpengine.netdna-ssl.com/wp-content/uploads/2016/03/GdcVdrLottes.pdf


评论


$ \ begingroup $
令人惊奇的是,边缘处的束带可以提供完美的外观效果。我希望至少有一点偏差:P
$ \ endgroup $
–艾伦·沃尔夫(Alan Wolfe)
17年12月4日在3:15

$ \ begingroup $
是的,我也很惊讶:)我相信它能奏效,因为我们正在线性减小抖动幅度,信号衰减的速率相同。因此,至少规模匹配...但是我同意,直接混合分布似乎没有负面影响是很有趣的。
$ \ endgroup $
– Mikkel Gjoel
17年12月17日在13:16

$ \ begingroup $
@MikkelGjoel不幸的是,由于代码中的错误,您的信念是错误的。您为dithertri和dithernorm重新使用了相同的RNG,而不是独立的RNG。一旦您完成所有数学运算并取消所有条款,您就会发现自己根本就没有忍耐力!取而代之的是,代码在v <0.5 /深度||时像硬截止。 v> 1-0.5 /深度,立即切换到那里的均匀分布。并不是说它可以消除您所拥有的良好抖动,它只是不必要地复杂了。修复错误实际上是不好的,您最终会得到更糟糕的抖动。只需使用硬性限制即可。
$ \ endgroup $
–orlp
19年4月19日在7:10



$ \ begingroup $
进行更深入的研究后,我在您的阴影中发现了另一个问题,即在对样本求平均时(在sRGB空间中不是线性的)求平均值时,您不进行伽玛校正。如果您正确地处理了伽玛,很遗憾,我们发现您还没有完成。我们必须调整噪声以应对伽玛校正。这是显示问题的shadertoy:shadertoy.com/view/3tf3Dn。我尝试了很多事情,但无法正常工作,所以我在这里发布了一个问题:computergraphics.stackexchange.com/questions/8793/…。
$ \ endgroup $
–orlp
19年4月23日在1:52

#2 楼

我不确定我能否完全回答您的问题,但是我会加一些想法,也许我们可以一起得出答案:)

首先,问题的根源对我来说还不清楚:为什么当其他每种颜色都有噪点时,为什么希望有干净的黑白?抖动后的理想结果是原始信号具有完全均匀的噪声。如果黑白不同,则您的噪音会随信号而变(这可能很好,因为无论如何都会在颜色被夹持的情况下发生)。

这就是说,在某些情况下,两种情况下都有噪音白色或黑色确实构成了一个问题(我不知道用例需要黑色和白色同时“干净”):当将添加混合的粒子渲染为带有纹理的四边形时,您不希望整个区域都添加噪声四边形,因为它也会显示在纹理外部。一种解决方案是抵消噪声,因此,您无需添加[-0.5; 1.5 [,而是添加[-2.0; 0.0 [(即减去2位噪声))。这是一个非常有经验的解决方案,但是我不知道有一种更正确的方法。考虑到这一点,您可能还希望增强信号以补偿丢失的强度...

蒂莫西·洛特斯(Timothy Lottes)在GDC上发表了一篇GDC演讲,内容是将噪声整形到频谱所在的部分最需要的,可以减少频谱最亮处的噪声:http://32ipi028l5q82yhj72224m8j-wpengine.netdna-ssl.com/wp-content/uploads/2016/03/GdcVdrLottes.pdf

评论


$ \ begingroup $
(对不起,我不小心按了Enter键,并且编辑时间限制已过期)示例中的用例是一种很重要的情况:在3位显示设备上渲染浮点灰度图像。只需更改LSB,强度就会发生很大变化。我试图了解是否有任何“正确的方法”可以将最终值映射为纯色,例如压缩值范围并使最终值饱和。对此的数学解释是什么?在示例公式中,输入值为1.0不会产生平均为7的输出,这让我感到困扰。
$ \ endgroup $
– hotmultimedia
17年12月1日在23:03

#3 楼

我已经将Mikkel Gjoel的将三角噪声抖动的想法简化为只需要一个RNG调用的简单函数。我已经删除了所有不必要的部分,因此它应该很容易理解和理解。
关于想法和背景,我将带您参考Mikkel Gjoel的回答。