Alpha混合 - 反复混合RGBA颜色会产生黑色

时间:2014-04-14 14:16:42

标签: c# alphablending

我从另一个问题实施了this code,效果非常好。

我遇到的问题是反复混合两种颜色导致黑色。这是效果的一个例子。

Example

我正在使用C#,我在Color32类型中有两种颜色的RGBA(背景和前景) - 红色,绿色,蓝色和alpha的1个字节。目前我正在将0-255转换为0-1,但我认为存在一些浮点转换问题。

什么方式不会产生这种效果?

编辑:这是我正在使用的代码。 currentColor是画布(背景),brushColor是前景。

float bg_r = ((float)currentColor.r) / 255.0f;
float bg_g = ((float)currentColor.g) / 255.0f;
float bg_b = ((float)currentColor.b) / 255.0f;
float bg_a = ((float)currentColor.a) / 255.0f;

float bg_r_a = bg_r * bg_a;
float bg_g_a = bg_g * bg_a;
float bg_b_a = bg_b * bg_a;

float fg_r = ((float)brushColor.r) / 255.0f;
float fg_g = ((float)brushColor.g) / 255.0f;
float fg_b = ((float)brushColor.b) / 255.0f;
float fg_a = (((float)brushColor.a) / 255.0f) * brush.pressure; // 0 - 1

float fg_r_a = fg_r * fg_a;
float fg_g_a = fg_g * fg_a;
float fg_b_a = fg_b * fg_a;

float col_r_a = fg_r_a + bg_r_a * ( 1.0f - fg_a );
float col_g_a = fg_g_a + bg_g_a * ( 1.0f - fg_a );
float col_b_a = fg_b_a + bg_b_a * ( 1.0f - fg_a );
float col_a = fg_a + bg_a * ( 1.0f - fg_a );

float col_r = col_r_a / col_a;
float col_g = col_g_a / col_a;
float col_b = col_b_a / col_a;

byte colR = (byte)Mathf.Clamp( col_r * 255.0f, 0.0f, 255.0f );
byte colG = (byte)Mathf.Clamp( col_g * 255.0f, 0.0f, 255.0f );
byte colB = (byte)Mathf.Clamp( col_b * 255.0f, 0.0f, 255.0f );
byte colA = (byte)Mathf.Clamp( col_a * 255.0f, 0.0f, 255.0f );

Color32 outputColor = new Color32( colR, colG, colB, colA );

链接:http://pastebin.com/hXkKSYLe

1 个答案:

答案 0 :(得分:1)

问题很可能在以下几个方面:

byte colR = (byte)Mathf.Clamp( col_r * 255.0f, 0.0f, 255.0f );

具体来说,是(byte)演员。从浮点类型转换为整数类型将截断小数部分:

Console.WriteLine((byte)1.9f);  // Outputs "1"
Console.WriteLine((int)-1.9f);  // Outputs "-1"

因此,在每次转换回字节后,您将失去平均0.5字节大小的增量,并且在平均512次转换后,您的颜色将漂移为黑色。

尝试添加对Math.Round的调用以消除漂移。

byte colR = (byte)Math.Round(Mathf.Clamp( col_r * 255.0f, 0.0f, 255.0f ));