什么是显示具有规则24 BPP显示器上的每通道8位以上的最忠实显卡的最佳方式?
Answer 1:
我能想到的最好的解决方案是基于改变每一帧的随机抖动。 这种结合了不具有固定抖动模式抖动的优势,因为给定的像素变化值很多次第二你感觉更接近平均这些不同的价值观,这是更接近原来的“深色”值比任何给定的24 BPP值。
如何看起来
的绿色的梯度,未颤动,抖动(10帧被示出),然后在两者能见度相同的方式增强:
抖动
抖动是通过将伽马压缩深颜色值与一个随机值每个信道,然后四舍五入到最接近的8位值来实现的。 这似乎自然(在相当于1在8位伽玛压缩值单位我说的是,如0和1或254和255之间的差)与-0.5和0.5之间的均匀分布到使用随机数,然而,这将导致一种带状伪像,其中靠近一个8位的值的梯度的值将具有小的噪声,而值从任意8位数值的最远将显示更大量的噪声。 高斯噪声是更适合,因为它给出了一个更平滑的噪声水平。 我选择了一个西格玛的1.0,但噪音少0.8西格玛可能会做。
可以通过取两个随机数,创建一个高斯PRNG n1
和n2
,在装配它们各自[-1,1]范围内,如果它们表示单位圆内的点(如果该总和sum
它们的平方的差或等于1,否则重新开始)返回sqrt(-2. * log(sum) / sum) * n1
。
实际执行情况
我选择通过转换每个通道15位线性RGB帧缓冲器到每通道的sRGB帧缓冲区的8比特来实现此。 为sRGB部分线性仅仅是一个细节,我使用的查找表来转换线性值成γ-压缩值(I选择使这些中间值使用13个比特,则可以把它看作是一个8.5的固定点记数法为sRGB值)。
它应该不用说,你不会产生每个像素的新的随机高斯数,你要预先计算一群人,把他们在一个循环缓冲区。 我选择了让他们的16384,是的,只有16384,我避免任何重复图案在这个缓冲区选择一个随机的切入点,随机长度要经过(100和1123之间,这是相当任意的),当我到达长度的端部我选择一个新的随机起点和一个新的随机长度。 这样,我得到相当随机不重复的数字出来的一个相对较小的缓冲区。 在缓冲区中的号码存储在2.5定点格式,这样一来他们都是-4.0和4.0,其中涵盖高斯随机数我想拥有的范围之间。 只要确保加0.5到您的随机数,因为这会照顾四舍五入到最接近的整数后。
这里的基本上它是如何工作的每个像素和每个通道:
15位线性值--via LUT - > 13位(8.5定点)伽玛压缩值然后ADD然后2.5定点随机数SHIFT 5个比特到右侧。
现在你就-4和260之间的整数值,您可以使用,如果()■限制那些,但它的速度更快,以使用为负数返回0(您可以通过分配使用负数作为索引264元LUT您的缓冲区然后做缓冲=缓冲区[4],为您节省的另外我猜),并且上面255的数字返回255我用的是相同的随机数为三个颜色通道,这样就避免了色彩噪波,虽然可以说是结果可能会少了几分嘈杂,如果这三个独立的使用数量。
用于单个像素的红色通道我的代码看起来是这样的: sfb[i].r = bytecheck_l.lutb[lsrgb_l.lutint[fb[i].r] + dither_l.lutint[id] >> 5];
SFB是与sRGB 24 BPP缓冲器,FB为45 BPP线性RGB缓冲器,lsrgb_l.lutint []为线性伽马压缩LUT,dither_l.lutint []含有2.5随机高斯号码LUT定点格式和bytecheck_l .lutb []中返回值限幅为[0,255]。
性能
我得到了50 FPS的1400x820 SDL窗口使用的2.4 GHz的Core 2 Quad Q6600和双通道800 MHz的DDR2内存,一个稍显平庸的机器现行标准只是一个核心我的测试梯度,因此该方案似乎绝对适合现代电脑。
请让我知道,如果我的任何解释都需要澄清。