在仿真器中正确显示RetroConsole的颜色



几乎所有的游戏机复古控制台都以某些RGB编码选项生成颜色。

但是这些像素颜色通常是为与模拟器通常使用的屏幕完全不同的屏幕设计的。 在本文中,我将讨论颜色仿真的重要性,并提供一些代码示例和屏幕截图。

当今最常见的显示器类型是LCD面板。 他们以黑色水平非常差而著称。 TN,PVA和IPS之间的差异不会对此造成太大影响。

一些粉丝在CRT显示器上玩耍,而OLED屏幕越来越受欢迎,尤其是在手机和平​​板电脑上。 但是在本文中,我们将主要考虑LCD屏幕,尽管该技术对于任何类型的显示器都很重要。

色彩准确度


第一个重要细节:大多数计算机以24位彩色模式运行,为红色,绿色和蓝色通道提供8位颜色细节。 但是在大多数较旧的游戏系统中,颜色设置的精度都不高。

例如,Sega Genesis编码9位颜色,每个通道给出3位。

最幼稚的解决方案是将3位放在输出的最高3位中,而将较低的5位保留为空白,但是白色会变成灰色。

一个例子:

  000000000-> 000'00000 000'00000 000'00000
 111111111-> 111'00000 111'00000 111'00000 



如果用单位填充它们,则黑色会变得太浅。

一个例子:

  000000000-> 000'11111 000'11111 000'11111
 111111111-> 111'11111 111'11111 111'11111 



解决方案是重复原始位,以便它们填充所有输出位。

一个例子:

  000-> 000 000 00 ...
 010-> 010 010 01 ...
 011-> 011 011 01 ...
 111-> 111 111 11 ... 

以代码形式:

  uint8红色= r << 5 |  r << 2 |  r >> 1
 // rrr00000 |  000rrr00 |  000000rr-> rrrrrrrr 

屏幕模拟


游戏复古系统并非设计用于现代LCD电脑显示器。 通常,家用控制台是为CRT屏幕设计的,而便携式控制台则使用了较旧且精度较低的LCD面板。

在本文中,我们将不考虑屏幕伪影,例如屏幕弯曲度,扫描线,色差,帧间融合,光圈网格等:目前,我们仅关注单个像素的颜色。

电脑显示器


监视器具有相当广泛的颜色范围,因为只有其中一些经过了专业校准以符合SRGB等标准,但是总的来说,我们能做的最好的就是尝试模拟颜色,就好像我们使用的是经过正确校准的SRGB监视器一样。

CRT仿真:超级任天堂


CRT屏幕和计算机的LCD监视器之间的主要区别在于,黑电平显着降低,只能通过伽玛校正曲线对其进行少量补偿:

  // SNES颜色为RGB555格式,因此每个通道有32个色阶
静态常量uint8 gammaRamp [32] = {
   0x00,0x01,0x03,0x06,0x0a 0x0f 0x15,0x1c
   0x24、0x2d,0x37、0x42、0x4e,0x5b,0x69、0x78,
   0x88,0x90,0x98,0xa0,0xa8,0xb0,0xb8,0xc0
   0xc8,0xd0,0xd8,0xe0,0xe8,0xf0,0xf8,0xff
 }; 

该表是从Super Sleuth / Kindred的Overload借来的。 它遮盖了调色板的下半部分,而上部则保持不变。

这对仿真期间的图像产生了惊人的影响:左侧显示了原始图像,右侧应用了经过伽马校正的图像:





LCD仿真:Game Boy Advance


Game Boy Advance具有最差的LCD屏幕之一,其色彩完全褪色。 狡猾的开发人员意识到,通过显着放大颜色,可以在实际设备上获得更令人愉悦的效果。

当然,如果您在标准LCD显示器上使用这些颜色,结果将是一场噩梦。 幸运的是,我们可以通过创建相当自然的颜色来弥补这一点:

 双lcdGamma = 4.0,outGamma = 2.2;
双磅=战俘(B / 31.0,lcdGamma);
双lg =战俘(G / 31.0,lcdGamma);
 double lr =战俘(R / 31.0,lcdGamma);
 r =战俘((0 * lb + 50 * log + 255 * lr)/ 255,1 / outGamma)*(0xffff * 255/280);
 g =战俘((30 *磅+ 230 *日志+ 10 * lr)/ 255,1 / outGamma)*(0xffff * 255/280);
 b =战俘((220 *磅+ 10 *对数+ 50 * lr)/ 255,1 / outGamma)*(0xffff * 255/280); 

这段代码是由Talarubi编写的。

与CRT相比,对比度要大得多-顶部是原始图像,底部是带有色彩校正的版本:





LCD仿真:Game Boy颜色


“ Game Boy彩色”屏幕在再现颜色方面出奇地好,并且最终图片中可能仅出现轻微的颜色模糊。

以下算法在Game Boy Color模拟器中非常流行:

  R =(r * 26 + g * 4 + b * 2);
 G =(g * 24 + b * 8);
 B =(r * 6 + g * 4 + b * 22);
 R =最小值(960,R)>> 2;
 G =最小值(960,G)>> 2;
 B =最小值(960,B)>> 2; 

不幸的是,我不知道是谁写的算法。 如果您知道,请告诉我,以便表明作者身份!

和以前一样,左边为原始文件,右边为具有色彩校正的版本:



本示例是经过特殊选择的:尽管原始外观看起来更生动有趣,但如果仔细观察,您会发现人物周围的国际象棋图案比背景浅。

最有可能的是,这是开发人员的疏忽,因为在真正的游戏中
Boy的白色阴影模糊不清,两种不同的阴影几乎完美地融合在一起。

总结


还有许多系统仍然缺少良好的颜色仿真滤镜。
它们很难配置。 其中最重要的例子是WonderSwan和Neo Geo Pocket,在撰写本文时,它们还没有用于近似颜色的良好滤镜。

便携式控制台仍然更加复杂,因为它们通常没有背光(有时甚至是前灯!),并且有改变对比度的方法,因此对于特定的RGB值没有真彩色值。

一个特别有趣的边界情况是WonderSwan Color,它具有软件设置的标志来增加显示图像的对比度。
我们尚不知道如何可靠地模仿这种行为,也不清楚我们是否可以做到。

颜色仿真是一个需要更多关注的领域,因此,如果您是数学和颜色分析方面的专家,那么对于仿真场景,您的帮助将非常有用!

Source: https://habr.com/ru/post/zh-CN467581/


All Articles