mame.ini是通过floor,offset,scale,power,saturation等五个参数及red_ratio/grn_ratio/blu_ratio组成的三原色比例矩阵来对色彩进行调节的。

其中 output代表最终输出色彩,signal代表rgb分量信号值,ratio代表rgb分量比例矩阵,saturation代表整体饱和度: (一)信号:mame.ini中的信号值范围为0至1,换算成8bit色则为0-255,数值之间用逗号分隔。例如0.5, 0, 0表示明度居中的纯红色(127,0,0)。 rgb分量信号是由各分量对应的信号函数调整的,函数结构为 f(signal)=floor^power+((1−floor^power)×scale×signal+offset)^power:

在mame.ini找到floor,offset,scale,power,即可参照该函数对信号进行调整,其中4个变量按计算先后排列依次为:
底值(floor, 0.0-1.0): 将保证处理后的信号不会低于此值。mame的底值处理方式不是把低于底值的信号值直接抬高至底值,而是把信号区间从[0.0,1.0]平移抬高后用公式中的系数1-floor^power线性压缩至[floor^power,1.0],从而调整所有信号。另外,底值将受到幂的影响,例如底值为0.5,幂值为2时,实际底值会变为0.25而不是0.5。底值一般用来表现屏幕的背景色调。
倍率(scale, -2.0-2.0) :经过底值处理后的信号将乘以倍率,一般用来调节整体明度。
偏移量(offset,-1.0-1.0):对乘算过后的信号进行加减运算,一般用来搭配倍率进行色相及对比调节。
幂(power, -8.0-8.0):对经过前3步处理的信号和信号底值进行幂运算,一般用来表现反射屏的偏振光衰减效果。
(二)分量比例矩阵: 在mame.ini的DIRECT3D POST-PROCESSING OPTIONS下可找到red_ratio/grn_ratio/blu_ratio,即组成矩阵的3组数字,它们分别表示3个输入分量(RGB)对输出分量的影响。可表示为:
red_ratio[0], red_ratio[1], red_ratio[2]
grn_ratio[0], grn_ratio[1], grn_ratio[2]
blu_ratio[0], blu_ratio[1], blu_ratio[2]]
mame的默认矩阵为: 1, 0, 0 0, 1, 0 0, 0, 1 (三)整体饱和度(0.0-40.0): 即HSB模型中的S,代表色彩的鲜艳度,使用该值可方便调节整个画面的饱和度。 下面将以wonderswan的游戏画面为例,介绍具体过程

(原始图像为灰阶图)(一)信号调节:把mame.ini的默认变量值(power=1, offset=0, scale=1, floor=0)代入信号函数可得: f(signal)=0.0^1.0+((1−0.0^1.0)×1.0×signal+0.0)^1.0=signal , 此时函数并不会对信号作任何处理。 接下来分析wonderswan实机屏幕以拟定变量值。 如图所示,wonderswan配备常亮式反射屏,色彩由黄绿偏光膜与深蓝滤色层混合而成,亮部偏冷,暗部偏暖,中间色偏灰:

(wonderswan实机效果) 对实机画面进行采样统计后,可得出最亮色与最暗色的RGB信号值:

(采样统计得出最亮色与最暗色)
暗色rgb为23,23,10,对应信号值为0.09,0.09,0.04;亮色rgb为121,145,133, 对应信号值0.47,0.57,0.52。
接下来绘制rgb分量的信号函数:

(rgb分量信号函数1)
函数x轴代表原始灰阶信号值,y轴代表处理后的彩色信号值,把r=0.09, g=0.09, b=0.04(暗色输出信号值)绘入x=0.0(黑色输入信号所在位置),把r=0.47,g=0.57,b=0.52(亮色输出信号值)绘入x=1.0(白色输入信号所在位置),再用线段连结这两组RGB信号值,即可绘出RGB分量信号函数的大致外观并推算出floor=0.04,0.04,0.04,scale=0.4,0.5,0.5, offset=0.05,0.05,0.0,power=1.0,1.0,1.0。
把4个变量值代入mame.ini:
#底值
floor 0.04,0.04,0.04
#倍率
scale 0.4,0.5,0.5
#偏移量
offset 0.05,0.05,0.0
#幂
power 1.0,1.0,1.0
进入mame即可看到初步效果:

(初步效果)当前色调基本正确,接下来修改幂值实现光线2次衰减的效果。 与背光屏不同,作为信号源的入射光线并不会全部参与反射,其中一部分在入射时就已被偏光片阻挡而衰减,衰减程度取决于画面各位置亮度。

(反射屏成像原理)
把幂值设为2并使底值与先前保持一致即可实现衰减效果:
#幂
power 2.0,2.0,2.0
#修改底值floor,使其在平方运算后保持0.04不变
floor 0.2,0.2,0.2
此时的RGB分量信号函数如下图:

(RGB分量信号函数2)
#阴影遮罩相关参数
#为了达成和游戏像素一一对应的效果,阴影遮罩将采用模式1,即游戏源图模式
shadow_mask_tile_mode 1
#wonderswan的阴影遮罩不明显,强度设为0.25
shadow_mask_alpha 0.25
#阴影遮罩贴图,选用gameboy的贴图
shadow_mask_texture monochrome-matrix.png
#贴图为4x4的点阵,每个点在贴图中的uv大小为1/4=0.25,且每个点都和游戏像素一一对应(count=1)
shadow_mask_x_count 1
shadow_mask_y_count 1
shadow_mask_usize 0.25
shadow_mask_vsize 0.25
#泛光相关参数
#泛光系数须大于0
bloom_scale 1.0
#泛光权重lvl0,相当于原始画面的不透明度,设为1.0
bloom_lvl0_weight 1.0
#泛光权重lvl1,泛光效果比较集中,wonderswan可设为0.5
bloom_lvl1_weight 0.5
#其余泛光权重设为0
bloom_lvl2_weight 0.0
bloom_lvl3_weight 0.0
bloom_lvl4_weight 0.0
bloom_lvl5_weight 0.0
bloom_lvl6_weight 0.0
bloom_lvl7_weight 0.0
bloom_lvl8_weight 0.0
调亮画面并把mame的默认点阵屏阴影遮罩monochrome-matrix.png替换为前文绘制的遮罩ws.png可使细节更丰富。最终效果如下:


(右侧画面对比度和饱和度偏高且颜色偏黄)
为平衡画面色彩,需要用部分红绿信号抬高蓝色信号,并用部分蓝色信号稀释红绿信号。调整时需注意保证每行数字之和等于1.0,如red_ratio=0.8+0.0+0.2=1.0。另外,可使用mame菜单中的滑块控件(slider controls)一边调整一边预览效果(选项名称格式为XXX Output from XXX,XXX代表Red/Green/Blue)。
调整完毕后,在mame.ini中找到red_ratio/grn_ratio/blu_ratio并进行替换,如下:
#将得到的矩阵输入mame.ini
red_ratio 0.75,0.0,0.25
grn_ratio 0.05,0.9,0.05
blu_ratio 0.25,0.25,0.5

(套用矩阵后得到的修正结果)
而mame的gbc色彩输出也和实机显示的不同,此时需进行“原色替换”,即获取红绿蓝三原色在实机上呈现出的rgb值,并把大致色彩比例直接代入到矩阵中,但同样要保证每行数字等于1,例如mame中的纯蓝色在实机上是绿色占比约25%青蓝,就把蓝色分量比例blu_ratio改为0.0 0.25 0.75,依此类推,即可推算出gbc的分量比例矩阵为:
red_ratio 0.75,0.25,0.0
grn_ratio 0.0,0.75,0.25
blu_ratio 0.0,0.25,0.75

(用分量比例矩阵调节gbc游戏色彩)(三)饱和度:设为0时画面将变为灰阶图像,设为1时饱和度不变,大于1时将提升画面饱和度。
许多gba游戏都针对硬件进行了色彩适配,这使得gba的原始画面不够自然,需要进行色彩补正来模拟硬件特征,还原游戏画面的真实色彩。例如下图的晓月圆舞曲人物界面:

(晓月圆舞曲)和许多gba游戏一样,晓月圆舞曲的原始画面也呈现出泛白且偏暖的特点,而在gba实机上却显示正常。这是因为游戏在制作时考虑到了gba显示屏的硬件特征,对原始画面进行了补正,使之能在实机上得到预想效果。 为还原实机画面,就要模拟硬件来对原始画面进行反向补正: 原生gba和wonderswan一样,配备了常亮式反射屏,可采用相同的信号处理函数模仿反射屏来解决泛白问题。变量方面,gba是彩色屏幕,附有rgb滤镜,而前文是使用50%的阴影遮罩模拟滤镜进行颜色调节的,故倍率scale和偏移量offset都将采用mame默认值1.0和0.0,幂值power则参考wonderswan实例设为2.0。 然后是底值floor,原始画面将黑色(0,0,0)转换成了上图的暗红色(24,0,0),所以我们要在原先底值的基础上降低红色的底值,才能在保持色彩信息完整且均衡的同时补正画面。
#底值,参考wonderswan实例设为0.2,由于采用了50%阴影遮罩,还需乘以2以保证一致
floor 0.4,0.4,0.4
#倍率,使用默认值1.0
scale 1.0,1.0,1.0
#偏移量,使用默认值1.0
offset 0.0,0.0,0.0
#幂,参考wonderswan实例设为2.0
power 2.0,2.0,2.0

(改值后未添加阴影遮罩时的画面)
为方便分析红色的降低程度,先对改值后未添加阴影遮罩的画面背景进行采样,黑色(0,0,0)在图中的rgb值为(53,41,41),为去除红色使其变为中性色(41,41,41),并考虑到幂值power对底值floor的影响,则需要将红色底值降低(53/255)^0.5-(41/255)^0.5=0.46-0.4=0.06,代入mame.ini中:
#红色底值降低0.06,使黑色中性化
floor 0.34,0.4,0.4
此时界面的黑色背景已变为中性色,相应的,此时游戏画面的冷暖也趋于平衡。
需要注意的是,修改底值floor并不能改变亮部色调,若要改变整个画面的色调,则需使用前文的gba特化版tn.png遮罩:

(gba特化版tn.png,使画面向210度补正,添加了GBA遮罩纹理和动态亮度,须替换hlsl参数)屏幕高光效果(可选):虽然gba游戏画面整体偏暗,但屏幕会随视角视点变化出现高亮区域,可通过提高画面对比度来模拟。对比度默认为1,提升对比度会损失一部分画面细节:
#在mame.ini中修改对比(contrast),其默认值为1
contrast 1.25

(应用特化遮罩&修改对比度)(附1)lut调节方法:除线性调节手段外,mame还提供了lut手段调节色彩,lut全称为look up table(检色表),mame的lut位于artwork文件夹下,名称为"lut-default.png",是一张4096x64的像素色彩表,涵盖了一套6-bit颜色。检色表从左往右分为64个大区块,每个大区块的所有内部像素都拥有固定的蓝值,且大区块之间的蓝值从左往右递增。单个大区块内部像素则存在红值从左往右递增,绿值从上往下递增的规律。

(lut-default.png)
如果开启了lut功能,则mame在原始图像生成阶段会用lut上的颜色对画面颜色进行插值替换。
再次以前面的分量比例矩阵调节为例,调整结束后的皮卡丘颜色依然偏暗。此时我们也可以用lut把画面还原为灰阶图,再重新调色:
用图形编辑工具打开游戏原始图像截图,寻找待替换色的rgb,再打开artwork下的lut-default.png,根据采色器提供的数据,找到最接近待替换色的像素,涂上替换色。

(lut修改,可以看到屏幕上的灰点即为替换后的颜色)
完成后记得在mame.ini中开启lut选项并选择一个lut文件:
#开启lut选项
lut_enable 1
#artwork下的默认lut贴图文件
lut_texture lut-default.png
最终效果如下:

(修改lut替换颜色,实现更精准的画面控制)

(wonderswan color,亮色偏青蓝,底色偏蓝紫,需降低遮罩红值并降低底值floor的g值。且该设备横纹不明显,故遮罩削弱了横向黑线)

(wonderswan,仅使用信号函数进行调节)

gameboy pocket (使用信号函数前,先用lut替换掉mame的原始色)

(gbc的补正和遮罩同gba,且gbc实机饱和度较低。上图saturation=0.5)

(降低gamma也可提高对比且不会丢失画面细节,但会使画面整体变暗。上图gamma=0.75)