Floyd–Steinberg 像素着色器的抖动替代方案
我知道 Floyd–Steinberg 抖动 算法无法用像素实现着色器,因为该算法是严格顺序的。但也许存在一些高度并行的抖动算法,其视觉输出类似于 Floyd-Steinberg 算法?
所以问题是 - 哪些抖动算法适合在像素着色器(最好是 GLSL)上实现并且输出质量(非常)类似于 Floyd-Steinberg 抖动?
顺便提一句。允许使用多遍算法,直到不超过 2 遍并且这些遍之间的 CPU 开销很小。
有什么想法吗?
编辑:
我需要从 24 位颜色抖动到 21 位颜色。
(也就是说 - 我需要从 8 位/通道转换为 7 位/通道。)
编辑 2 也许我没有很好地解释问题。所以我会尝试对具体问题进行一些扩展。 问题是这样的 - 假设我们有这张图片:
我们有上面的图片,但经过抖动算法处理:
现在这个程序将测试你的抖动对我是否有好处:
1.将这些图片作为 2 层的一张图片加载到 Photoshop 中。
2。选择图层混合模式为“差异”。
3。对图层执行“合并可见”操作,仅得到一层。
4。执行操作=>图像/调整/均衡
之后你必须得到这样的图像:
如您所见 - 单调红色的中间像素根本没有抖动。 左右图像区域的抖动也有点不同。尝试用这种行为重建抖动算法。
I know that Floyd–Steinberg dithering algorithm can't be implemented with pixel shader, because that algorithm is strictly sequential. But maybe there exist some higly parallel dithering algorithm which by it's visual output is similar to Floyd-Steinberg algorithm ?
So the question is - What are dithering algorithms which are suitable to implement on pixel shader (preferably GLSL) and with output quality (very) similar to Floyd-Steinberg dithering ?
BTW. Multi-pass algorithms are allowed until there are not more than 2 passes and CPU overhead between those passes is small.
Any ideas ?
EDIT:
I need dithering from 24-bit color to 21-bit color.
(That is - i need to convert from 8 bits/channel to 7 bits/channel.)
EDIT 2
Maybe I've not explained problem very well. So i'll try to expand a bit on exact problem.
Problem is this - consider we have this picture:
And we have above picture, but processed with dithering algorithm:
Now this is procedure which will test your dithering is good for me or not:
1. Load these pictures in Photoshop as one picture with 2 layers.
2. Choose Layers blending mode to "Difference".
3. Perform "Merge Visible" operation on layers, to get just one layer.
4. Perform operation => Image/Adjustments/Equalize
After that you must get such image:
As you see - middle pixels which was in monotone red color was not dithered at all.
Also dithering of left and right image zones is a bit different. Try to reconstruct dithering algorithm with such behavior.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用有序抖动。它看起来比 Floyd-Steinberg 更粗糙,但像素之间没有依赖性。
编辑:由于您只删除了一位,因此这几乎变得微不足道。有序抖动背后的原理是创建一种使过渡阈值产生偏差的模式;在这种情况下,偏差将为 0 或 1,图案将为 2x2 像素。这两项更改一起将使该模式比维基百科文章中的模式更不令人讨厌 - 您甚至可能比 Floyd-Steinberg 更喜欢它。
这是一些伪代码:
编辑 2: 这是我的差异结果,尽我所能。如果不知道如何将 7 位值映射回 8 位,我就无法做得更好。
You could use an ordered dither. It's more coarse looking than Floyd-Steinberg but there's no dependency between pixels.
Edit: Since you're only removing a single bit, this becomes almost trivial. The principle behind ordered dither is to create a pattern that biases the transition threshold; in this case the bias will be 0 or 1 and the pattern will be 2x2 pixels. These two changes together will make the pattern much less obnoxious than the one in the Wikipedia article - you might even like it better than Floyd-Steinberg.
Here's some pseudo-code:
Edit 2: Here's my difference result, as best as I can do. Without knowing how you map your 7-bit values back to 8 bits I'm unable to do better.
如果从 8 位减少到 7 位,则几乎不会丢弃任何信息。你确定你还需要犹豫吗?
如果您需要抖动,添加随机噪声然后进行剪辑,这对您的应用程序来说非常有用。
If you are reducing from 8 bits to 7, you are throwing away almost no information. Are you sure you even need to dither?
If you need to dither, add random noise and then clip, it will be plenty good for your application.