JaminGrey

Color blending formulas

Nov 11th, 2012
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.18 KB | None | 0 0
  1. //Figure out what blend mode we want, and do the blending.
  2. if(blendMode == BlendMode::Mask)
  3. {
  4.     //The mask "alpha" applied to the tile, is determined by the alpha of the mask, or the
  5.     //blackness of the mask. So basically, the average of the RGB colors with alpha affecting it also.
  6.     int finalAlpha = (colorA.GetAlpha() * colorB.GetAverageValue()) / 255;
  7.     finalColor.SetAlpha(finalAlpha);
  8. }
  9. else if(blendMode == BlendMode::Normal)
  10. {
  11.     float alpha = (float(colorB.GetAlpha()) / 255.0f);
  12.  
  13.     finalColor.SetR(((1.0f - alpha) * colorA.GetR()) + (alpha * colorB.GetR()));
  14.     finalColor.SetG(((1.0f - alpha) * colorA.GetG()) + (alpha * colorB.GetG()));
  15.     finalColor.SetB(((1.0f - alpha) * colorA.GetB()) + (alpha * colorB.GetB()));
  16.  
  17.     //Leave the tile's alpha unchanged.
  18.     finalColor.SetAlpha(colorA.GetAlpha());
  19. }
  20. else if(blendMode == BlendMode::Overlay)
  21. {
  22.     //Overlay must be done per color channel.
  23.     /*if(colorA.GetR() <= 128)
  24.         finalColor.SetR((2 * colorA.GetR() * colorB.GetR()) / 256);
  25.     else
  26.         finalColor.SetR(255 - (((255 - (2 * (colorA.GetR() - 128))) * (255 - colorB.GetR())) / 256));
  27.  
  28.     if(colorA.GetG() <= 128)
  29.         finalColor.SetG((2 * colorA.GetG() * colorB.GetG()) / 256);
  30.     else
  31.         finalColor.SetG(255 - (((255 - (2 * (colorA.GetG() - 128))) * (255 - colorB.GetG())) / 256));
  32.  
  33.     if(colorA.GetB() <= 128)
  34.         finalColor.SetB((2 * colorA.GetB() * colorB.GetB()) / 256);
  35.     else
  36.         finalColor.SetB(255 - (((255 - (2 * (colorA.GetB() - 128))) * (255 - colorB.GetB())) / 256));*/
  37.  
  38.     if(colorB.GetR() <= 128)
  39.         finalColor.SetR((2 * colorB.GetR() * colorA.GetR()) / 256);
  40.     else
  41.         finalColor.SetR(255 - (((255 - (2 * (colorB.GetR() - 128))) * (255 - colorA.GetR())) / 256));
  42.  
  43.     if(colorB.GetG() <= 128)
  44.         finalColor.SetG((2 * colorB.GetG() * colorA.GetG()) / 256);
  45.     else
  46.         finalColor.SetG(255 - (((255 - (2 * (colorB.GetG() - 128))) * (255 - colorA.GetG())) / 256));
  47.  
  48.     if(colorB.GetB() <= 128)
  49.         finalColor.SetB((2 * colorB.GetB() * colorA.GetB()) / 256);
  50.     else
  51.         finalColor.SetB(255 - (((255 - (2 * (colorB.GetB() - 128))) * (255 - colorA.GetB())) / 256));
  52.  
  53.     BUILD_NOTE("Shouldn't this be SetAlpha(colorA.GetAlpha())?")
  54.     finalColor.SetAlpha(255); //Undo any changes to alpha.
  55. }
  56. else if(blendMode == BlendMode::Multiply)
  57. {
  58.     finalColor = (colorA * colorB);
  59.     finalColor.SetAlpha(255); //Undo any changes to alpha.
  60. }
  61. else if(blendMode == BlendMode::Screen)
  62. {
  63.     const cColor FULL_COLOR(255, 255, 255, 255);
  64.  
  65.     finalColor = FULL_COLOR - ((FULL_COLOR - colorA) * (FULL_COLOR - colorB));
  66.     finalColor.SetAlpha(255); //Undo any changes to alpha.
  67. }
  68. else if(blendMode == BlendMode::Dodge)
  69. {
  70.     finalColor.SetR((colorA.GetR() * 256) / ((255 - colorB.GetR()) + 1));
  71.     finalColor.SetG((colorA.GetG() * 256) / ((255 - colorB.GetG()) + 1));
  72.     finalColor.SetB((colorA.GetB() * 256) / ((255 - colorB.GetB()) + 1));
  73.  
  74.     //finalColor.SetAlpha((colorA.GetAlpha() * 256) / ((255 - colorB.GetAlpha()) + 1));
  75.  
  76.     //Leave the tile's alpha unchanged.
  77.     finalColor.SetAlpha(colorA.GetAlpha());
  78. }
  79. else if(blendMode == BlendMode::Burn)
  80. {
  81.     //This works, even with alpha, but it doesn't match PaintShopPro's result.
  82.     /*unsigned int redFactor = colorB.GetR() + (255 - colorB.GetAlpha()) + 1;
  83.     if(redFactor > 255) redFactor = 255;
  84.     finalColor.SetR(255 - (((255 * (255 - colorA.GetR())) / redFactor)));
  85.  
  86.     unsigned int greenFactor = colorB.GetG() + (255 - colorB.GetAlpha()) + 1;
  87.     if(greenFactor > 255) greenFactor = 255;
  88.     finalColor.SetG(255 - (((255 * (255 - colorA.GetG())) / greenFactor)));
  89.  
  90.     unsigned int blueFactor = colorB.GetB() + (255 - colorB.GetAlpha()) + 1;
  91.     if(blueFactor > 255) blueFactor = 255;
  92.     finalColor.SetB(255 - (((255 * (255 - colorA.GetB())) / blueFactor)));*/
  93.  
  94.     //GIMP version:
  95.     finalColor.SetR(255 - ((256 * (255 - colorA.GetR())) / (colorB.GetR() + 1)));
  96.     finalColor.SetG(255 - ((256 * (255 - colorA.GetG())) / (colorB.GetG() + 1)));
  97.     finalColor.SetB(255 - ((256 * (255 - colorA.GetB())) / (colorB.GetB() + 1)));
  98.  
  99.     //Leave the tile's alpha unchanged.
  100.     finalColor.SetAlpha(colorA.GetAlpha());
  101. }
Advertisement
Add Comment
Please, Sign In to add comment